diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:47:26 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:47:26 +0000 |
commit | 51072bd6bf79ef2bc6a922079bff57c31c1effbc (patch) | |
tree | 91a2effbc9e6f80bdbbf9eb70e06c51ad0867ea0 | |
parent | bb5e33f003797b67974a8893f7f2930fc51b8210 (diff) |
Notes
2421 files changed, 50626 insertions, 13676 deletions
diff --git a/.arcconfig b/.arcconfig index 6d07e827fcb8a..c96fbc1b4e6c7 100644 --- a/.arcconfig +++ b/.arcconfig @@ -1,4 +1,4 @@ { "project_id" : "libcxx", - "conduit_uri" : "http://reviews.llvm.org/" + "conduit_uri" : "https://reviews.llvm.org/" } diff --git a/CMakeLists.txt b/CMakeLists.txt index e6c96f64711b2..d618e8358caef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ #=============================================================================== # Setup Project #=============================================================================== -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.4.3) if(POLICY CMP0042) cmake_policy(SET CMP0042 NEW) # Set MACOSX_RPATH=YES by default @@ -12,13 +12,6 @@ if(POLICY CMP0022) cmake_policy(SET CMP0022 NEW) # Required when interacting with LLVM and Clang endif() -project(libcxx CXX C) - -set(PACKAGE_NAME libcxx) -set(PACKAGE_VERSION trunk-svn) -set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") -set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") - # Add path for custom modules set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" @@ -26,15 +19,18 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ) -# Require out of source build. -include(MacroEnsureOutOfSourceBuild) -MACRO_ENSURE_OUT_OF_SOURCE_BUILD( - "${PROJECT_NAME} requires an out of source build. Please create a separate - build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there." - ) - # Find the LLVM sources and simulate LLVM CMake options. include(HandleOutOfTreeLLVM) + +if (LIBCXX_BUILT_STANDALONE) + project(libcxx CXX C) + + set(PACKAGE_NAME libcxx) + set(PACKAGE_VERSION trunk-svn) + set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") + set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") +endif () + if (LIBCXX_BUILT_STANDALONE AND NOT LLVM_FOUND) message(WARNING "UNSUPPORTED LIBCXX CONFIGURATION DETECTED: " "llvm-config not found and LLVM_PATH not defined.\n" @@ -42,6 +38,13 @@ if (LIBCXX_BUILT_STANDALONE AND NOT LLVM_FOUND) "or -DLLVM_PATH=path/to/llvm-source-root.") endif() +# Require out of source build. +include(MacroEnsureOutOfSourceBuild) +MACRO_ENSURE_OUT_OF_SOURCE_BUILD( + "${PROJECT_NAME} requires an out of source build. Please create a separate + build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there." + ) + #=============================================================================== # Setup CMake Options #=============================================================================== @@ -49,7 +52,9 @@ endif() # 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_ENABLE_EXPERIMENTAL_LIBRARY "Build libc++experimental.a" ON) +option(LIBCXX_ENABLE_FILESYSTEM + "Build filesystem as part of libc++experimental.a" ${LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY}) option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS}) option(LIBCXX_INCLUDE_DOCS "Build the libc++ documentation." ${LLVM_INCLUDE_DOCS}) set(LIBCXX_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING @@ -57,6 +62,7 @@ set(LIBCXX_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING option(LIBCXX_INSTALL_HEADERS "Install the libc++ headers." ON) option(LIBCXX_INSTALL_LIBRARY "Install the libc++ library." ON) option(LIBCXX_INSTALL_SUPPORT_HEADERS "Install libc++ support headers." ON) +option(LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY "Install libc++experimental.a" OFF) set(LIBCXX_ABI_VERSION 1 CACHE STRING "ABI version of libc++.") option(LIBCXX_ABI_UNSTABLE "Unstable ABI of libc++." OFF) @@ -92,7 +98,8 @@ option(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "Statically link the ABI library" OFF) set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE OFF) if (LLVM_HAVE_LINK_VERSION_SCRIPT AND NOT LIBCXX_ENABLE_STATIC_ABI_LIBRARY AND NOT LIBCXX_CXX_ABI_LIBNAME STREQUAL "none" - AND PYTHONINTERP_FOUND) + AND PYTHONINTERP_FOUND + AND LIBCXX_ENABLE_SHARED) set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE ON) endif() @@ -121,12 +128,14 @@ option(LIBCXX_ENABLE_MONOTONIC_CLOCK "Build libc++ with support for a monotonic clock. This option may only be set to OFF when LIBCXX_ENABLE_THREADS=OFF." ON) option(LIBCXX_HAS_MUSL_LIBC "Build libc++ with support for the Musl C library" OFF) +option(LIBCXX_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread API" OFF) # Misc options ---------------------------------------------------------------- # FIXME: Turn -pedantic back ON. It is currently off because it warns # about #include_next which is used everywhere. option(LIBCXX_ENABLE_PEDANTIC "Compile with pedantic enabled." OFF) option(LIBCXX_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF) +option(LIBCXX_DISABLE_MACRO_CONFLICT_WARNINGS "Disable #warnings about conflicting macros." OFF) option(LIBCXX_GENERATE_COVERAGE "Enable generating code coverage." OFF) set(LIBCXX_COVERAGE_LIBRARY "" CACHE STRING @@ -160,6 +169,11 @@ option(LIBCXX_CONFIGURE_IDE "Configure libcxx for use within an IDE" # Check option configurations #=============================================================================== +if (LIBCXX_ENABLE_FILESYSTEM AND NOT LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY) + message(FATAL_ERROR + "LIBCXX_ENABLE_FILESYSTEM cannot be turned on when LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF") +endif() + # 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) @@ -167,6 +181,11 @@ if(LIBCXX_ENABLE_THREADS AND NOT LIBCXX_ENABLE_MONOTONIC_CLOCK) " when LIBCXX_ENABLE_THREADS is also set to OFF.") endif() +if(LIBCXX_HAS_PTHREAD_API AND NOT LIBCXX_ENABLE_THREADS) + message(FATAL_ERROR "LIBCXX_HAS_PTHREAD_API can only be set to ON" + " when LIBCXX_ENABLE_THREADS is also set to ON.") +endif() + # Ensure LLVM_USE_SANITIZER is not specified when LIBCXX_GENERATE_COVERAGE # is ON. if (LLVM_USE_SANITIZER AND LIBCXX_GENERATE_COVERAGE) @@ -199,6 +218,9 @@ if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT) if (NOT PYTHONINTERP_FOUND) message(FATAL_ERROR "LIBCXX_ENABLE_ABI_LINKER_SCRIPT requires python but it was not found.") endif() + if (NOT LIBCXX_ENABLE_SHARED) + message(FATAL_ERROR "LIBCXX_ENABLE_ABI_LINKER_SCRIPT is only available for shared library builds.") + endif() endif() if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT) @@ -233,6 +255,18 @@ set(LIBCXX_COMPILE_FLAGS "") set(LIBCXX_LINK_FLAGS "") set(LIBCXX_LIBRARIES "") +# Include macros for adding and removing libc++ flags. +include(HandleLibcxxFlags) + +# Target flags ================================================================ +# These flags get added to CMAKE_CXX_FLAGS and CMAKE_C_FLAGS so that +# 'config-ix' use them during feature checks. It also adds them to both +# 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS' +add_target_flags_if(LIBCXX_BUILD_32_BITS "-m32") +add_target_flags_if(LIBCXX_TARGET_TRIPLE "-target ${LIBCXX_TARGET_TRIPLE}") +add_target_flags_if(LIBCXX_SYSROOT "--sysroot=${LIBCXX_SYSROOT}") +add_target_flags_if(LIBCXX_GCC_TOOLCHAIN "-gcc-toolchain ${LIBCXX_GCC_TOOLCHAIN}") + # Configure compiler. include(config-ix) @@ -248,10 +282,7 @@ string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE) # Setup Compiler Flags #=============================================================================== -include(HandleLibCXXABI) # Steup the ABI library flags - -# Include macros for adding and removing libc++ flags. -include(HandleLibcxxFlags) +include(HandleLibCXXABI) # Setup the ABI library flags # Remove flags that may have snuck in. remove_flags(-DNDEBUG -UNDEBUG -D_DEBUG @@ -274,17 +305,13 @@ endif() # headers add_compile_flags_if_supported(-nostdinc++) -# Target flags ================================================================ -add_flags_if(LIBCXX_BUILD_32_BITS -m32) -add_flags_if(LIBCXX_TARGET_TRIPLE "-target ${LIBCXX_TARGET_TRIPLE}") -add_flags_if(LIBCXX_SYSROOT "--sysroot ${LIBCXX_SYSROOT}") -add_flags_if(LIBCXX_GCC_TOOLCHAIN "-gcc-toolchain ${LIBCXX_GCC_TOOLCHAIN}") # Warning flags =============================================================== add_definitions(-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) add_compile_flags_if_supported( -Wall -W -Wwrite-strings - -Wno-unused-parameter -Wno-long-long + -Wno-unused-parameter -Wno-long-long -Wno-user-defined-literals + -Wno-covered-switch-default -Werror=return-type) if (LIBCXX_ENABLE_WERROR) add_compile_flags_if_supported(-Werror) @@ -297,6 +324,9 @@ endif() if (LIBCXX_ENABLE_PEDANTIC) add_compile_flags_if_supported(-pedantic) endif() +if (LIBCXX_DISABLE_MACRO_CONFLICT_WARNINGS) + add_definitions(-D_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS) +endif() # Exception flags ============================================================= if (LIBCXX_ENABLE_EXCEPTIONS) @@ -376,6 +406,7 @@ config_define_if_not(LIBCXX_ENABLE_THREADS _LIBCPP_HAS_NO_THREADS) config_define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK _LIBCPP_HAS_NO_MONOTONIC_CLOCK) config_define_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS) +config_define_if(LIBCXX_HAS_PTHREAD_API _LIBCPP_HAS_THREAD_API_PTHREAD) config_define_if(LIBCXX_HAS_MUSL_LIBC _LIBCPP_HAS_MUSL_LIBC) if (LIBCXX_NEEDS_SITE_CONFIG) diff --git a/CREDITS.TXT b/CREDITS.TXT index 1cf713a688427..ceb12c42b9651 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -37,6 +37,10 @@ E: mclow.lists@gmail.com E: marshall@idio.com D: C++14 support, patches and bug fixes. +N: Jonathan B Coe +E: jbcoe@me.com +D: Implementation of propagate_const. + N: Eric Fiselier E: eric@efcs.ca D: LFTS support, patches and bug fixes. diff --git a/LICENSE.TXT b/LICENSE.TXT index 53352e42dd1f8..339e232c68fd4 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -14,7 +14,7 @@ Full text of the relevant licenses is included below. University of Illinois/NCSA Open Source License -Copyright (c) 2009-2015 by the contributors listed in CREDITS.TXT +Copyright (c) 2009-2016 by the contributors listed in CREDITS.TXT All rights reserved. diff --git a/Makefile b/Makefile deleted file mode 100644 index ab7b5b603a04d..0000000000000 --- a/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -## -# libc++ Makefile -## - -SRCDIRS = . -DESTDIR = $(DSTROOT) - -OBJROOT=. -SYMROOT=. -export TRIPLE=-apple- - -ifeq (,$(RC_INDIGO)) - INSTALL_PREFIX="" -else - INSTALL_PREFIX="$(SDKROOT)" -endif -INSTALL_DIR=$(DSTROOT)/$(INSTALL_PREFIX) - -.PHONY: help installsrc clean installheaders install - -help:: - @echo "Use make install DSTROOT=<destination>" - -installsrc:: $(SRCROOT) - - ditto $(SRCDIRS)/include $(SRCROOT)/include - ditto $(SRCDIRS)/lib $(SRCROOT)/lib - ditto $(SRCDIRS)/src $(SRCROOT)/src - ditto $(SRCDIRS)/Makefile $(SRCROOT)/Makefile - -clean:: - -# The installheaders target is used by clang's runtime/libcxx makefile. -installheaders:: - mkdir -p $(HEADER_DIR)/c++/v1/ext - (cd $(SRCDIRS)/include && \ - tar cf - --exclude=".*" --exclude=support \ - --exclude=CMakeLists.txt *) | \ - (cd $(HEADER_DIR)/c++/v1 && tar xf -) - chmod 755 $(HEADER_DIR)/c++/v1 - chmod 644 $(HEADER_DIR)/c++/v1/* - chmod 755 $(HEADER_DIR)/c++/v1/ext - chmod 644 $(HEADER_DIR)/c++/v1/ext/* - chmod 755 $(HEADER_DIR)/c++/v1/experimental - chmod 644 $(HEADER_DIR)/c++/v1/experimental/* - -install:: - - cd lib && ./buildit - ditto lib/libc++.1.dylib $(SYMROOT)/usr/lib/libc++.1.dylib - cd lib && dsymutil -o $(SYMROOT)/libc++.1.dylib.dSYM \ - $(SYMROOT)/usr/lib/libc++.1.dylib - mkdir -p $(INSTALL_DIR)/usr/lib - strip -S -o $(INSTALL_DIR)/usr/lib/libc++.1.dylib \ - $(SYMROOT)/usr/lib/libc++.1.dylib - cd $(INSTALL_DIR)/usr/lib && ln -s libc++.1.dylib libc++.dylib diff --git a/benchmarks/unordered_set_operations.bench.cpp b/benchmarks/unordered_set_operations.bench.cpp new file mode 100644 index 0000000000000..c9ee689f69d3c --- /dev/null +++ b/benchmarks/unordered_set_operations.bench.cpp @@ -0,0 +1,44 @@ +#include <unordered_set> +#include <vector> +#include <cstdint> + +#include "benchmark/benchmark_api.h" + +template <class IntT> +std::vector<IntT> getInputs(size_t N) { + std::vector<IntT> inputs; + for (size_t i=0; i < N; ++i) { + inputs.push_back(i); + } + return inputs; +} + +template <class Container, class Inputs> +void BM_SetInsert(benchmark::State& st, Container c, Inputs const& in) { + const auto end = in.end(); + while (st.KeepRunning()) { + c.clear(); + for (auto it = in.begin(); it != end; ++it) { + benchmark::DoNotOptimize(c.insert(*it)); + } + benchmark::DoNotOptimize(c); + } +} +BENCHMARK_CAPTURE(BM_SetInsert, uint32_insert, + std::unordered_set<uint32_t>{}, getInputs<uint32_t>(1024)); + +template <class Container, class Inputs> +void BM_SetFind(benchmark::State& st, Container c, Inputs const& in) { + c.insert(in.begin(), in.end()); + const auto end = in.end(); + while (st.KeepRunning()) { + for (auto it = in.begin(); it != end; ++it) { + benchmark::DoNotOptimize(c.find(*it)); + } + } +} +BENCHMARK_CAPTURE(BM_SetFind, uint32_lookup, + std::unordered_set<uint32_t>{}, getInputs<uint32_t>(1024)); + + +BENCHMARK_MAIN() diff --git a/cmake/Modules/CheckLibcxxAtomic.cmake b/cmake/Modules/CheckLibcxxAtomic.cmake new file mode 100644 index 0000000000000..4ff343236feab --- /dev/null +++ b/cmake/Modules/CheckLibcxxAtomic.cmake @@ -0,0 +1,41 @@ +INCLUDE(CheckCXXSourceCompiles) + +# Sometimes linking against libatomic is required for atomic ops, if +# the platform doesn't support lock-free atomics. +# +# We could modify LLVM's CheckAtomic module and have it check for 64-bit +# atomics instead. However, we would like to avoid careless uses of 64-bit +# atomics inside LLVM over time on 32-bit platforms. + +function(check_cxx_atomics varname) + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS "-std=c++11 -nostdinc++ -isystem ${LIBCXX_SOURCE_DIR}/include") + if (${LIBCXX_GCC_TOOLCHAIN}) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --gcc-toolchain=${LIBCXX_GCC_TOOLCHAIN}") + endif() + check_cxx_source_compiles(" +#include <cstdint> +#include <atomic> +std::atomic<uintptr_t> x; +std::atomic<uintmax_t> y; +int main() { + return x + y; +} +" ${varname}) + set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) +endfunction(check_cxx_atomics) + +check_cxx_atomics(LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB) +check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB) +# If not, check if the library exists, and atomics work with it. +if(NOT LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB) + if(LIBCXX_HAS_ATOMIC_LIB) + list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") + check_cxx_atomics(LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB) + if (NOT LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB) + message(WARNING "Host compiler must support std::atomic!") + endif() + else() + message(WARNING "Host compiler appears to require libatomic, but cannot find it.") + endif() +endif() diff --git a/cmake/Modules/HandleLibCXXABI.cmake b/cmake/Modules/HandleLibCXXABI.cmake index d9c652d87badc..c655adff718ec 100644 --- a/cmake/Modules/HandleLibCXXABI.cmake +++ b/cmake/Modules/HandleLibCXXABI.cmake @@ -21,9 +21,11 @@ macro(setup_abi_lib abidefines abilib abifiles abidirs) CACHE PATH "Paths to C++ ABI header directories separated by ';'." FORCE ) - + set(LIBCXX_CXX_ABI_LIBRARY_PATH "${LIBCXX_CXX_ABI_LIBRARY_PATH}" + CACHE PATH + "Paths to C++ ABI library directory" + ) set(LIBCXX_CXX_ABI_LIBRARY ${abilib}) - set(LIBCXX_ABILIB_FILES ${abifiles}) file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include") diff --git a/cmake/Modules/HandleLibcxxFlags.cmake b/cmake/Modules/HandleLibcxxFlags.cmake index bb886fa8a01ff..325c1bdf7bcb8 100644 --- a/cmake/Modules/HandleLibcxxFlags.cmake +++ b/cmake/Modules/HandleLibcxxFlags.cmake @@ -35,6 +35,11 @@ macro(remove_flags) endforeach() endmacro(remove_flags) +macro(check_flag_supported flag) + mangle_name("${flag}" flagname) + check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG") +endmacro() + # Add a macro definition if condition is true. macro(define_if condition def) if (${condition}) @@ -71,6 +76,26 @@ macro(config_define value def) set(LIBCXX_NEEDS_SITE_CONFIG ON) endmacro() +# Add a list of flags to all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', +# 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS'. +macro(add_target_flags) + foreach(value ${ARGN}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${value}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${value}") + 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 +# all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', 'LIBCXX_COMPILE_FLAGS' +# and 'LIBCXX_LINK_FLAGS'. +macro(add_target_flags_if condition) + if (${condition}) + add_target_flags(${ARGN}) + endif() +endmacro() + # Add a specified list of flags to both 'LIBCXX_COMPILE_FLAGS' and # 'LIBCXX_LINK_FLAGS'. macro(add_flags) diff --git a/cmake/Modules/HandleOutOfTreeLLVM.cmake b/cmake/Modules/HandleOutOfTreeLLVM.cmake index 6215be7f586a2..9c5dd81092616 100644 --- a/cmake/Modules/HandleOutOfTreeLLVM.cmake +++ b/cmake/Modules/HandleOutOfTreeLLVM.cmake @@ -35,7 +35,7 @@ macro(find_llvm_parts) 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") + set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm") else() set(LLVM_FOUND OFF) return() @@ -93,14 +93,6 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) 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() - # Required doc configuration if (LLVM_ENABLE_SPHINX) message(STATUS "Sphinx enabled.") diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index c05597ea73dd0..3e6c3599d23de 100644 --- a/cmake/config-ix.cmake +++ b/cmake/config-ix.cmake @@ -1,5 +1,6 @@ include(CheckLibraryExists) include(CheckCXXCompilerFlag) +include(CheckLibcxxAtomic) # Check compiler flags diff --git a/docs/BuildingLibcxx.rst b/docs/BuildingLibcxx.rst index f00ce4f9cff1a..36866b13ef7bd 100644 --- a/docs/BuildingLibcxx.rst +++ b/docs/BuildingLibcxx.rst @@ -1,3 +1,4 @@ +.. _BuildingLibcxx: =============== Building libc++ @@ -6,6 +7,8 @@ Building libc++ .. contents:: :local: +.. _build instructions: + Getting Started =============== @@ -34,8 +37,7 @@ The basic steps needed to build libc++ are: #. Configure and build libc++ with libc++abi: - CMake is the only supported configuration system. Unlike other LLVM - projects autotools is not supported for either libc++ or libc++abi. + CMake is the only supported configuration system. Clang is the preferred compiler when building and using libc++. @@ -120,6 +122,18 @@ CMake docs or execute ``cmake --help-variable VARIABLE_NAME``. libc++ specific options ----------------------- +.. option:: LIBCXX_INSTALL_LIBRARY:BOOL + + **Default**: ``ON`` + + Toggle the installation of the library portion of libc++. + +.. option:: LIBCXX_INSTALL_HEADERS:BOOL + + **Default**: ``ON`` + + Toggle the installation of the libc++ headers. + .. option:: LIBCXX_ENABLE_ASSERTIONS:BOOL **Default**: ``ON`` @@ -144,6 +158,33 @@ libc++ specific options Extra suffix to append to the directory where libraries are to be installed. This option overrides :option:`LLVM_LIBDIR_SUFFIX`. + +.. _libc++experimental options: + +libc++experimental Specific Options +------------------------------------ + +.. option:: LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY:BOOL + + **Default**: ``ON`` + + Build and test libc++experimental.a. + +.. option:: LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY:BOOL + + **Default**: ``OFF`` + + Install libc++experimental.a alongside libc++. + + +.. option:: LIBCXX_ENABLE_FILESYSTEM:BOOL + + **Default**: ``LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY`` + + Build filesystem as part of libc++experimental.a. This allows filesystem + to be disabled without turning off the entire experimental library. + + .. _ABI Library Specific Options: ABI Library Specific Options @@ -304,3 +345,72 @@ own copy of libsupc++ and this can lead to subtle problems. $ make install You can now run clang with -stdlib=libc++. + + +.. _libcxxrt_ref: + +Using libcxxrt on Linux +------------------------ + +You will need to keep the source tree of `libcxxrt`_ available +on your build machine and your copy of the libcxxrt shared library must +be placed where your linker will find it. + +We can now run CMake like: + +.. code-block:: bash + + $ CC=clang CXX=clang++ cmake -G "Unix Makefiles" \ + -DLIBCXX_CXX_ABI=libcxxrt \ + -DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/libcxxrt-sources/src \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr \ + <libc++-source-directory> + $ make cxx + $ make install + +Unfortunately you can't simply run clang with "-stdlib=libc++" at this point, as +clang is set up to link for libc++ linked to libsupc++. To get around this +you'll have to set up your linker yourself (or patch clang). For example, + +.. code-block:: bash + + $ clang++ -stdlib=libc++ helloworld.cpp \ + -nodefaultlibs -lc++ -lcxxrt -lm -lc -lgcc_s -lgcc + +Alternately, you could just add libcxxrt to your libraries list, which in most +situations will give the same result: + +.. code-block:: bash + + $ clang++ -stdlib=libc++ helloworld.cpp -lcxxrt + +.. _`libcxxrt`: https://github.com/pathscale/libcxxrt/ + + +Using a local ABI library installation +--------------------------------------- + +.. warning:: + This is not recommended in almost all cases. + +These instructions should only be used when you can't install your ABI library. + +Normally you must link libc++ against a ABI shared library that the +linker can find. If you want to build and test libc++ against an ABI +library not in the linker's path you needq to set +``-DLIBCXX_CXX_ABI_LIBRARY_PATH=/path/to/abi/lib`` when configuring CMake. + +An example build using libc++abi would look like: + +.. code-block:: bash + + $ CC=clang CXX=clang++ cmake \ + -DLIBCXX_CXX_ABI=libc++abi \ + -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/path/to/libcxxabi/include" \ + -DLIBCXX_CXX_ABI_LIBRARY_PATH="/path/to/libcxxabi-build/lib" \ + path/to/libcxx + $ make + +When testing libc++ LIT will automatically link against the proper ABI +library. diff --git a/docs/TestingLibcxx.rst b/docs/TestingLibcxx.rst index 98162d9c2e056..9226ae17023ed 100644 --- a/docs/TestingLibcxx.rst +++ b/docs/TestingLibcxx.rst @@ -98,7 +98,7 @@ configuration. Passing the option on the command line will override the default. .. program:: lit -.. option:: cxx_under_test=<path/to/compiler> +.. option:: --cxx_under_test=<path/to/compiler> Specify the compiler used to build the tests. @@ -108,37 +108,46 @@ configuration. Passing the option on the command line will override the default. Change the standard version used when building the tests. -.. option:: libcxx_site_config=<path/to/lit.site.cfg> +.. option:: --libcxx_site_config=<path/to/lit.site.cfg> Specify the site configuration to use when running the tests. This option overrides the enviroment variable LIBCXX_SITE_CONFIG. -.. option:: libcxx_headers=<path/to/headers> +.. option:: --libcxx_headers=<path/to/headers> Specify the libc++ headers that are tested. By default the headers in the source tree are used. -.. option:: libcxx_library=<path/to/libc++.so> +.. option:: --cxx_library_root=<path/to/lib/> - Specify the libc++ library that is tested. By default the library in the - build directory is used. This option cannot be used when use_system_lib is - provided. + Specify the directory of the libc++ library to be tested. By default the + library folder of the build directory is used. This option cannot be used + when use_system_lib is provided. -.. option:: use_system_lib=<bool> + +.. option:: --cxx_runtime_root=<path/to/lib/> + + Specify the directory of the libc++ library to use at runtime. This directory + is not added to the linkers search path. This can be used to compile tests + against one version of libc++ and run them using another. The default value + for this option is `cxx_library_root`. This option cannot be used + when use_system_lib is provided. + +.. option:: --use_system_lib=<bool> **Default**: False Enable or disable testing against the installed version of libc++ library. Note: This does not use the installed headers. -.. option:: use_lit_shell=<bool> +.. option:: --use_lit_shell=<bool> Enable or disable the use of LIT's internal shell in ShTests. If the environment variable LIT_USE_INTERNAL_SHELL is present then that is used as the default value. Otherwise the default value is True on Windows and False on every other platform. -.. option:: no_default_flags=<bool> +.. option:: --no_default_flags=<bool> **Default**: False @@ -146,16 +155,16 @@ configuration. Passing the option on the command line will override the default. option is used only flags specified using the compile_flags and link_flags will be used. -.. option:: compile_flags="<list-of-args>" +.. option:: --compile_flags="<list-of-args>" Specify additional compile flags as a space delimited string. Note: This options should not be used to change the standard version used. -.. option:: link_flags="<list-of-args>" +.. option:: --link_flags="<list-of-args>" Specify additional link flags as a space delimited string. -.. option:: debug_level=<level> +.. option:: --debug_level=<level> **Values**: 0, 1 diff --git a/docs/UsingLibcxx.rst b/docs/UsingLibcxx.rst index 2a117917638ce..514ed14b7464a 100644 --- a/docs/UsingLibcxx.rst +++ b/docs/UsingLibcxx.rst @@ -49,7 +49,30 @@ An example of using ``LD_LIBRARY_PATH``: $ export LD_LIBRARY_PATH=<libcxx-install-prefix>/lib $ ./a.out # Searches for libc++ along LD_LIBRARY_PATH +Using libc++experimental and ``<experimental/...>`` +===================================================== +Libc++ provides implementations of experimental technical specifications +in a separate library, ``libc++experimental.a``. Users of ``<experimental/...>`` +headers may be required to link ``-lc++experimental``. + +.. code-block:: bash + + $ clang++ -std=c++14 -stdlib=libc++ test.cpp -lc++experimental + +Libc++experimental.a may not always be available, even when libc++ is already +installed. For information on building libc++experimental from source see +:ref:`Building Libc++ <build instructions>` and +:ref:`libc++experimental CMake Options <libc++experimental options>`. + +Also see the `Experimental Library Implementation Status <http://libcxx.llvm.org/ts1z_status.html>`__ +page. + +.. warning:: + Experimental libraries are Experimental. + * The contents of the ``<experimental/...>`` headers and ``libc++experimental.a`` + library will not remain compatible between versions. + * No guarantees of API or ABI stability are provided. Using libc++ on Linux ===================== @@ -87,3 +110,16 @@ not just libstdc++ so they must be manually linked. For example: $ g++ -nostdinc++ -I<libcxx-install-prefix>/include/c++/v1 \ test.cpp -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc + + +GDB Pretty printers for libc++ +------------------------------ + +GDB does not support pretty-printing of libc++ symbols by default. Unfortunately +libc++ does not provide pretty-printers itself. However there are 3rd +party implementations available and although they are not officially +supported by libc++ they may be useful to users. + +Known 3rd Party Implementations Include: + +* `Koutheir's libc++ pretty-printers <https://github.com/koutheir/libcxx-pretty-printers>`_. diff --git a/docs/conf.py b/docs/conf.py index 915daa47a514b..e385406b99239 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -40,16 +40,16 @@ master_doc = 'index' # General information about the project. project = u'libc++' -copyright = u'2011-2015, LLVM Project' +copyright = u'2011-2016, LLVM Project' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '3.8' +version = '3.9' # The full version, including alpha/beta/rc tags. -release = '3.8' +release = '3.9' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index e16dc8b4de63d..219d1b730839e 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -19,7 +19,7 @@ file(COPY . if (LIBCXX_INSTALL_HEADERS) install(DIRECTORY . DESTINATION include/c++/v1 - COMPONENT libcxx + COMPONENT libcxx-headers FILES_MATCHING ${LIBCXX_HEADER_PATTERN} PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ @@ -41,12 +41,23 @@ if (LIBCXX_INSTALL_HEADERS) # Add a target that executes the generation commands. add_custom_target(generate_config_header ALL DEPENDS ${LIBCXX_BINARY_DIR}/__generated_config) + set(generated_config_deps generate_config_header) # Install the generated header as __config. install(FILES ${LIBCXX_BINARY_DIR}/__generated_config DESTINATION include/c++/v1 PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ RENAME __config - COMPONENT libcxx) + COMPONENT libcxx-headers) + endif() + + if (NOT CMAKE_CONFIGURATION_TYPES) + # this target is just needed as a placeholder for the distribution target + add_custom_target(libcxx-headers) + add_custom_target(install-libcxx-headers + DEPENDS libcxx-headers ${generated_config_deps} + COMMAND "${CMAKE_COMMAND}" + -DCMAKE_INSTALL_COMPONENT=libcxx-headers + -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") endif() endif() diff --git a/include/__bsd_locale_defaults.h b/include/__bsd_locale_defaults.h new file mode 100644 index 0000000000000..f315ca2949e31 --- /dev/null +++ b/include/__bsd_locale_defaults.h @@ -0,0 +1,33 @@ +// -*- C++ -*- +//===---------------------- __bsd_locale_defaults.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. +// +//===----------------------------------------------------------------------===// +// The BSDs have lots of *_l functions. We don't want to define those symbols +// on other platforms though, for fear of conflicts with user code. So here, +// we will define the mapping from an internal macro to the real BSD symbol. +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_BSD_LOCALE_DEFAULTS_H +#define _LIBCPP_BSD_LOCALE_DEFAULTS_H + +#define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc) +#define __libcpp_btowc_l(ch, loc) btowc_l(ch, loc) +#define __libcpp_wctob_l(wch, loc) wctob_l(wch, loc) +#define __libcpp_wcsnrtombs_l(dst, src, nwc, len, ps, loc) wcsnrtombs_l(dst, src, nwc, len, ps, loc) +#define __libcpp_wcrtomb_l(src, wc, ps, loc) wcrtomb_l(src, wc, ps, loc) +#define __libcpp_mbsnrtowcs_l(dst, src, nms, len, ps, loc) mbsnrtowcs_l(dst, src, nms, len, ps, loc) +#define __libcpp_mbrtowc_l(pwc, s, n, ps, l) mbrtowc_l(pwc, s, n, ps, l) +#define __libcpp_mbtowc_l(pwc, pmb, max, l) mbtowc_l(pwc, pmb, max, l) +#define __libcpp_mbrlen_l(s, n, ps, l) mbrlen_l(s, n, ps, l) +#define __libcpp_localeconv_l(l) localeconv_l(l) +#define __libcpp_mbsrtowcs_l(dest, src, len, ps, l) mbsrtowcs_l(dest, src, len, ps, l) +#define __libcpp_snprintf_l(...) snprintf_l(__VA_ARGS__) +#define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__) +#define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__) + +#endif // _LIBCPP_BSD_LOCALE_DEFAULTS_H diff --git a/include/__bsd_locale_fallbacks.h b/include/__bsd_locale_fallbacks.h new file mode 100644 index 0000000000000..cbc8ad226fd20 --- /dev/null +++ b/include/__bsd_locale_fallbacks.h @@ -0,0 +1,138 @@ +// -*- C++ -*- +//===---------------------- __bsd_locale_fallbacks.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. +// +//===----------------------------------------------------------------------===// +// The BSDs have lots of *_l functions. This file provides reimplementations +// of those functions for non-BSD platforms. +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H +#define _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H + +#include <stdlib.h> +#include <memory> + +_LIBCPP_BEGIN_NAMESPACE_STD + +typedef _VSTD::remove_pointer<locale_t>::type __use_locale_struct; +typedef _VSTD::unique_ptr<__use_locale_struct, decltype(&uselocale)> __locale_raii; + +inline _LIBCPP_ALWAYS_INLINE +decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return MB_CUR_MAX; +} + +inline _LIBCPP_ALWAYS_INLINE +wint_t __libcpp_btowc_l(int __c, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return btowc(__c); +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_wctob_l(wint_t __c, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return wctob(__c); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __libcpp_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, + size_t __len, mbstate_t *__ps, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return wcsnrtombs(__dest, __src, __nwc, __len, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __libcpp_wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return wcrtomb(__s, __wc, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __libcpp_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, + size_t __len, mbstate_t *__ps, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return mbsnrtowcs(__dest, __src, __nms, __len, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __libcpp_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, + mbstate_t *__ps, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return mbrtowc(__pwc, __s, __n, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return mbtowc(__pwc, __pmb, __max); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return mbrlen(__s, __n, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +lconv *__libcpp_localeconv_l(locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return localeconv(); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, + mbstate_t *__ps, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return mbsrtowcs(__dest, __src, __len, __ps); +} + +inline +int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); + __locale_raii __current( uselocale(__l), uselocale ); + int __res = vsnprintf(__s, __n, __format, __va); + va_end(__va); + return __res; +} + +inline +int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); + __locale_raii __current( uselocale(__l), uselocale ); + int __res = vasprintf(__s, __format, __va); + va_end(__va); + return __res; +} + +inline +int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); + __locale_raii __current( uselocale(__l), uselocale ); + int __res = vsscanf(__s, __format, __va); + va_end(__va); + return __res; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H diff --git a/include/__config b/include/__config index db5a832b6cd14..3edb9de017abd 100644 --- a/include/__config +++ b/include/__config @@ -27,7 +27,7 @@ #define _GNUC_VER 0 #endif -#define _LIBCPP_VERSION 3800 +#define _LIBCPP_VERSION 3900 #ifndef _LIBCPP_ABI_VERSION #define _LIBCPP_ABI_VERSION 1 @@ -41,6 +41,22 @@ #define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE // Fix undefined behavior in how std::list stores it's linked nodes. #define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB +// Fix undefined behavior in how __tree stores its end and parent nodes. +#define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB +#define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB +#define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#elif _LIBCPP_ABI_VERSION == 1 +// Feature macros for disabling pre ABI v1 features. All of these options +// are deprecated. +#if defined(__FreeBSD__) +#define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR +#endif +#endif + +#ifdef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR +#error "_LIBCPP_TRIVIAL_PAIR_COPY_CTOR" is no longer supported. \ + use _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR instead #endif #define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y @@ -178,6 +194,12 @@ # endif #endif // !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN) +#if __has_attribute(__no_sanitize__) +#define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi"))) +#else +#define _LIBCPP_NO_CFI +#endif + #ifdef _WIN32 // only really useful for a DLL @@ -236,6 +258,12 @@ # endif #endif +#ifndef _LIBCPP_PREFERRED_OVERLOAD +# if __has_attribute(__enable_if__) +# define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, ""))) +# endif +#endif + #ifndef _LIBCPP_TYPE_VIS_ONLY # define _LIBCPP_TYPE_VIS_ONLY _LIBCPP_TYPE_VIS #endif @@ -283,7 +311,7 @@ typedef __char16_t char16_t; typedef __char32_t char32_t; #endif -#if !(__has_feature(cxx_exceptions)) +#if !(__has_feature(cxx_exceptions)) && !defined(_LIBCPP_NO_EXCEPTIONS) #define _LIBCPP_NO_EXCEPTIONS #endif @@ -305,8 +333,6 @@ typedef __char32_t char32_t; # define _LIBCPP_NORETURN __attribute__ ((noreturn)) #endif -#define _LIBCPP_UNUSED __attribute__((__unused__)) - #if !(__has_feature(cxx_default_function_template_args)) #define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS #endif @@ -434,8 +460,8 @@ namespace std { #endif // Allow for build-time disabling of unsigned integer sanitization -#ifndef _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK -#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute((no_sanitize("unsigned-integer-overflow"))) +#if !defined(_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK) && __has_attribute(no_sanitize) +#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow"))) #endif #elif defined(__GNUC__) @@ -445,8 +471,6 @@ namespace std { #define _LIBCPP_NORETURN __attribute__((noreturn)) -#define _LIBCPP_UNUSED __attribute__((__unused__)) - #if _GNUC_VER >= 407 #define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T) #define _LIBCPP_IS_LITERAL(T) __is_literal_type(T) @@ -461,8 +485,6 @@ namespace std { #define _LIBCPP_NO_EXCEPTIONS #endif -#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES - // constexpr was added to GCC in 4.6. #if _GNUC_VER < 406 #define _LIBCPP_HAS_NO_CONSTEXPR @@ -494,6 +516,7 @@ namespace std { #define _LIBCPP_HAS_NO_VARIADICS #define _LIBCPP_HAS_NO_RVALUE_REFERENCES #define _LIBCPP_HAS_NO_STRONG_ENUMS +#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES #define _LIBCPP_HAS_NO_NOEXCEPT #else // __GXX_EXPERIMENTAL_CXX0X__ @@ -517,6 +540,7 @@ namespace std { #if _GNUC_VER < 406 #define _LIBCPP_HAS_NO_NOEXCEPT #define _LIBCPP_HAS_NO_NULLPTR +#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES #endif #if _GNUC_VER < 407 @@ -552,7 +576,6 @@ using namespace _LIBCPP_NAMESPACE __attribute__((__strong__)); #define _LIBCPP_HAS_NO_NOEXCEPT #define __alignof__ __alignof #define _LIBCPP_NORETURN __declspec(noreturn) -#define _LIBCPP_UNUSED #define _ALIGNAS(x) __declspec(align(x)) #define _LIBCPP_HAS_NO_VARIADICS @@ -574,7 +597,6 @@ namespace std { #define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) #define _ATTRIBUTE(x) __attribute__((x)) #define _LIBCPP_NORETURN __attribute__((noreturn)) -#define _LIBCPP_UNUSED #define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS #define _LIBCPP_HAS_NO_TEMPLATE_ALIASES @@ -655,6 +677,12 @@ template <unsigned> struct __static_assert_check {}; #define _LIBCPP_DEFAULT = default; #endif +#ifdef _LIBCPP_HAS_NO_DELETED_FUNCTIONS +#define _LIBCPP_EQUAL_DELETE +#else +#define _LIBCPP_EQUAL_DELETE = delete +#endif + #ifdef __GNUC__ #define _NOALIAS __attribute__((__malloc__)) #else @@ -712,10 +740,12 @@ template <unsigned> struct __static_assert_check {}; #define _LIBCPP_LOCALE__L_EXTENSIONS 1 #endif -#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(_NEWLIB_VERSION) && \ - !defined(__CloudABI__) +#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +// Most unix variants have catopen. These are the specific ones that don't. +#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(_NEWLIB_VERSION) #define _LIBCPP_HAS_CATOPEN 1 #endif +#endif #ifdef __FreeBSD__ #define _DECLARE_C99_LDBL_MATH 1 @@ -729,17 +759,13 @@ template <unsigned> struct __static_assert_check {}; #define _LIBCPP_WCTYPE_IS_MASK #endif -#ifndef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR -# define _LIBCPP_TRIVIAL_PAIR_COPY_CTOR 1 -#endif - #ifndef _LIBCPP_STD_VER # if __cplusplus <= 201103L # define _LIBCPP_STD_VER 11 # elif __cplusplus <= 201402L # define _LIBCPP_STD_VER 14 # else -# define _LIBCPP_STD_VER 15 // current year, or date of c++17 ratification +# define _LIBCPP_STD_VER 16 // current year, or date of c++17 ratification # endif #endif // _LIBCPP_STD_VER @@ -763,6 +789,12 @@ template <unsigned> struct __static_assert_check {}; #define _LIBCPP_CONSTEXPR_AFTER_CXX11 #endif +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +#define _LIBCPP_CONSTEXPR_AFTER_CXX14 constexpr +#else +#define _LIBCPP_CONSTEXPR_AFTER_CXX14 +#endif + #ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES # define _LIBCPP_EXPLICIT_MOVE(x) _VSTD::move(x) #else @@ -790,6 +822,25 @@ extern "C" void __sanitizer_annotate_contiguous_container( # define _LIBCPP_WEAK __attribute__((__weak__)) #endif +// Thread API +#if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +# if defined(__FreeBSD__) || \ + defined(__NetBSD__) || \ + defined(__linux__) || \ + defined(__APPLE__) || \ + defined(__CloudABI__) || \ + defined(__sun__) +# define _LIBCPP_HAS_THREAD_API_PTHREAD +# else +# error "No thread API" +# endif // _LIBCPP_HAS_THREAD_API +#endif // _LIBCPP_HAS_NO_THREADS + +#if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +# error _LIBCPP_HAS_THREAD_API_PTHREAD may only be defined when \ + _LIBCPP_HAS_NO_THREADS is not defined. +#endif + #if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS) # error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \ _LIBCPP_HAS_NO_THREADS is defined. @@ -833,7 +884,20 @@ extern "C" void __sanitizer_annotate_contiguous_container( #ifndef _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK #define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK -#endif +#endif + +#if __cplusplus < 201103L +#define _LIBCPP_CXX03_LANG +#else +#if defined(_LIBCPP_HAS_NO_VARIADIC_TEMPLATES) || defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) +#error Libc++ requires a feature complete C++11 compiler in C++11 or greater. +#endif +#endif + +#if (defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) && defined(__clang__) \ + && __has_attribute(acquire_capability)) +#define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS +#endif #endif // __cplusplus diff --git a/include/__config_site.in b/include/__config_site.in index ec64485289fa5..6c2b7bb446d72 100644 --- a/include/__config_site.in +++ b/include/__config_site.in @@ -19,5 +19,6 @@ #cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK #cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS #cmakedefine _LIBCPP_HAS_MUSL_LIBC +#cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD #endif // _LIBCPP_CONFIG_SITE diff --git a/include/__functional_base b/include/__functional_base index 52c535aa3ea11..1a08ea29deea3 100644 --- a/include/__functional_base +++ b/include/__functional_base @@ -38,8 +38,6 @@ struct _LIBCPP_TYPE_VIS_ONLY binary_function typedef _Result result_type; }; -template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash; - template <class _Tp> struct __has_result_type { @@ -306,75 +304,19 @@ struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> #endif // _LIBCPP_HAS_NO_VARIADICS -// __invoke - -#ifndef _LIBCPP_HAS_NO_VARIADICS - -// bullets 1 and 2 - -template <class _Fp, class _A0, class ..._Args, - class> -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)) -{ - return (_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...); -} - -template <class _Fp, class _A0, class ..._Args, - class> -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)) -{ - return ((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...); -} - -// bullets 3 and 4 +#ifndef _LIBCPP_CXX03_LANG -template <class _Fp, class _A0, - class> -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0) - -> decltype(_VSTD::forward<_A0>(__a0).*__f) -{ - return _VSTD::forward<_A0>(__a0).*__f; -} - -template <class _Fp, class _A0, - class> -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0) - -> decltype((*_VSTD::forward<_A0>(__a0)).*__f) -{ - return (*_VSTD::forward<_A0>(__a0)).*__f; -} - -// bullet 5 - -template <class _Fp, class ..._Args> -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _Args&& ...__args) - -> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)) -{ - 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 +#else // defined(_LIBCPP_CXX03_LANG) #include <__functional_base_03> -#endif // _LIBCPP_HAS_NO_VARIADICS +#endif // !defined(_LIBCPP_CXX03_LANG) template <class _Ret> @@ -577,10 +519,6 @@ public: #endif // _LIBCPP_HAS_NO_VARIADICS }; -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 diff --git a/include/__hash_table b/include/__hash_table index c7d1ef3d082f4..08bc519ae17f2 100644 --- a/include/__hash_table +++ b/include/__hash_table @@ -17,6 +17,7 @@ #include <iterator> #include <algorithm> #include <cmath> +#include <utility> #include <__undef_min_max> #include <__undef___deallocate> @@ -29,6 +30,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_CXX03_LANG +template <class _Key, class _Tp> +union __hash_value_type; +#else +template <class _Key, class _Tp> +struct __hash_value_type; +#endif + +#ifndef _LIBCPP_CXX03_LANG +template <class _Tp> +struct __is_hash_value_type_imp : false_type {}; + +template <class _Key, class _Value> +struct __is_hash_value_type_imp<__hash_value_type<_Key, _Value>> : true_type {}; + +template <class ..._Args> +struct __is_hash_value_type : false_type {}; + +template <class _One> +struct __is_hash_value_type<_One> : __is_hash_value_type_imp<typename __uncvref<_One>::type> {}; +#endif + _LIBCPP_FUNC_VIS size_t __next_prime(size_t __n); @@ -49,10 +73,10 @@ struct __hash_node typename __rebind_pointer<_VoidPtr, __hash_node<_Tp, _VoidPtr> >::type > { - typedef _Tp value_type; + typedef _Tp __node_value_type; size_t __hash_; - value_type __value_; + __node_value_type __value_; }; inline _LIBCPP_INLINE_VISIBILITY @@ -66,7 +90,8 @@ inline _LIBCPP_INLINE_VISIBILITY size_t __constrain_hash(size_t __h, size_t __bc) { - return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : __h % __bc; + return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : + (__h < __bc ? __h : __h % __bc); } inline _LIBCPP_INLINE_VISIBILITY @@ -76,24 +101,173 @@ __next_hash_pow2(size_t __n) return size_t(1) << (std::numeric_limits<size_t>::digits - __clz(__n-1)); } + template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table; + +template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_iterator; template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator; +template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_local_iterator; +template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_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 _Tp> +struct __hash_key_value_types { + static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, ""); + typedef _Tp key_type; + typedef _Tp __node_value_type; + typedef _Tp __container_value_type; + static const bool __is_map = false; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& __get_key(_Tp const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type const& __get_value(__node_value_type const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n); + } +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + static __container_value_type&& __move(__node_value_type& __v) { + return _VSTD::move(__v); + } +#endif +}; + +template <class _Key, class _Tp> +struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { + typedef _Key key_type; + typedef _Tp mapped_type; + typedef __hash_value_type<_Key, _Tp> __node_value_type; + typedef pair<const _Key, _Tp> __container_value_type; + typedef pair<_Key, _Tp> __nc_value_type; + typedef __container_value_type __map_value_type; + static const bool __is_map = true; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& __get_key(__container_value_type const& __v) { + return __v.first; + } + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + static typename enable_if<__is_same_uncvref<_Up, __node_value_type>::value, + __container_value_type const&>::type + __get_value(_Up& __t) { + return __t.__cc; + } + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, + __container_value_type const&>::type + __get_value(_Up& __t) { + return __t; + } + + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n.__cc); + } +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + static __nc_value_type&& __move(__node_value_type& __v) { + return _VSTD::move(__v.__nc); + } +#endif + +}; + +template <class _Tp, class _AllocPtr, class _KVTypes = __hash_key_value_types<_Tp>, + bool = _KVTypes::__is_map> +struct __hash_map_pointer_types {}; + +template <class _Tp, class _AllocPtr, class _KVTypes> +struct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { + typedef typename _KVTypes::__map_value_type _Mv; + typedef typename __rebind_pointer<_AllocPtr, _Mv>::type + __map_value_type_pointer; + typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type + __const_map_value_type_pointer; +}; + +template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type> +struct __hash_node_types; + +template <class _NodePtr, class _Tp, class _VoidPtr> +struct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> > + : public __hash_key_value_types<_Tp>, __hash_map_pointer_types<_Tp, _VoidPtr> + +{ + typedef __hash_key_value_types<_Tp> __base; + +public: + typedef ptrdiff_t difference_type; + typedef size_t size_type; + + typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer; + + typedef typename pointer_traits<_NodePtr>::element_type __node_type; + typedef _NodePtr __node_pointer; + + typedef __hash_node_base<__node_pointer> __node_base_type; + typedef typename __rebind_pointer<_NodePtr, __node_base_type>::type + __node_base_pointer; + + typedef _Tp __node_value_type; + typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type + __node_value_type_pointer; + typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type + __const_node_value_type_pointer; +private: + static_assert(!is_const<__node_type>::value, + "_NodePtr should never be a pointer to const"); + static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value), + "_VoidPtr does not point to unqualified void type"); + static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type, + _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); +}; + + + +template <class _HashIterator> +struct __hash_node_types_from_iterator; +template <class _NodePtr> +struct __hash_node_types_from_iterator<__hash_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; +template <class _NodePtr> +struct __hash_node_types_from_iterator<__hash_const_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; +template <class _NodePtr> +struct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; +template <class _NodePtr> +struct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; + + +template <class _NodeValueTp, class _VoidPtr> +struct __make_hash_node_types { + typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp; + typedef typename __rebind_pointer<_VoidPtr, _NodeTp>::type _NodePtr; + typedef __hash_node_types<_NodePtr> type; +}; + template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_iterator { - typedef _NodePtr __node_pointer; + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; __node_pointer __node_; public: - typedef forward_iterator_tag iterator_category; - typedef typename pointer_traits<__node_pointer>::element_type::value_type value_type; - typedef typename pointer_traits<__node_pointer>::difference_type difference_type; - typedef value_type& reference; - typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer; + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef value_type& reference; + typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT #if _LIBCPP_STD_VER > 11 @@ -202,25 +376,24 @@ private: template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap; }; -template <class _ConstNodePtr> +template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator { - typedef _ConstNodePtr __node_pointer; - - __node_pointer __node_; + static_assert(!is_const<typename pointer_traits<_NodePtr>::element_type>::value, ""); + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; - typedef typename remove_const< - typename pointer_traits<__node_pointer>::element_type - >::type __node; + __node_pointer __node_; public: - typedef forward_iterator_tag iterator_category; - typedef typename __node::value_type value_type; - typedef typename pointer_traits<__node_pointer>::difference_type difference_type; - typedef const value_type& reference; - typedef typename __rebind_pointer<__node_pointer, const value_type>::type pointer; - typedef typename __rebind_pointer<__node_pointer, __node>::type __non_const_node_pointer; - typedef __hash_iterator<__non_const_node_pointer> __non_const_iterator; + typedef __hash_iterator<_NodePtr> __non_const_iterator; + + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; + _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT #if _LIBCPP_STD_VER > 11 @@ -336,24 +509,22 @@ private: template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap; }; -template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator; - template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_local_iterator { - typedef _NodePtr __node_pointer; + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; __node_pointer __node_; size_t __bucket_; size_t __bucket_count_; - typedef pointer_traits<__node_pointer> __pointer_traits; public: typedef forward_iterator_tag iterator_category; - typedef typename __pointer_traits::element_type::value_type value_type; - typedef typename __pointer_traits::difference_type difference_type; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; typedef value_type& reference; - typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer; + typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT { @@ -476,7 +647,8 @@ private: template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator { - typedef _ConstNodePtr __node_pointer; + typedef __hash_node_types<_ConstNodePtr> _NodeTypes; + typedef _ConstNodePtr __node_pointer; __node_pointer __node_; size_t __bucket_; @@ -487,18 +659,15 @@ class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator typedef typename remove_const<__node>::type __non_const_node; typedef typename __rebind_pointer<__node_pointer, __non_const_node>::type __non_const_node_pointer; - +public: typedef __hash_local_iterator<__non_const_node_pointer> __non_const_iterator; -public: - typedef forward_iterator_tag iterator_category; - typedef typename remove_const< - typename __pointer_traits::element_type::value_type - >::type value_type; - typedef typename __pointer_traits::difference_type difference_type; - typedef const value_type& reference; - typedef typename __rebind_pointer<__node_pointer, const value_type>::type - pointer; + + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT @@ -686,10 +855,11 @@ class __hash_node_destructor { typedef _Alloc allocator_type; typedef allocator_traits<allocator_type> __alloc_traits; - typedef typename __alloc_traits::value_type::value_type value_type; + public: typedef typename __alloc_traits::pointer pointer; private: + typedef __hash_node_types<pointer> _NodeTypes; allocator_type& __na_; @@ -709,7 +879,7 @@ public: void operator()(pointer __p) _NOEXCEPT { if (__value_constructed) - __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_)); + __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); if (__p) __alloc_traits::deallocate(__na_, __p, 1); } @@ -728,23 +898,47 @@ public: private: typedef allocator_traits<allocator_type> __alloc_traits; + typedef typename + __make_hash_node_types<value_type, typename __alloc_traits::void_pointer>::type + _NodeTypes; public: + + typedef typename _NodeTypes::__node_value_type __node_value_type; + typedef typename _NodeTypes::__container_value_type __container_value_type; + typedef typename _NodeTypes::key_type key_type; typedef value_type& reference; typedef const value_type& const_reference; typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; +#ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE typedef typename __alloc_traits::size_type size_type; - typedef typename __alloc_traits::difference_type difference_type; +#else + typedef typename _NodeTypes::size_type size_type; +#endif + typedef typename _NodeTypes::difference_type difference_type; public: // Create __node - typedef __hash_node<value_type, typename __alloc_traits::void_pointer> __node; + + typedef typename _NodeTypes::__node_type __node; 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; - typedef __hash_node_base<__node_pointer> __first_node; - typedef typename __rebind_pointer<__node_pointer, __first_node>::type - __node_base_pointer; + typedef typename _NodeTypes::__void_pointer __void_pointer; + typedef typename _NodeTypes::__node_pointer __node_pointer; + typedef typename _NodeTypes::__node_pointer __node_const_pointer; + typedef typename _NodeTypes::__node_base_type __first_node; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + +private: + // check for sane allocator pointer rebinding semantics. Rebinding the + // allocator for a new pointer type should be exactly the same as rebinding + // the pointer using 'pointer_traits'. + static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); + typedef typename __rebind_alloc_helper<__node_traits, __first_node>::type + __node_base_allocator; + typedef allocator_traits<__node_base_allocator> __node_base_traits; + static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); private: @@ -755,10 +949,10 @@ private: typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; // --- Member data begin --- - __bucket_list __bucket_list_; - __compressed_pair<__first_node, __node_allocator> __p1_; - __compressed_pair<size_type, hasher> __p2_; - __compressed_pair<float, key_equal> __p3_; + __bucket_list __bucket_list_; + __compressed_pair<__first_node, __node_allocator> __p1_; + __compressed_pair<size_type, hasher> __p2_; + __compressed_pair<float, key_equal> __p3_; // --- Member data end --- _LIBCPP_INLINE_VISIBILITY @@ -809,7 +1003,7 @@ public: explicit __hash_table(const allocator_type& __a); __hash_table(const __hash_table& __u); __hash_table(const __hash_table& __u, const allocator_type& __a); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG __hash_table(__hash_table&& __u) _NOEXCEPT_( is_nothrow_move_constructible<__bucket_list>::value && @@ -818,11 +1012,11 @@ public: is_nothrow_move_constructible<hasher>::value && is_nothrow_move_constructible<key_equal>::value); __hash_table(__hash_table&& __u, const allocator_type& __a); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // _LIBCPP_CXX03_LANG ~__hash_table(); __hash_table& operator=(const __hash_table& __u); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY __hash_table& operator=(__hash_table&& __u) _NOEXCEPT_( @@ -848,41 +1042,103 @@ public: iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) - template <class... _Args> - pair<iterator, bool> __emplace_unique(_Args&&... __args); - template <class... _Args> - iterator __emplace_multi(_Args&&... __args); +#ifndef _LIBCPP_CXX03_LANG + template <class _Key, class ..._Args> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args); + template <class... _Args> - iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); -#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique_impl(_Args&&... __args); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - template <class _ValueTp> + template <class _Pp> _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> __insert_unique_value(_ValueTp&& __x); -#else + pair<iterator, bool> __emplace_unique(_Pp&& __x) { + return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template <class _First, class _Second> _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> __insert_unique_value(const value_type& __x); -#endif + typename enable_if< + __can_extract_map_key<_First, key_type, __container_value_type>::value, + pair<iterator, bool> + >::type __emplace_unique(_First&& __f, _Second&& __s) { + return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), + _VSTD::forward<_Second>(__s)); + } - pair<iterator, bool> __insert_unique(const value_type& __x); + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique(_Args&&... __args) { + return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); + } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - pair<iterator, bool> __insert_unique(value_type&& __x); template <class _Pp> - pair<iterator, bool> __insert_unique(_Pp&& __x); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { + return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); + } + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { + return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); + } + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { + return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); + } + + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_multi(_Args&&... __args); + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); + + + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __insert_unique(__container_value_type&& __x) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x)); + } + + template <class _Pp, class = typename enable_if< + !__is_same_uncvref<_Pp, __container_value_type>::value + >::type> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __insert_unique(_Pp&& __x) { + return __emplace_unique(_VSTD::forward<_Pp>(__x)); + } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Pp> - iterator __insert_multi(_Pp&& __x); + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(_Pp&& __x) { + return __emplace_multi(_VSTD::forward<_Pp>(__x)); + } + template <class _Pp> - iterator __insert_multi(const_iterator __p, _Pp&& __x); -#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES - iterator __insert_multi(const value_type& __x); - iterator __insert_multi(const_iterator __p, const value_type& __x); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const_iterator __p, _Pp&& __x) { + return __emplace_hint_multi(__p, _VSTD::forward<_Pp>(__x)); + } + +#else // !defined(_LIBCPP_CXX03_LANG) + template <class _Key, class _Args> + pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args& __args); + + iterator __insert_multi(const __container_value_type& __x); + iterator __insert_multi(const_iterator __p, const __container_value_type& __x); +#endif + + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __insert_unique(const __container_value_type& __x) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); + } void clear() _NOEXCEPT; void rehash(size_type __n); @@ -1042,16 +1298,17 @@ public: private: void __rehash(size_type __n); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_CXX03_LANG template <class ..._Args> - __node_holder __construct_node(_Args&& ...__args); -#endif // _LIBCPP_HAS_NO_VARIADICS - __node_holder __construct_node(value_type&& __v, size_t __hash); -#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES - __node_holder __construct_node(const value_type& __v); + __node_holder __construct_node(_Args&& ...__args); + + template <class _First, class ..._Rest> + __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); +#else // _LIBCPP_CXX03_LANG + __node_holder __construct_node(const __container_value_type& __v); + __node_holder __construct_node_hash(size_t __hash, const __container_value_type& __v); #endif - __node_holder __construct_node(const value_type& __v, size_t __hash); + _LIBCPP_INLINE_VISIBILITY void __copy_assign_alloc(const __hash_table& __u) @@ -1061,6 +1318,7 @@ private: _LIBCPP_INLINE_VISIBILITY void __copy_assign_alloc(const __hash_table&, false_type) {} +#ifndef _LIBCPP_CXX03_LANG void __move_assign(__hash_table& __u, false_type); void __move_assign(__hash_table& __u, true_type) _NOEXCEPT_( @@ -1087,6 +1345,7 @@ private: } _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} +#endif // _LIBCPP_CXX03_LANG void __deallocate(__node_pointer __np) _NOEXCEPT; __node_pointer __detach() _NOEXCEPT; @@ -1163,7 +1422,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, { } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) @@ -1212,11 +1471,15 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, } } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() { + static_assert((is_copy_constructible<key_equal>::value), + "Predicate must be copy-constructible."); + static_assert((is_copy_constructible<hasher>::value), + "Hasher must be copy-constructible."); __deallocate(__p1_.first().__next_); #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__erase_c(this); @@ -1277,7 +1540,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate(__node_pointer __np) } __get_db()->unlock(); #endif - __node_traits::destroy(__na, _VSTD::addressof(__np->__value_)); + __node_traits::destroy(__na, _NodeTypes::__get_ptr(__np->__value_)); __node_traits::deallocate(__na, __np, 1); __np = __next; } @@ -1296,7 +1559,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT return __cache; } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> void @@ -1369,8 +1632,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( const_iterator __i = __u.begin(); while (__u.size() != 0) { - __node_holder __h = - __construct_node(_VSTD::move(__u.remove(__i++)->__value_)); + __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__value_)); __node_insert_multi(__h.get()); __h.release(); } @@ -1392,7 +1654,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) return *this; } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> template <class _InputIterator> @@ -1400,6 +1662,11 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, _InputIterator __last) { + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value), + "__assign_unique may only be called with the containers value type"); + if (bucket_count() != 0) { __node_pointer __cache = __detach(); @@ -1434,6 +1701,12 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, _InputIterator __last) { + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value || + is_same<_ItValueType, __node_value_type>::value), + "__assign_multi may only be called with the containers value type" + " or the nodes value type"); if (bucket_count() != 0) { __node_pointer __cache = __detach(); @@ -1459,7 +1732,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, __deallocate(__cache); } for (; __first != __last; ++__first) - __insert_multi(*__first); + __insert_multi(_NodeTypes::__get_value(*__first)); } template <class _Tp, class _Hash, class _Equal, class _Alloc> @@ -1685,31 +1958,24 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( return __node_insert_multi(__cp); } -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(const value_type& __x) -{ - return __insert_unique_value(__x); -} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> -template <class _ValueTp> +template <class _Key, class ..._Args> _LIBCPP_INLINE_VISIBILITY pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique_value(_ValueTp&& __x) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) #else template <class _Tp, class _Hash, class _Equal, class _Alloc> +template <class _Key, class _Args> _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) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args& __args) #endif { -#if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) - typedef const value_type& _ValueTp; -#endif - size_t __hash = hash_function()(__x); + + size_t __hash = hash_function()(__k); size_type __bc = bucket_count(); bool __inserted = false; __node_pointer __nd; @@ -1724,13 +1990,17 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique_value(const value_type __constrain_hash(__nd->__hash_, __bc) == __chash; __nd = __nd->__next_) { - if (key_eq()(__nd->__value_, __x)) + if (key_eq()(__nd->__value_, __k)) goto __done; } } } { - __node_holder __h = __construct_node(_VSTD::forward<_ValueTp>(__x), __hash); +#ifndef _LIBCPP_CXX03_LANG + __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...); +#else + __node_holder __h = __construct_node_hash(__hash, __args); +#endif if (size()+1 > __bc * max_load_factor() || __bc == 0) { rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc), @@ -1742,7 +2012,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique_value(const value_type __node_pointer __pn = __bucket_list_[__chash]; if (__pn == nullptr) { - __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + __pn = static_cast<__node_pointer>(static_cast<__void_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()))); __h->__next_ = __pn->__next_; __pn->__next_ = __h.get(); // fix up __bucket_list_ @@ -1768,13 +2038,12 @@ __done: #endif } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> template <class... _Args> pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique(_Args&&... __args) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); pair<iterator, bool> __r = __node_insert_unique(__h.get()); @@ -1811,64 +2080,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( return __r; } -#endif // _LIBCPP_HAS_NO_VARIADICS +#else // _LIBCPP_CXX03_LANG 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) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x)); - pair<iterator, bool> __r = __node_insert_unique(__h.get()); - if (__r.second) - __h.release(); - return __r; -} - -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - -template <class _Tp, class _Hash, class _Equal, class _Alloc> -template <class _Pp> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(_Pp&& __x) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x)); - iterator __r = __node_insert_multi(__h.get()); - __h.release(); - return __r; -} - -template <class _Tp, class _Hash, class _Equal, class _Alloc> -template <class _Pp> -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, - _Pp&& __x) -{ -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container::insert(const_iterator, rvalue) called with an iterator not" - " referring to this unordered container"); -#endif - __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x)); - iterator __r = __node_insert_multi(__p, __h.get()); - __h.release(); - return __r; -} - -#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES - -template <class _Tp, class _Hash, class _Equal, class _Alloc> -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const value_type& __x) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const __container_value_type& __x) { __node_holder __h = __construct_node(__x); iterator __r = __node_insert_multi(__h.get()); @@ -1879,7 +2095,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const value_type& __x) template <class _Tp, class _Hash, class _Equal, class _Alloc> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, - const value_type& __x) + const __container_value_type& __x) { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, @@ -1892,7 +2108,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, return __r; } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> void @@ -1986,10 +2202,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) if (__nd != nullptr) { for (__nd = __nd->__next_; __nd != nullptr && - __constrain_hash(__nd->__hash_, __bc) == __chash; + (__nd->__hash_ == __hash + || __constrain_hash(__nd->__hash_, __bc) == __chash); __nd = __nd->__next_) { - if (key_eq()(__nd->__value_, __k)) + if ((__nd->__hash_ == __hash) && key_eq()(__nd->__value_, __k)) #if _LIBCPP_DEBUG_LEVEL >= 2 return iterator(__nd, this); #else @@ -2015,10 +2232,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const if (__nd != nullptr) { for (__nd = __nd->__next_; __nd != nullptr && - __constrain_hash(__nd->__hash_, __bc) == __chash; + (__hash == __nd->__hash_ || __constrain_hash(__nd->__hash_, __bc) == __chash); __nd = __nd->__next_) { - if (key_eq()(__nd->__value_, __k)) + if ((__nd->__hash_ == __hash) && key_eq()(__nd->__value_, __k)) #if _LIBCPP_DEBUG_LEVEL >= 2 return const_iterator(__nd, this); #else @@ -2031,70 +2248,74 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const return end(); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> template <class ..._Args> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args) { + static_assert(!__is_hash_value_type<_Args...>::value, + "Construct cannot be called with a hash value type"); __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); __h.get_deleter().__value_constructed = true; __h->__hash_ = hash_function()(__h->__value_); __h->__next_ = nullptr; return __h; } -#endif // _LIBCPP_HAS_NO_VARIADICS - template <class _Tp, class _Hash, class _Equal, class _Alloc> +template <class _First, class ..._Rest> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(value_type&& __v, - size_t __hash) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash( + size_t __hash, _First&& __f, _Rest&& ...__rest) { + static_assert(!__is_hash_value_type<_First, _Rest...>::value, + "Construct cannot be called with a hash value type"); __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), + _VSTD::forward<_First>(__f), + _VSTD::forward<_Rest>(__rest)...); __h.get_deleter().__value_constructed = true; __h->__hash_ = __hash; __h->__next_ = nullptr; return __h; } -#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#else // _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const __container_value_type& __v) { __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); __h.get_deleter().__value_constructed = true; __h->__hash_ = hash_function()(__h->__value_); __h->__next_ = nullptr; return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - template <class _Tp, class _Hash, class _Equal, class _Alloc> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v, - size_t __hash) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(size_t __hash, + const __container_value_type& __v) { __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); __h.get_deleter().__value_constructed = true; __h->__hash_ = __hash; __h->__next_ = nullptr; return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 } +#endif // _LIBCPP_CXX03_LANG + template <class _Tp, class _Hash, class _Equal, class _Alloc> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) diff --git a/include/__mutex_base b/include/__mutex_base index b019b4760d186..38a76ac6f2ec9 100644 --- a/include/__mutex_base +++ b/include/__mutex_base @@ -14,9 +14,7 @@ #include <__config> #include <chrono> #include <system_error> -#ifndef _LIBCPP_HAS_NO_THREADS -#include <pthread.h> -#endif +#include <__threading_support> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -26,29 +24,41 @@ _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_HAS_NO_THREADS -class _LIBCPP_TYPE_VIS mutex +#ifndef _LIBCPP_THREAD_SAFETY_ANNOTATION +# ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS +# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x)) +# else +# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) +# endif +#endif // _LIBCPP_THREAD_SAFETY_ANNOTATION + +class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex { - pthread_mutex_t __m_; +#ifndef _LIBCPP_HAS_NO_CONSTEXPR + __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER; +#else + __libcpp_mutex_t __m_; +#endif public: _LIBCPP_INLINE_VISIBILITY #ifndef _LIBCPP_HAS_NO_CONSTEXPR - constexpr mutex() _NOEXCEPT : __m_(PTHREAD_MUTEX_INITIALIZER) {} + constexpr mutex() _NOEXCEPT _LIBCPP_DEFAULT #else - mutex() _NOEXCEPT {__m_ = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;} + mutex() _NOEXCEPT {__m_ = (__libcpp_mutex_t)_LIBCPP_MUTEX_INITIALIZER;} #endif - ~mutex(); + ~mutex(); private: mutex(const mutex&);// = delete; mutex& operator=(const mutex&);// = delete; public: - void lock(); - bool try_lock() _NOEXCEPT; - void unlock() _NOEXCEPT; + void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); + bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true)); + void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()); - typedef pthread_mutex_t* native_handle_type; + typedef __libcpp_mutex_t* native_handle_type; _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;} }; @@ -70,8 +80,21 @@ constexpr adopt_lock_t adopt_lock = adopt_lock_t(); #endif + +// Forward declare lock_guard as a variadic template even in C++03 to keep +// the mangling consistent between dialects. +#if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD) +template <class ..._Mutexes> +class _LIBCPP_TYPE_VIS_ONLY lock_guard; +#endif + template <class _Mutex> -class _LIBCPP_TYPE_VIS_ONLY lock_guard +class _LIBCPP_TYPE_VIS_ONLY _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) +#if !defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD) +lock_guard +#else +lock_guard<_Mutex> +#endif { public: typedef _Mutex mutex_type; @@ -81,17 +104,17 @@ private: public: _LIBCPP_INLINE_VISIBILITY - explicit lock_guard(mutex_type& __m) + explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m)) : __m_(__m) {__m_.lock();} _LIBCPP_INLINE_VISIBILITY - lock_guard(mutex_type& __m, adopt_lock_t) + lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m)) : __m_(__m) {} _LIBCPP_INLINE_VISIBILITY - ~lock_guard() {__m_.unlock();} + ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();} private: - lock_guard(lock_guard const&);// = delete; - lock_guard& operator=(lock_guard const&);// = delete; + lock_guard(lock_guard const&) _LIBCPP_EQUAL_DELETE; + lock_guard& operator=(lock_guard const&) _LIBCPP_EQUAL_DELETE; }; template <class _Mutex> @@ -109,24 +132,24 @@ public: unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {} _LIBCPP_INLINE_VISIBILITY explicit unique_lock(mutex_type& __m) - : __m_(&__m), __owns_(true) {__m_->lock();} + : __m_(_VSTD::addressof(__m)), __owns_(true) {__m_->lock();} _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT - : __m_(&__m), __owns_(false) {} + : __m_(_VSTD::addressof(__m)), __owns_(false) {} _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, try_to_lock_t) - : __m_(&__m), __owns_(__m.try_lock()) {} + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock()) {} _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, adopt_lock_t) - : __m_(&__m), __owns_(true) {} + : __m_(_VSTD::addressof(__m)), __owns_(true) {} template <class _Clock, class _Duration> _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t) - : __m_(&__m), __owns_(__m.try_lock_until(__t)) {} + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_until(__t)) {} template <class _Rep, class _Period> _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d) - : __m_(&__m), __owns_(__m.try_lock_for(__d)) {} + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_for(__d)) {} _LIBCPP_INLINE_VISIBILITY ~unique_lock() { @@ -268,13 +291,18 @@ _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status) class _LIBCPP_TYPE_VIS condition_variable { - pthread_cond_t __cv_; +#ifndef _LIBCPP_HAS_NO_CONSTEXPR + __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER; +#else + __libcpp_condvar_t __cv_; +#endif + public: _LIBCPP_INLINE_VISIBILITY #ifndef _LIBCPP_HAS_NO_CONSTEXPR - constexpr condition_variable() : __cv_(PTHREAD_COND_INITIALIZER) {} + constexpr condition_variable() _NOEXCEPT _LIBCPP_DEFAULT #else - condition_variable() {__cv_ = (pthread_cond_t)PTHREAD_COND_INITIALIZER;} + condition_variable() _NOEXCEPT {__cv_ = (__libcpp_condvar_t)_LIBCPP_CONDVAR_INITIALIZER;} #endif ~condition_variable(); @@ -313,7 +341,7 @@ public: const chrono::duration<_Rep, _Period>& __d, _Predicate __pred); - typedef pthread_cond_t* native_handle_type; + typedef __libcpp_condvar_t* native_handle_type; _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;} private: diff --git a/include/__threading_support b/include/__threading_support new file mode 100644 index 0000000000000..c9a4ea9d0947e --- /dev/null +++ b/include/__threading_support @@ -0,0 +1,205 @@ +// -*- 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_THREADING_SUPPORT +#define _LIBCPP_THREADING_SUPPORT + +#include <__config> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +#ifndef _LIBCPP_HAS_NO_THREADS + +#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +#include <pthread.h> +#include <sched.h> +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) + +// Mutex +#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +typedef pthread_mutex_t __libcpp_mutex_t; + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m) +{ + pthread_mutexattr_t attr; + int __ec = pthread_mutexattr_init(&attr); + if (__ec) return __ec; + __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + if (__ec) + { + pthread_mutexattr_destroy(&attr); + return __ec; + } + __ec = pthread_mutex_init(__m, &attr); + if (__ec) + { + pthread_mutexattr_destroy(&attr); + return __ec; + } + __ec = pthread_mutexattr_destroy(&attr); + if (__ec) + { + pthread_mutex_destroy(__m); + return __ec; + } + return 0; +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_mutex_lock(__libcpp_mutex_t* __m) +{ + return pthread_mutex_lock(__m); +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_mutex_trylock(__libcpp_mutex_t* __m) +{ + return pthread_mutex_trylock(__m); +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_mutex_unlock(__libcpp_mutex_t* __m) +{ + return pthread_mutex_unlock(__m); +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_mutex_destroy(__libcpp_mutex_t* __m) +{ + return pthread_mutex_destroy(__m); +} + +// Condition variable +#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER +typedef pthread_cond_t __libcpp_condvar_t; + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_condvar_signal(__libcpp_condvar_t* __cv) +{ + return pthread_cond_signal(__cv); +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv) +{ + return pthread_cond_broadcast(__cv); +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m) +{ + return pthread_cond_wait(__cv, __m); +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts) +{ + return pthread_cond_timedwait(__cv, __m, __ts); +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv) +{ + return pthread_cond_destroy(__cv); +} + +// Thread id +typedef pthread_t __libcpp_thread_id; + +// Returns non-zero if the thread ids are equal, otherwise 0 +inline _LIBCPP_ALWAYS_INLINE +bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) +{ + return pthread_equal(t1, t2) != 0; +} + +// Returns non-zero if t1 < t2, otherwise 0 +inline _LIBCPP_ALWAYS_INLINE +bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) +{ + return t1 < t2; +} + +// Thread +typedef pthread_t __libcpp_thread_t; + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg) +{ + return pthread_create(__t, 0, __func, __arg); +} + +inline _LIBCPP_ALWAYS_INLINE +__libcpp_thread_id __libcpp_thread_get_current_id() +{ + return pthread_self(); +} + +inline _LIBCPP_ALWAYS_INLINE +__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t) +{ + return *__t; +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_thread_join(__libcpp_thread_t* __t) +{ + return pthread_join(*__t, 0); +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_thread_detach(__libcpp_thread_t* __t) +{ + return pthread_detach(*__t); +} + +inline _LIBCPP_ALWAYS_INLINE +void __libcpp_thread_yield() +{ + sched_yield(); +} + +// Thread local storage +typedef pthread_key_t __libcpp_tl_key; + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_tl_create(__libcpp_tl_key* __key, void (*__at_exit)(void*)) +{ + return pthread_key_create(__key, __at_exit); +} + +inline _LIBCPP_ALWAYS_INLINE +void* __libcpp_tl_get(__libcpp_tl_key __key) +{ + return pthread_getspecific(__key); +} + +inline _LIBCPP_ALWAYS_INLINE +void __libcpp_tl_set(__libcpp_tl_key __key, void* __p) +{ + pthread_setspecific(__key, __p); +} + +#else // !_LIBCPP_HAS_THREAD_API_PTHREAD + #error "No thread API selected." +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_HAS_NO_THREADS + +#endif // _LIBCPP_THREADING_SUPPORT diff --git a/include/__tree b/include/__tree index 94565bc3f74ce..bfcec78d4c9b1 100644 --- a/include/__tree +++ b/include/__tree @@ -29,6 +29,22 @@ template <class _Tp, class _NodePtr, class _DiffType> template <class _Tp, class _ConstNodePtr, class _DiffType> class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator; +template <class _Pointer> class __tree_end_node; +template <class _VoidPtr> class __tree_node_base; +template <class _Tp, class _VoidPtr> class __tree_node; + +#ifndef _LIBCPP_CXX03_LANG +template <class _Key, class _Value> +union __value_type; +#else +template <class _Key, class _Value> +struct __value_type; +#endif + +template <class _Allocator> class __map_node_destructor; +template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_iterator; +template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator; + /* _NodePtr algorithms @@ -149,21 +165,36 @@ __tree_next(_NodePtr __x) _NOEXCEPT if (__x->__right_ != nullptr) return __tree_min(__x->__right_); while (!__tree_is_left_child(__x)) - __x = __x->__parent_; - return __x->__parent_; + __x = __x->__parent_unsafe(); + return __x->__parent_unsafe(); +} + +template <class _EndNodePtr, class _NodePtr> +inline _LIBCPP_INLINE_VISIBILITY +_EndNodePtr +__tree_next_iter(_NodePtr __x) _NOEXCEPT +{ + if (__x->__right_ != nullptr) + return static_cast<_EndNodePtr>(__tree_min(__x->__right_)); + while (!__tree_is_left_child(__x)) + __x = __x->__parent_unsafe(); + return static_cast<_EndNodePtr>(__x->__parent_); } // Returns: pointer to the previous in-order node before __x. // Precondition: __x != nullptr. -template <class _NodePtr> +// Note: __x may be the end node. +template <class _NodePtr, class _EndNodePtr> +inline _LIBCPP_INLINE_VISIBILITY _NodePtr -__tree_prev(_NodePtr __x) _NOEXCEPT +__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT { if (__x->__left_ != nullptr) return __tree_max(__x->__left_); - while (__tree_is_left_child(__x)) - __x = __x->__parent_; - return __x->__parent_; + _NodePtr __xx = static_cast<_NodePtr>(__x); + while (__tree_is_left_child(__xx)) + __xx = __xx->__parent_unsafe(); + return __xx->__parent_unsafe(); } // Returns: pointer to a node which has no children @@ -199,14 +230,14 @@ __tree_left_rotate(_NodePtr __x) _NOEXCEPT _NodePtr __y = __x->__right_; __x->__right_ = __y->__left_; if (__x->__right_ != nullptr) - __x->__right_->__parent_ = __x; + __x->__right_->__set_parent(__x); __y->__parent_ = __x->__parent_; if (__tree_is_left_child(__x)) __x->__parent_->__left_ = __y; else - __x->__parent_->__right_ = __y; + __x->__parent_unsafe()->__right_ = __y; __y->__left_ = __x; - __x->__parent_ = __y; + __x->__set_parent(__y); } // Effects: Makes __x->__left_ the subtree root with __x as its right child @@ -219,14 +250,14 @@ __tree_right_rotate(_NodePtr __x) _NOEXCEPT _NodePtr __y = __x->__left_; __x->__left_ = __y->__right_; if (__x->__left_ != nullptr) - __x->__left_->__parent_ = __x; + __x->__left_->__set_parent(__x); __y->__parent_ = __x->__parent_; if (__tree_is_left_child(__x)) __x->__parent_->__left_ = __y; else - __x->__parent_->__right_ = __y; + __x->__parent_unsafe()->__right_ = __y; __y->__right_ = __x; - __x->__parent_ = __y; + __x->__set_parent(__y); } // Effects: Rebalances __root after attaching __x to a leaf. @@ -242,17 +273,17 @@ void __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT { __x->__is_black_ = __x == __root; - while (__x != __root && !__x->__parent_->__is_black_) + while (__x != __root && !__x->__parent_unsafe()->__is_black_) { // __x->__parent_ != __root because __x->__parent_->__is_black == false - if (__tree_is_left_child(__x->__parent_)) + if (__tree_is_left_child(__x->__parent_unsafe())) { - _NodePtr __y = __x->__parent_->__parent_->__right_; + _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_; if (__y != nullptr && !__y->__is_black_) { - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = true; - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = __x == __root; __y->__is_black_ = true; } @@ -260,12 +291,12 @@ __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT { if (!__tree_is_left_child(__x)) { - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __tree_left_rotate(__x); } - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = true; - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = false; __tree_right_rotate(__x); break; @@ -273,12 +304,12 @@ __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT } else { - _NodePtr __y = __x->__parent_->__parent_->__left_; + _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_; if (__y != nullptr && !__y->__is_black_) { - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = true; - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = __x == __root; __y->__is_black_ = true; } @@ -286,12 +317,12 @@ __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT { if (__tree_is_left_child(__x)) { - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __tree_right_rotate(__x); } - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = true; - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = false; __tree_left_rotate(__x); break; @@ -328,13 +359,13 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT { __y->__parent_->__left_ = __x; if (__y != __root) - __w = __y->__parent_->__right_; + __w = __y->__parent_unsafe()->__right_; else __root = __x; // __w == nullptr } else { - __y->__parent_->__right_ = __x; + __y->__parent_unsafe()->__right_ = __x; // __y can't be root if it is a right child __w = __y->__parent_->__left_; } @@ -348,12 +379,12 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT if (__tree_is_left_child(__z)) __y->__parent_->__left_ = __y; else - __y->__parent_->__right_ = __y; + __y->__parent_unsafe()->__right_ = __y; __y->__left_ = __z->__left_; - __y->__left_->__parent_ = __y; + __y->__left_->__set_parent(__y); __y->__right_ = __z->__right_; if (__y->__right_ != nullptr) - __y->__right_->__parent_ = __y; + __y->__right_->__set_parent(__y); __y->__is_black_ = __z->__is_black_; if (__root == __z) __root = __y; @@ -390,8 +421,8 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT if (!__w->__is_black_) { __w->__is_black_ = true; - __w->__parent_->__is_black_ = false; - __tree_left_rotate(__w->__parent_); + __w->__parent_unsafe()->__is_black_ = false; + __tree_left_rotate(__w->__parent_unsafe()); // __x is still valid // reset __root only if necessary if (__root == __w->__left_) @@ -404,7 +435,7 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT (__w->__right_ == nullptr || __w->__right_->__is_black_)) { __w->__is_black_ = false; - __x = __w->__parent_; + __x = __w->__parent_unsafe(); // __x can no longer be null if (__x == __root || !__x->__is_black_) { @@ -413,7 +444,7 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT } // reset sibling, and it still can't be null __w = __tree_is_left_child(__x) ? - __x->__parent_->__right_ : + __x->__parent_unsafe()->__right_ : __x->__parent_->__left_; // continue; } @@ -427,13 +458,13 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT __tree_right_rotate(__w); // __w is known not to be root, so root hasn't changed // reset sibling, and it still can't be null - __w = __w->__parent_; + __w = __w->__parent_unsafe(); } // __w has a right red child, left child may be null - __w->__is_black_ = __w->__parent_->__is_black_; - __w->__parent_->__is_black_ = true; + __w->__is_black_ = __w->__parent_unsafe()->__is_black_; + __w->__parent_unsafe()->__is_black_ = true; __w->__right_->__is_black_ = true; - __tree_left_rotate(__w->__parent_); + __tree_left_rotate(__w->__parent_unsafe()); break; } } @@ -442,8 +473,8 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT if (!__w->__is_black_) { __w->__is_black_ = true; - __w->__parent_->__is_black_ = false; - __tree_right_rotate(__w->__parent_); + __w->__parent_unsafe()->__is_black_ = false; + __tree_right_rotate(__w->__parent_unsafe()); // __x is still valid // reset __root only if necessary if (__root == __w->__right_) @@ -456,7 +487,7 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT (__w->__right_ == nullptr || __w->__right_->__is_black_)) { __w->__is_black_ = false; - __x = __w->__parent_; + __x = __w->__parent_unsafe(); // __x can no longer be null if (!__x->__is_black_ || __x == __root) { @@ -465,7 +496,7 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT } // reset sibling, and it still can't be null __w = __tree_is_left_child(__x) ? - __x->__parent_->__right_ : + __x->__parent_unsafe()->__right_ : __x->__parent_->__left_; // continue; } @@ -479,13 +510,13 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT __tree_left_rotate(__w); // __w is known not to be root, so root hasn't changed // reset sibling, and it still can't be null - __w = __w->__parent_; + __w = __w->__parent_unsafe(); } // __w has a left red child, right child may be null - __w->__is_black_ = __w->__parent_->__is_black_; - __w->__parent_->__is_black_ = true; + __w->__is_black_ = __w->__parent_unsafe()->__is_black_; + __w->__parent_unsafe()->__is_black_ = true; __w->__left_->__is_black_ = true; - __tree_right_rotate(__w->__parent_); + __tree_right_rotate(__w->__parent_unsafe()); break; } } @@ -494,41 +525,182 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT } } -template <class _Allocator> class __map_node_destructor; +// node traits + + +#ifndef _LIBCPP_CXX03_LANG +template <class _Tp> +struct __is_tree_value_type_imp : false_type {}; + +template <class _Key, class _Value> +struct __is_tree_value_type_imp<__value_type<_Key, _Value>> : true_type {}; + +template <class ..._Args> +struct __is_tree_value_type : false_type {}; + +template <class _One> +struct __is_tree_value_type<_One> : __is_tree_value_type_imp<typename __uncvref<_One>::type> {}; +#endif + +template <class _Tp> +struct __tree_key_value_types { + typedef _Tp key_type; + typedef _Tp __node_value_type; + typedef _Tp __container_value_type; + static const bool __is_map = false; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& __get_key(_Tp const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type const& __get_value(__node_value_type const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n); + } + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + static __container_value_type&& __move(__node_value_type& __v) { + return _VSTD::move(__v); + } +#endif +}; + +template <class _Key, class _Tp> +struct __tree_key_value_types<__value_type<_Key, _Tp> > { + typedef _Key key_type; + typedef _Tp mapped_type; + typedef __value_type<_Key, _Tp> __node_value_type; + typedef pair<const _Key, _Tp> __container_value_type; + typedef pair<_Key, _Tp> __nc_value_type; + typedef __container_value_type __map_value_type; + static const bool __is_map = true; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& + __get_key(__node_value_type const& __t) { + return __t.__cc.first; + } + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, + key_type const&>::type + __get_key(_Up& __t) { + return __t.first; + } + + _LIBCPP_INLINE_VISIBILITY + static __container_value_type const& + __get_value(__node_value_type const& __t) { + return __t.__cc; + } + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, + __container_value_type const&>::type + __get_value(_Up& __t) { + return __t; + } + + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n.__cc); + } + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + static __nc_value_type&& __move(__node_value_type& __v) { + return _VSTD::move(__v.__nc); + } +#endif +}; + +template <class _VoidPtr> +struct __tree_node_base_types { + typedef _VoidPtr __void_pointer; + + typedef __tree_node_base<__void_pointer> __node_base_type; + typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type + __node_base_pointer; + + typedef __tree_end_node<__node_base_pointer> __end_node_type; + typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type + __end_node_pointer; +#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) + typedef __end_node_pointer __parent_pointer; +#else + typedef typename conditional< + is_pointer<__end_node_pointer>::value, + __end_node_pointer, + __node_base_pointer>::type __parent_pointer; +#endif -template <class _Allocator> -class __tree_node_destructor -{ - typedef _Allocator allocator_type; - typedef allocator_traits<allocator_type> __alloc_traits; - typedef typename __alloc_traits::value_type::value_type value_type; -public: - typedef typename __alloc_traits::pointer pointer; private: + static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value), + "_VoidPtr does not point to unqualified void type"); +}; - allocator_type& __na_; +template <class _Tp, class _AllocPtr, class _KVTypes = __tree_key_value_types<_Tp>, + bool = _KVTypes::__is_map> +struct __tree_map_pointer_types {}; + +template <class _Tp, class _AllocPtr, class _KVTypes> +struct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { + typedef typename _KVTypes::__map_value_type _Mv; + typedef typename __rebind_pointer<_AllocPtr, _Mv>::type + __map_value_type_pointer; + typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type + __const_map_value_type_pointer; +}; - __tree_node_destructor& operator=(const __tree_node_destructor&); +template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type> +struct __tree_node_types; +template <class _NodePtr, class _Tp, class _VoidPtr> +struct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> > + : public __tree_node_base_types<_VoidPtr>, + __tree_key_value_types<_Tp>, + __tree_map_pointer_types<_Tp, _VoidPtr> +{ + typedef __tree_node_base_types<_VoidPtr> __base; + typedef __tree_key_value_types<_Tp> __key_base; + typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base; public: - bool __value_constructed; - - _LIBCPP_INLINE_VISIBILITY - explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT - : __na_(__na), - __value_constructed(__val) - {} - _LIBCPP_INLINE_VISIBILITY - void operator()(pointer __p) _NOEXCEPT - { - if (__value_constructed) - __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_)); - if (__p) - __alloc_traits::deallocate(__na_, __p, 1); - } + typedef typename pointer_traits<_NodePtr>::element_type __node_type; + typedef _NodePtr __node_pointer; + + typedef _Tp __node_value_type; + typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type + __node_value_type_pointer; + typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type + __const_node_value_type_pointer; +#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) + typedef typename __base::__end_node_pointer __iter_pointer; +#else + typedef typename conditional< + is_pointer<__node_pointer>::value, + typename __base::__end_node_pointer, + __node_pointer>::type __iter_pointer; +#endif +private: + static_assert(!is_const<__node_type>::value, + "_NodePtr should never be a pointer to const"); + static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type, + _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); +}; - template <class> friend class __map_node_destructor; +template <class _ValueTp, class _VoidPtr> +struct __make_tree_node_types { + typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type + _NodePtr; + typedef __tree_node_types<_NodePtr> type; }; // node @@ -546,26 +718,30 @@ public: template <class _VoidPtr> class __tree_node_base - : public __tree_end_node - < - typename __rebind_pointer<_VoidPtr, __tree_node_base<_VoidPtr> >::type - > + : public __tree_node_base_types<_VoidPtr>::__end_node_type { - __tree_node_base(const __tree_node_base&); - __tree_node_base& operator=(const __tree_node_base&); -public: - typedef typename __rebind_pointer<_VoidPtr, __tree_node_base>::type pointer; - typedef typename __rebind_pointer<_VoidPtr, const __tree_node_base>::type const_pointer; + typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes; - typedef __tree_end_node<pointer> base; +public: + typedef typename _NodeBaseTypes::__node_base_pointer pointer; + typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer; - pointer __right_; - pointer __parent_; + pointer __right_; + __parent_pointer __parent_; bool __is_black_; _LIBCPP_INLINE_VISIBILITY - __tree_node_base() _NOEXCEPT - : __right_(), __parent_(), __is_black_(false) {} + pointer __parent_unsafe() const { return static_cast<pointer>(__parent_);} + + _LIBCPP_INLINE_VISIBILITY + void __set_parent(pointer __p) { + __parent_ = static_cast<__parent_pointer>(__p); + } + +private: + ~__tree_node_base() _LIBCPP_EQUAL_DELETE; + __tree_node_base(__tree_node_base const&) _LIBCPP_EQUAL_DELETE; + __tree_node_base& operator=(__tree_node_base const&) _LIBCPP_EQUAL_DELETE; }; template <class _Tp, class _VoidPtr> @@ -573,41 +749,71 @@ class __tree_node : public __tree_node_base<_VoidPtr> { public: - typedef __tree_node_base<_VoidPtr> base; - typedef _Tp value_type; + typedef _Tp __node_value_type; - value_type __value_; + __node_value_type __value_; + +private: + ~__tree_node() _LIBCPP_EQUAL_DELETE; + __tree_node(__tree_node const&) _LIBCPP_EQUAL_DELETE; + __tree_node& operator=(__tree_node const&) _LIBCPP_EQUAL_DELETE; +}; + + +template <class _Allocator> +class __tree_node_destructor +{ + typedef _Allocator allocator_type; + typedef allocator_traits<allocator_type> __alloc_traits; + +public: + typedef typename __alloc_traits::pointer pointer; +private: + typedef __tree_node_types<pointer> _NodeTypes; + allocator_type& __na_; + + __tree_node_destructor& operator=(const __tree_node_destructor&); + +public: + bool __value_constructed; + + _LIBCPP_INLINE_VISIBILITY + explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT + : __na_(__na), + __value_constructed(__val) + {} -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) - template <class ..._Args> - _LIBCPP_INLINE_VISIBILITY - explicit __tree_node(_Args&& ...__args) - : __value_(_VSTD::forward<_Args>(__args)...) {} -#else // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) _LIBCPP_INLINE_VISIBILITY - explicit __tree_node(const value_type& __v) - : __value_(__v) {} -#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + void operator()(pointer __p) _NOEXCEPT + { + if (__value_constructed) + __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); + if (__p) + __alloc_traits::deallocate(__na_, __p, 1); + } + + template <class> friend class __map_node_destructor; }; -template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_iterator; -template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator; template <class _Tp, class _NodePtr, class _DiffType> class _LIBCPP_TYPE_VIS_ONLY __tree_iterator { - typedef _NodePtr __node_pointer; - typedef typename pointer_traits<__node_pointer>::element_type __node; + typedef __tree_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; + typedef typename _NodeTypes::__iter_pointer __iter_pointer; + typedef pointer_traits<__node_pointer> __pointer_traits; - __node_pointer __ptr_; + __iter_pointer __ptr_; - typedef pointer_traits<__node_pointer> __pointer_traits; public: - typedef bidirectional_iterator_tag iterator_category; - typedef _Tp value_type; - typedef _DiffType difference_type; - typedef value_type& reference; - typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer; + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _DiffType difference_type; + typedef value_type& reference; + typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT #if _LIBCPP_STD_VER > 11 @@ -615,14 +821,15 @@ public: #endif {} - _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;} + _LIBCPP_INLINE_VISIBILITY reference operator*() const + {return __get_np()->__value_;} _LIBCPP_INLINE_VISIBILITY pointer operator->() const - {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);} + {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);} _LIBCPP_INLINE_VISIBILITY __tree_iterator& operator++() { - __ptr_ = static_cast<__node_pointer>( - __tree_next(static_cast<typename __node::base::pointer>(__ptr_))); + __ptr_ = static_cast<__iter_pointer>( + __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); return *this; } _LIBCPP_INLINE_VISIBILITY @@ -631,8 +838,8 @@ public: _LIBCPP_INLINE_VISIBILITY __tree_iterator& operator--() { - __ptr_ = static_cast<__node_pointer>( - __tree_prev(static_cast<typename __node::base::pointer>(__ptr_))); + __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>( + static_cast<__end_node_pointer>(__ptr_))); return *this; } _LIBCPP_INLINE_VISIBILITY @@ -649,6 +856,10 @@ public: private: _LIBCPP_INLINE_VISIBILITY explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} + _LIBCPP_INLINE_VISIBILITY + explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {} + _LIBCPP_INLINE_VISIBILITY + __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } template <class, class, class> friend class __tree; template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator; template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_iterator; @@ -658,21 +869,24 @@ private: template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset; }; -template <class _Tp, class _ConstNodePtr, class _DiffType> +template <class _Tp, class _NodePtr, class _DiffType> class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator { - typedef _ConstNodePtr __node_pointer; - typedef typename pointer_traits<__node_pointer>::element_type __node; + typedef __tree_node_types<_NodePtr> _NodeTypes; + typedef typename _NodeTypes::__node_pointer __node_pointer; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; + typedef typename _NodeTypes::__iter_pointer __iter_pointer; + typedef pointer_traits<__node_pointer> __pointer_traits; - __node_pointer __ptr_; + __iter_pointer __ptr_; - typedef pointer_traits<__node_pointer> __pointer_traits; public: - typedef bidirectional_iterator_tag iterator_category; - typedef _Tp value_type; - typedef _DiffType difference_type; - typedef const value_type& reference; - typedef typename __rebind_pointer<__node_pointer, const value_type>::type pointer; + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _DiffType difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT #if _LIBCPP_STD_VER > 11 @@ -681,26 +895,22 @@ public: {} private: - typedef typename remove_const<__node>::type __non_const_node; - typedef typename __rebind_pointer<__node_pointer, __non_const_node>::type - __non_const_node_pointer; - typedef __tree_iterator<value_type, __non_const_node_pointer, difference_type> - __non_const_iterator; + typedef __tree_iterator<value_type, __node_pointer, difference_type> + __non_const_iterator; public: _LIBCPP_INLINE_VISIBILITY __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {} - _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;} + _LIBCPP_INLINE_VISIBILITY reference operator*() const + {return __get_np()->__value_;} _LIBCPP_INLINE_VISIBILITY pointer operator->() const - {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);} + {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);} _LIBCPP_INLINE_VISIBILITY __tree_const_iterator& operator++() { - typedef typename __rebind_pointer<__node_pointer, typename __node::base>::type - __node_base_pointer; - __ptr_ = static_cast<__node_pointer>( - __tree_next(static_cast<__node_base_pointer>(__ptr_))); + __ptr_ = static_cast<__iter_pointer>( + __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); return *this; } @@ -710,10 +920,8 @@ public: _LIBCPP_INLINE_VISIBILITY __tree_const_iterator& operator--() { - typedef typename __rebind_pointer<__node_pointer, typename __node::base>::type - __node_base_pointer; - __ptr_ = static_cast<__node_pointer>( - __tree_prev(static_cast<__node_base_pointer>(__ptr_))); + __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>( + static_cast<__end_node_pointer>(__ptr_))); return *this; } @@ -732,12 +940,19 @@ private: _LIBCPP_INLINE_VISIBILITY explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} + _LIBCPP_INLINE_VISIBILITY + explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT + : __ptr_(__p) {} + _LIBCPP_INLINE_VISIBILITY + __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } + template <class, class, class> friend class __tree; template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map; template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap; template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set; template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset; template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator; + }; template <class _Tp, class _Compare, class _Allocator> @@ -747,48 +962,73 @@ public: typedef _Tp value_type; typedef _Compare value_compare; typedef _Allocator allocator_type; + +private: typedef allocator_traits<allocator_type> __alloc_traits; + typedef typename __make_tree_node_types<value_type, + typename __alloc_traits::void_pointer>::type + _NodeTypes; + typedef typename _NodeTypes::key_type key_type; +public: + typedef typename _NodeTypes::__node_value_type __node_value_type; + typedef typename _NodeTypes::__container_value_type __container_value_type; + typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; typedef typename __alloc_traits::size_type size_type; typedef typename __alloc_traits::difference_type difference_type; - typedef typename __alloc_traits::void_pointer __void_pointer; +public: + typedef typename _NodeTypes::__void_pointer __void_pointer; + + typedef typename _NodeTypes::__node_type __node; + typedef typename _NodeTypes::__node_pointer __node_pointer; + + typedef typename _NodeTypes::__node_base_type __node_base; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + + typedef typename _NodeTypes::__end_node_type __end_node_t; + typedef typename _NodeTypes::__end_node_pointer __end_node_ptr; + + typedef typename _NodeTypes::__parent_pointer __parent_pointer; + typedef typename _NodeTypes::__iter_pointer __iter_pointer; - typedef __tree_node<value_type, __void_pointer> __node; - typedef __tree_node_base<__void_pointer> __node_base; 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; - typedef typename __node_base::pointer __node_base_pointer; - typedef typename __node_base::pointer __node_base_const_pointer; + typedef allocator_traits<__node_allocator> __node_traits; + private: - typedef typename __node_base::base __end_node_t; - typedef typename __rebind_pointer<__node_pointer, __end_node_t>::type - __end_node_ptr; - typedef __end_node_ptr __end_node_const_ptr; + // check for sane allocator pointer rebinding semantics. Rebinding the + // allocator for a new pointer type should be exactly the same as rebinding + // the pointer using 'pointer_traits'. + static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); + typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type + __node_base_allocator; + typedef allocator_traits<__node_base_allocator> __node_base_traits; + static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); - __node_pointer __begin_node_; +private: + __iter_pointer __begin_node_; __compressed_pair<__end_node_t, __node_allocator> __pair1_; __compressed_pair<size_type, value_compare> __pair3_; public: _LIBCPP_INLINE_VISIBILITY - __node_pointer __end_node() _NOEXCEPT + __iter_pointer __end_node() _NOEXCEPT { - return static_cast<__node_pointer> - ( - pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first()) - ); + return static_cast<__iter_pointer>( + pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first()) + ); } _LIBCPP_INLINE_VISIBILITY - __node_const_pointer __end_node() const _NOEXCEPT + __iter_pointer __end_node() const _NOEXCEPT { - return static_cast<__node_const_pointer> - ( - pointer_traits<__end_node_const_ptr>::pointer_to(const_cast<__end_node_t&>(__pair1_.first())) - ); + return static_cast<__iter_pointer>( + pointer_traits<__end_node_ptr>::pointer_to( + const_cast<__end_node_t&>(__pair1_.first()) + ) + ); } _LIBCPP_INLINE_VISIBILITY __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();} @@ -797,9 +1037,9 @@ private: const __node_allocator& __node_alloc() const _NOEXCEPT {return __pair1_.second();} _LIBCPP_INLINE_VISIBILITY - __node_pointer& __begin_node() _NOEXCEPT {return __begin_node_;} + __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;} _LIBCPP_INLINE_VISIBILITY - const __node_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;} + const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;} public: _LIBCPP_INLINE_VISIBILITY allocator_type __alloc() const _NOEXCEPT @@ -816,12 +1056,14 @@ public: const value_compare& value_comp() const _NOEXCEPT {return __pair3_.second();} public: + _LIBCPP_INLINE_VISIBILITY - __node_pointer __root() _NOEXCEPT - {return static_cast<__node_pointer> (__end_node()->__left_);} - _LIBCPP_INLINE_VISIBILITY - __node_const_pointer __root() const _NOEXCEPT - {return static_cast<__node_const_pointer>(__end_node()->__left_);} + __node_pointer __root() const _NOEXCEPT + {return static_cast<__node_pointer>(__end_node()->__left_);} + + __node_base_pointer* __root_ptr() const _NOEXCEPT { + return _VSTD::addressof(__end_node()->__left_); + } typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator; typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator; @@ -877,45 +1119,195 @@ public: #endif ); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS + +#ifndef _LIBCPP_CXX03_LANG + template <class _Key, class ..._Args> + pair<iterator, bool> + __emplace_unique_key_args(_Key const&, _Args&&... __args); + template <class _Key, class ..._Args> + iterator + __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...); + template <class... _Args> - pair<iterator, bool> - __emplace_unique(_Args&&... __args); + pair<iterator, bool> __emplace_unique_impl(_Args&&... __args); + template <class... _Args> - iterator - __emplace_multi(_Args&&... __args); + iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args); template <class... _Args> - iterator - __emplace_hint_unique(const_iterator __p, _Args&&... __args); + iterator __emplace_multi(_Args&&... __args); + template <class... _Args> + iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique(_Pp&& __x) { + return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template <class _First, class _Second> + _LIBCPP_INLINE_VISIBILITY + typename enable_if< + __can_extract_map_key<_First, key_type, __container_value_type>::value, + pair<iterator, bool> + >::type __emplace_unique(_First&& __f, _Second&& __s) { + return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), + _VSTD::forward<_Second>(__s)); + } + + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique(_Args&&... __args) { + return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { + return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { + return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { + return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) { + return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template <class _First, class _Second> + _LIBCPP_INLINE_VISIBILITY + typename enable_if< + __can_extract_map_key<_First, key_type, __container_value_type>::value, iterator - __emplace_hint_multi(const_iterator __p, _Args&&... __args); -#endif // _LIBCPP_HAS_NO_VARIADICS + >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) { + return __emplace_hint_unique_key_args(__p, __f, + _VSTD::forward<_First>(__f), + _VSTD::forward<_Second>(__s)); + } - template <class _Vp> - pair<iterator, bool> __insert_unique(_Vp&& __v); - template <class _Vp> - iterator __insert_unique(const_iterator __p, _Vp&& __v); - template <class _Vp> - iterator __insert_multi(_Vp&& __v); - template <class _Vp> - iterator __insert_multi(const_iterator __p, _Vp&& __v); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) { + return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...); + } - pair<iterator, bool> __insert_unique(const value_type& __v); - iterator __insert_unique(const_iterator __p, const value_type& __v); - iterator __insert_multi(const value_type& __v); - iterator __insert_multi(const_iterator __p, const value_type& __v); + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) { + return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x)); + } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - pair<iterator, bool> __insert_unique( value_type&& __v); - iterator __insert_unique(const_iterator __p, value_type&& __v); - iterator __insert_multi( value_type&& __v); - iterator __insert_multi(const_iterator __p, value_type&& __v); + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) { + return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x)); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) { + return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x)); + } + +#else + template <class _Key, class _Args> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args& __args); + template <class _Key, class _Args> + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&); #endif + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __insert_unique(const __container_value_type& __v) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v); + } + + _LIBCPP_INLINE_VISIBILITY + iterator __insert_unique(const_iterator __p, const __container_value_type& __v) { + return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v); + } + +#ifdef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const __container_value_type& __v); + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const_iterator __p, const __container_value_type& __v); +#else + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __insert_unique(__container_value_type&& __v) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v)); + } + + _LIBCPP_INLINE_VISIBILITY + iterator __insert_unique(const_iterator __p, __container_value_type&& __v) { + return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v)); + } + + template <class _Vp, class = typename enable_if< + !is_same<typename __unconstref<_Vp>::type, + __container_value_type + >::value + >::type> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __insert_unique(_Vp&& __v) { + return __emplace_unique(_VSTD::forward<_Vp>(__v)); + } + + template <class _Vp, class = typename enable_if< + !is_same<typename __unconstref<_Vp>::type, + __container_value_type + >::value + >::type> + _LIBCPP_INLINE_VISIBILITY + iterator __insert_unique(const_iterator __p, _Vp&& __v) { + return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v)); + } + + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(__container_value_type&& __v) { + return __emplace_multi(_VSTD::move(__v)); + } + + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const_iterator __p, __container_value_type&& __v) { + return __emplace_hint_multi(__p, _VSTD::move(__v)); + } + + template <class _Vp> + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(_Vp&& __v) { + return __emplace_multi(_VSTD::forward<_Vp>(__v)); + } + + template <class _Vp> + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const_iterator __p, _Vp&& __v) { + return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v)); + } + +#endif // !_LIBCPP_CXX03_LANG + pair<iterator, bool> __node_insert_unique(__node_pointer __nd); iterator __node_insert_unique(const_iterator __p, __node_pointer __nd); @@ -930,7 +1322,7 @@ public: template <class _Key> size_type __erase_multi(const _Key& __k); - void __insert_node_at(__node_base_pointer __parent, + void __insert_node_at(__parent_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node); @@ -951,15 +1343,15 @@ public: template <class _Key> iterator __lower_bound(const _Key& __v, __node_pointer __root, - __node_pointer __result); + __iter_pointer __result); template <class _Key> _LIBCPP_INLINE_VISIBILITY const_iterator lower_bound(const _Key& __v) const {return __lower_bound(__v, __root(), __end_node());} template <class _Key> const_iterator __lower_bound(const _Key& __v, - __node_const_pointer __root, - __node_const_pointer __result) const; + __node_pointer __root, + __iter_pointer __result) const; template <class _Key> _LIBCPP_INLINE_VISIBILITY iterator upper_bound(const _Key& __v) @@ -967,15 +1359,15 @@ public: template <class _Key> iterator __upper_bound(const _Key& __v, __node_pointer __root, - __node_pointer __result); + __iter_pointer __result); template <class _Key> _LIBCPP_INLINE_VISIBILITY const_iterator upper_bound(const _Key& __v) const {return __upper_bound(__v, __root(), __end_node());} template <class _Key> const_iterator __upper_bound(const _Key& __v, - __node_const_pointer __root, - __node_const_pointer __result) const; + __node_pointer __root, + __iter_pointer __result) const; template <class _Key> pair<iterator, iterator> __equal_range_unique(const _Key& __k); @@ -995,26 +1387,27 @@ public: __node_holder remove(const_iterator __p) _NOEXCEPT; private: - typename __node_base::pointer& - __find_leaf_low(typename __node_base::pointer& __parent, const value_type& __v); - typename __node_base::pointer& - __find_leaf_high(typename __node_base::pointer& __parent, const value_type& __v); - typename __node_base::pointer& + __node_base_pointer& + __find_leaf_low(__parent_pointer& __parent, const key_type& __v); + __node_base_pointer& + __find_leaf_high(__parent_pointer& __parent, const key_type& __v); + __node_base_pointer& __find_leaf(const_iterator __hint, - typename __node_base::pointer& __parent, const value_type& __v); + __parent_pointer& __parent, const key_type& __v); template <class _Key> - typename __node_base::pointer& - __find_equal(typename __node_base::pointer& __parent, const _Key& __v); + __node_base_pointer& + __find_equal(__parent_pointer& __parent, const _Key& __v); template <class _Key> - typename __node_base::pointer& - __find_equal(const_iterator __hint, typename __node_base::pointer& __parent, + __node_base_pointer& + __find_equal(const_iterator __hint, __parent_pointer& __parent, + __node_base_pointer& __dummy, const _Key& __v); -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) +#ifndef _LIBCPP_CXX03_LANG template <class ..._Args> - __node_holder __construct_node(_Args&& ...__args); -#else // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) - __node_holder __construct_node(const value_type& __v); + __node_holder __construct_node(_Args&& ...__args); +#else + __node_holder __construct_node(const __container_value_type& __v); #endif void destroy(__node_pointer __nd) _NOEXCEPT; @@ -1069,7 +1462,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp) template <class _Tp, class _Compare, class _Allocator> __tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a) - : __begin_node_(__node_pointer()), + : __begin_node_(__iter_pointer()), __pair1_(__node_allocator(__a)), __pair3_(0) { @@ -1079,7 +1472,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a) template <class _Tp, class _Compare, class _Allocator> __tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp, const allocator_type& __a) - : __begin_node_(__node_pointer()), + : __begin_node_(__iter_pointer()), __pair1_(__node_allocator(__a)), __pair3_(0, __comp) { @@ -1091,7 +1484,7 @@ template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::__node_pointer __tree<_Tp, _Compare, _Allocator>::__detach() { - __node_pointer __cache = __begin_node(); + __node_pointer __cache = static_cast<__node_pointer>(__begin_node()); __begin_node() = __end_node(); __end_node()->__left_->__parent_ = nullptr; __end_node()->__left_ = nullptr; @@ -1123,7 +1516,7 @@ __tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache) return static_cast<__node_pointer>(__tree_leaf(__cache->__right_)); } // __cache is right child - __cache->__parent_->__right_ = nullptr; + __cache->__parent_unsafe()->__right_ = nullptr; __cache = static_cast<__node_pointer>(__cache->__parent_); if (__cache->__left_ == nullptr) return __cache; @@ -1148,6 +1541,11 @@ template <class _InputIterator> void __tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last) { + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value), + "__assign_unique may only be called with the containers value type"); + if (size() != 0) { __node_pointer __cache = __detach(); @@ -1188,6 +1586,12 @@ template <class _InputIterator> void __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last) { + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value || + is_same<_ItValueType, __node_value_type>::value), + "__assign_multi may only be called with the containers value type" + " or the nodes value type"); if (size() != 0) { __node_pointer __cache = __detach(); @@ -1220,12 +1624,12 @@ __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _Input } } for (; __first != __last; ++__first) - __insert_multi(*__first); + __insert_multi(_NodeTypes::__get_value(*__first)); } template <class _Tp, class _Compare, class _Allocator> __tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t) - : __begin_node_(__node_pointer()), + : __begin_node_(__iter_pointer()), __pair1_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())), __pair3_(0, __t.value_comp()) { @@ -1247,7 +1651,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) __begin_node() = __end_node(); else { - __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node()); + __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); __t.__begin_node() = __t.__end_node(); __t.__end_node()->__left_ = nullptr; __t.size() = 0; @@ -1267,7 +1671,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __ { __begin_node() = __t.__begin_node(); __end_node()->__left_ = __t.__end_node()->__left_; - __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node()); + __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); size() = __t.size(); __t.__begin_node() = __t.__end_node(); __t.__end_node()->__left_ = nullptr; @@ -1295,7 +1699,7 @@ __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type) __begin_node() = __end_node(); else { - __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node()); + __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); __t.__begin_node() = __t.__end_node(); __t.__end_node()->__left_ = nullptr; __t.size() = 0; @@ -1344,7 +1748,7 @@ __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) } } while (__t.size() != 0) - __insert_multi(__e, _VSTD::move(__t.remove(__t.begin())->__value_)); + __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_)); } } @@ -1367,6 +1771,8 @@ __tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t) template <class _Tp, class _Compare, class _Allocator> __tree<_Tp, _Compare, _Allocator>::~__tree() { + static_assert((is_copy_constructible<value_compare>::value), + "Comparator must be copy-constructible."); destroy(__root()); } @@ -1379,7 +1785,7 @@ __tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT destroy(static_cast<__node_pointer>(__nd->__left_)); destroy(static_cast<__node_pointer>(__nd->__right_)); __node_allocator& __na = __node_alloc(); - __node_traits::destroy(__na, _VSTD::addressof(__nd->__value_)); + __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_)); __node_traits::deallocate(__na, __nd, 1); } } @@ -1403,11 +1809,11 @@ __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t) if (size() == 0) __begin_node() = __end_node(); else - __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node()); + __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); if (__t.size() == 0) __t.__begin_node() = __t.__end_node(); else - __t.__end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__t.__end_node()); + __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node()); } template <class _Tp, class _Compare, class _Allocator> @@ -1424,9 +1830,9 @@ __tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT // Set __parent to parent of null leaf // Return reference to null leaf template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& -__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node_base::pointer& __parent, - const value_type& __v) +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& +__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent, + const key_type& __v) { __node_pointer __nd = __root(); if (__nd != nullptr) @@ -1439,8 +1845,8 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node_base::pointer __nd = static_cast<__node_pointer>(__nd->__right_); else { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent->__right_; + __parent = static_cast<__parent_pointer>(__nd); + return __nd->__right_; } } else @@ -1449,13 +1855,13 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node_base::pointer __nd = static_cast<__node_pointer>(__nd->__left_); else { - __parent = static_cast<__node_base_pointer>(__nd); + __parent = static_cast<__parent_pointer>(__nd); return __parent->__left_; } } } } - __parent = static_cast<__node_base_pointer>(__end_node()); + __parent = static_cast<__parent_pointer>(__end_node()); return __parent->__left_; } @@ -1463,9 +1869,9 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node_base::pointer // Set __parent to parent of null leaf // Return reference to null leaf template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& -__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node_base::pointer& __parent, - const value_type& __v) +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& +__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent, + const key_type& __v) { __node_pointer __nd = __root(); if (__nd != nullptr) @@ -1478,7 +1884,7 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node_base::pointe __nd = static_cast<__node_pointer>(__nd->__left_); else { - __parent = static_cast<__node_base_pointer>(__nd); + __parent = static_cast<__parent_pointer>(__nd); return __parent->__left_; } } @@ -1488,13 +1894,13 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node_base::pointe __nd = static_cast<__node_pointer>(__nd->__right_); else { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent->__right_; + __parent = static_cast<__parent_pointer>(__nd); + return __nd->__right_; } } } } - __parent = static_cast<__node_base_pointer>(__end_node()); + __parent = static_cast<__parent_pointer>(__end_node()); return __parent->__left_; } @@ -1505,10 +1911,10 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node_base::pointe // Set __parent to parent of null leaf // Return reference to null leaf template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint, - typename __node_base::pointer& __parent, - const value_type& __v) + __parent_pointer& __parent, + const key_type& __v) { if (__hint == end() || !value_comp()(*__hint, __v)) // check before { @@ -1519,13 +1925,13 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint, // *prev(__hint) <= __v <= *__hint if (__hint.__ptr_->__left_ == nullptr) { - __parent = static_cast<__node_base_pointer>(__hint.__ptr_); + __parent = static_cast<__parent_pointer>(__hint.__ptr_); return __parent->__left_; } else { - __parent = static_cast<__node_base_pointer>(__prior.__ptr_); - return __parent->__right_; + __parent = static_cast<__parent_pointer>(__prior.__ptr_); + return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; } } // __v < *prev(__hint) @@ -1541,43 +1947,44 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint, // If __v exists, set parent to node of __v and return reference to node of __v template <class _Tp, class _Compare, class _Allocator> template <class _Key> -typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& -__tree<_Tp, _Compare, _Allocator>::__find_equal(typename __node_base::pointer& __parent, +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& +__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent, const _Key& __v) { __node_pointer __nd = __root(); + __node_base_pointer* __nd_ptr = __root_ptr(); if (__nd != nullptr) { while (true) { if (value_comp()(__v, __nd->__value_)) { - if (__nd->__left_ != nullptr) + if (__nd->__left_ != nullptr) { + __nd_ptr = _VSTD::addressof(__nd->__left_); __nd = static_cast<__node_pointer>(__nd->__left_); - else - { - __parent = static_cast<__node_base_pointer>(__nd); + } else { + __parent = static_cast<__parent_pointer>(__nd); return __parent->__left_; } } else if (value_comp()(__nd->__value_, __v)) { - if (__nd->__right_ != nullptr) + if (__nd->__right_ != nullptr) { + __nd_ptr = _VSTD::addressof(__nd->__right_); __nd = static_cast<__node_pointer>(__nd->__right_); - else - { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent->__right_; + } else { + __parent = static_cast<__parent_pointer>(__nd); + return __nd->__right_; } } else { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent; + __parent = static_cast<__parent_pointer>(__nd); + return *__nd_ptr; } } } - __parent = static_cast<__node_base_pointer>(__end_node()); + __parent = static_cast<__parent_pointer>(__end_node()); return __parent->__left_; } @@ -1590,9 +1997,10 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(typename __node_base::pointer& _ // If __v exists, set parent to node of __v and return reference to node of __v template <class _Tp, class _Compare, class _Allocator> template <class _Key> -typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, - typename __node_base::pointer& __parent, + __parent_pointer& __parent, + __node_base_pointer& __dummy, const _Key& __v) { if (__hint == end() || value_comp()(__v, *__hint)) // check before @@ -1604,13 +2012,13 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, // *prev(__hint) < __v < *__hint if (__hint.__ptr_->__left_ == nullptr) { - __parent = static_cast<__node_base_pointer>(__hint.__ptr_); + __parent = static_cast<__parent_pointer>(__hint.__ptr_); return __parent->__left_; } else { - __parent = static_cast<__node_base_pointer>(__prior.__ptr_); - return __parent->__right_; + __parent = static_cast<__parent_pointer>(__prior.__ptr_); + return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; } } // __v <= *prev(__hint) @@ -1623,14 +2031,14 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, if (__next == end() || value_comp()(__v, *__next)) { // *__hint < __v < *_VSTD::next(__hint) - if (__hint.__ptr_->__right_ == nullptr) + if (__hint.__get_np()->__right_ == nullptr) { - __parent = static_cast<__node_base_pointer>(__hint.__ptr_); - return __parent->__right_; + __parent = static_cast<__parent_pointer>(__hint.__ptr_); + return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_; } else { - __parent = static_cast<__node_base_pointer>(__next.__ptr_); + __parent = static_cast<__parent_pointer>(__next.__ptr_); return __parent->__left_; } } @@ -1638,48 +2046,115 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, return __find_equal(__parent, __v); } // else __v == *__hint - __parent = static_cast<__node_base_pointer>(__hint.__ptr_); - return __parent; + __parent = static_cast<__parent_pointer>(__hint.__ptr_); + __dummy = static_cast<__node_base_pointer>(__hint.__ptr_); + return __dummy; } template <class _Tp, class _Compare, class _Allocator> void -__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__node_base_pointer __parent, +__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__parent_pointer __parent, __node_base_pointer& __child, - __node_base_pointer __new_node) + __node_base_pointer __new_node) { __new_node->__left_ = nullptr; __new_node->__right_ = nullptr; __new_node->__parent_ = __parent; + // __new_node->__is_black_ is initialized in __tree_balance_after_insert __child = __new_node; if (__begin_node()->__left_ != nullptr) - __begin_node() = static_cast<__node_pointer>(__begin_node()->__left_); + __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_); __tree_balance_after_insert(__end_node()->__left_, __child); ++size(); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_CXX03_LANG +template <class _Tp, class _Compare, class _Allocator> +template <class _Key, class... _Args> +pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> +__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) +#else +template <class _Tp, class _Compare, class _Allocator> +template <class _Key, class _Args> +pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> +__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args& __args) +#endif +{ + __parent_pointer __parent; + __node_base_pointer& __child = __find_equal(__parent, __k); + __node_pointer __r = static_cast<__node_pointer>(__child); + bool __inserted = false; + if (__child == nullptr) + { +#ifndef _LIBCPP_CXX03_LANG + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); +#else + __node_holder __h = __construct_node(__args); +#endif + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + __inserted = true; + } + return pair<iterator, bool>(iterator(__r), __inserted); +} + + +#ifndef _LIBCPP_CXX03_LANG +template <class _Tp, class _Compare, class _Allocator> +template <class _Key, class... _Args> +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args( + const_iterator __p, _Key const& __k, _Args&&... __args) +#else +template <class _Tp, class _Compare, class _Allocator> +template <class _Key, class _Args> +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args( + const_iterator __p, _Key const& __k, _Args& __args) +#endif +{ + __parent_pointer __parent; + __node_base_pointer __dummy; + __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k); + __node_pointer __r = static_cast<__node_pointer>(__child); + if (__child == nullptr) + { +#ifndef _LIBCPP_CXX03_LANG + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); +#else + __node_holder __h = __construct_node(__args); +#endif + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + } + return iterator(__r); +} + + +#ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Compare, class _Allocator> template <class ..._Args> typename __tree<_Tp, _Compare, _Allocator>::__node_holder __tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args) { + static_assert(!__is_tree_value_type<_Args...>::value, + "Cannot construct from __value_type"); __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); __h.get_deleter().__value_constructed = true; return __h; } + template <class _Tp, class _Compare, class _Allocator> template <class... _Args> pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> -__tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args) +__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - __node_base_pointer __parent; + __parent_pointer __parent; __node_base_pointer& __child = __find_equal(__parent, __h->__value_); __node_pointer __r = static_cast<__node_pointer>(__child); bool __inserted = false; @@ -1695,11 +2170,12 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args) template <class _Tp, class _Compare, class _Allocator> template <class... _Args> typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique(const_iterator __p, _Args&&... __args) +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - __node_base_pointer __parent; - __node_base_pointer& __child = __find_equal(__p, __parent, __h->__value_); + __parent_pointer __parent; + __node_base_pointer __dummy; + __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_); __node_pointer __r = static_cast<__node_pointer>(__child); if (__child == nullptr) { @@ -1715,8 +2191,8 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_)); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); return iterator(static_cast<__node_pointer>(__h.release())); } @@ -1728,161 +2204,35 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, _Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_)); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); return iterator(static_cast<__node_pointer>(__h.release())); } -#endif // _LIBCPP_HAS_NO_VARIADICS -template <class _Tp, class _Compare, class _Allocator> -pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> -__tree<_Tp, _Compare, _Allocator>::__insert_unique(value_type&& __v) -{ - __node_holder __h = __construct_node(_VSTD::forward<value_type>(__v)); - pair<iterator, bool> __r = __node_insert_unique(__h.get()); - if (__r.second) - __h.release(); - return __r; -} - -template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, value_type&& __v) -{ - __node_holder __h = __construct_node(_VSTD::forward<value_type>(__v)); - iterator __r = __node_insert_unique(__p, __h.get()); - if (__r.__ptr_ == __h.get()) - __h.release(); - return __r; -} - -template <class _Tp, class _Compare, class _Allocator> -template <class _Vp> -pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> -__tree<_Tp, _Compare, _Allocator>::__insert_unique(_Vp&& __v) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v)); - pair<iterator, bool> __r = __node_insert_unique(__h.get()); - if (__r.second) - __h.release(); - return __r; -} - -template <class _Tp, class _Compare, class _Allocator> -template <class _Vp> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, _Vp&& __v) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v)); - iterator __r = __node_insert_unique(__p, __h.get()); - if (__r.__ptr_ == __h.get()) - __h.release(); - return __r; -} - -template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_multi(value_type&& __v) -{ - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf_high(__parent, __v); - __node_holder __h = __construct_node(_VSTD::forward<value_type>(__v)); - __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - return iterator(__h.release()); -} - -template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, value_type&& __v) -{ - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf(__p, __parent, __v); - __node_holder __h = __construct_node(_VSTD::forward<value_type>(__v)); - __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - return iterator(__h.release()); -} - -template <class _Tp, class _Compare, class _Allocator> -template <class _Vp> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_multi(_Vp&& __v) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v)); - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_); - __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - return iterator(__h.release()); -} - -template <class _Tp, class _Compare, class _Allocator> -template <class _Vp> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, _Vp&& __v) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v)); - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_); - __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - return iterator(__h.release()); -} - -#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#else // _LIBCPP_CXX03_LANG template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::__node_holder -__tree<_Tp, _Compare, _Allocator>::__construct_node(const value_type& __v) +__tree<_Tp, _Compare, _Allocator>::__construct_node(const __container_value_type& __v) { __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); __h.get_deleter().__value_constructed = true; return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - -template <class _Tp, class _Compare, class _Allocator> -pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> -__tree<_Tp, _Compare, _Allocator>::__insert_unique(const value_type& __v) -{ - __node_base_pointer __parent; - __node_base_pointer& __child = __find_equal(__parent, __v); - __node_pointer __r = static_cast<__node_pointer>(__child); - bool __inserted = false; - if (__child == nullptr) - { - __node_holder __h = __construct_node(__v); - __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - __r = __h.release(); - __inserted = true; - } - return pair<iterator, bool>(iterator(__r), __inserted); -} +#endif // _LIBCPP_CXX03_LANG +#ifdef _LIBCPP_CXX03_LANG template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, const value_type& __v) +__tree<_Tp, _Compare, _Allocator>::__insert_multi(const __container_value_type& __v) { - __node_base_pointer __parent; - __node_base_pointer& __child = __find_equal(__p, __parent, __v); - __node_pointer __r = static_cast<__node_pointer>(__child); - if (__child == nullptr) - { - __node_holder __h = __construct_node(__v); - __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - __r = __h.release(); - } - return iterator(__r); -} - -template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_multi(const value_type& __v) -{ - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf_high(__parent, __v); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__v)); __node_holder __h = __construct_node(__v); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); return iterator(__h.release()); @@ -1890,20 +2240,21 @@ __tree<_Tp, _Compare, _Allocator>::__insert_multi(const value_type& __v) template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const value_type& __v) +__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const __container_value_type& __v) { - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf(__p, __parent, __v); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__v)); __node_holder __h = __construct_node(__v); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); return iterator(__h.release()); } +#endif template <class _Tp, class _Compare, class _Allocator> pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> __tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd) { - __node_base_pointer __parent; + __parent_pointer __parent; __node_base_pointer& __child = __find_equal(__parent, __nd->__value_); __node_pointer __r = static_cast<__node_pointer>(__child); bool __inserted = false; @@ -1921,7 +2272,8 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p, __node_pointer __nd) { - __node_base_pointer __parent; + __parent_pointer __parent; + __node_base_pointer __dummy; __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_); __node_pointer __r = static_cast<__node_pointer>(__child); if (__child == nullptr) @@ -1936,8 +2288,8 @@ template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) { - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_)); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); return iterator(__nd); } @@ -1947,8 +2299,8 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, __node_pointer __nd) { - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_)); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); return iterator(__nd); } @@ -1957,16 +2309,17 @@ template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p) { - __node_pointer __np = __p.__ptr_; - iterator __r(__np); + __node_pointer __np = __p.__get_np(); + iterator __r(__p.__ptr_); ++__r; - if (__begin_node() == __np) + if (__begin_node() == __p.__ptr_) __begin_node() = __r.__ptr_; --size(); __node_allocator& __na = __node_alloc(); __tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__np)); - __node_traits::destroy(__na, const_cast<value_type*>(_VSTD::addressof(*__p))); + __node_traits::destroy(__na, _NodeTypes::__get_ptr( + const_cast<__node_value_type&>(*__p))); __node_traits::deallocate(__na, __np, 1); return __r; } @@ -2031,17 +2384,15 @@ template <class _Key> typename __tree<_Tp, _Compare, _Allocator>::size_type __tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const { - __node_const_pointer __result = __end_node(); - __node_const_pointer __rt = __root(); + __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { - __result = __rt; - __rt = static_cast<__node_const_pointer>(__rt->__left_); + __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) - __rt = static_cast<__node_const_pointer>(__rt->__right_); + __rt = static_cast<__node_pointer>(__rt->__right_); else return 1; } @@ -2053,21 +2404,21 @@ template <class _Key> typename __tree<_Tp, _Compare, _Allocator>::size_type __tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const { - __node_const_pointer __result = __end_node(); - __node_const_pointer __rt = __root(); + __iter_pointer __result = __end_node(); + __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { - __result = __rt; - __rt = static_cast<__node_const_pointer>(__rt->__left_); + __result = static_cast<__iter_pointer>(__rt); + __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) - __rt = static_cast<__node_const_pointer>(__rt->__right_); + __rt = static_cast<__node_pointer>(__rt->__right_); else return _VSTD::distance( - __lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt), - __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result) + __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), + __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result) ); } return 0; @@ -2078,13 +2429,13 @@ template <class _Key> typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, __node_pointer __root, - __node_pointer __result) + __iter_pointer __result) { while (__root != nullptr) { if (!value_comp()(__root->__value_, __v)) { - __result = __root; + __result = static_cast<__iter_pointer>(__root); __root = static_cast<__node_pointer>(__root->__left_); } else @@ -2097,18 +2448,18 @@ template <class _Tp, class _Compare, class _Allocator> template <class _Key> typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, - __node_const_pointer __root, - __node_const_pointer __result) const + __node_pointer __root, + __iter_pointer __result) const { while (__root != nullptr) { if (!value_comp()(__root->__value_, __v)) { - __result = __root; - __root = static_cast<__node_const_pointer>(__root->__left_); + __result = static_cast<__iter_pointer>(__root); + __root = static_cast<__node_pointer>(__root->__left_); } else - __root = static_cast<__node_const_pointer>(__root->__right_); + __root = static_cast<__node_pointer>(__root->__right_); } return const_iterator(__result); } @@ -2118,13 +2469,13 @@ template <class _Key> typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, __node_pointer __root, - __node_pointer __result) + __iter_pointer __result) { while (__root != nullptr) { if (value_comp()(__v, __root->__value_)) { - __result = __root; + __result = static_cast<__iter_pointer>(__root); __root = static_cast<__node_pointer>(__root->__left_); } else @@ -2137,18 +2488,18 @@ template <class _Tp, class _Compare, class _Allocator> template <class _Key> typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, - __node_const_pointer __root, - __node_const_pointer __result) const + __node_pointer __root, + __iter_pointer __result) const { while (__root != nullptr) { if (value_comp()(__v, __root->__value_)) { - __result = __root; - __root = static_cast<__node_const_pointer>(__root->__left_); + __result = static_cast<__iter_pointer>(__root); + __root = static_cast<__node_pointer>(__root->__left_); } else - __root = static_cast<__node_const_pointer>(__root->__right_); + __root = static_cast<__node_pointer>(__root->__right_); } return const_iterator(__result); } @@ -2160,13 +2511,13 @@ pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) { typedef pair<iterator, iterator> _Pp; - __node_pointer __result = __end_node(); + __iter_pointer __result = __end_node(); __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { - __result = __rt; + __result = static_cast<__iter_pointer>(__rt); __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) @@ -2175,7 +2526,7 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) return _Pp(iterator(__rt), iterator( __rt->__right_ != nullptr ? - static_cast<__node_pointer>(__tree_min(__rt->__right_)) + static_cast<__iter_pointer>(__tree_min(__rt->__right_)) : __result)); } return _Pp(iterator(__result), iterator(__result)); @@ -2188,22 +2539,22 @@ pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator, __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const { typedef pair<const_iterator, const_iterator> _Pp; - __node_const_pointer __result = __end_node(); - __node_const_pointer __rt = __root(); + __iter_pointer __result = __end_node(); + __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { - __result = __rt; - __rt = static_cast<__node_const_pointer>(__rt->__left_); + __result = static_cast<__iter_pointer>(__rt); + __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) - __rt = static_cast<__node_const_pointer>(__rt->__right_); + __rt = static_cast<__node_pointer>(__rt->__right_); else return _Pp(const_iterator(__rt), const_iterator( __rt->__right_ != nullptr ? - static_cast<__node_const_pointer>(__tree_min(__rt->__right_)) + static_cast<__iter_pointer>(__tree_min(__rt->__right_)) : __result)); } return _Pp(const_iterator(__result), const_iterator(__result)); @@ -2216,19 +2567,19 @@ pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) { typedef pair<iterator, iterator> _Pp; - __node_pointer __result = __end_node(); + __iter_pointer __result = __end_node(); __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { - __result = __rt; + __result = static_cast<__iter_pointer>(__rt); __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) __rt = static_cast<__node_pointer>(__rt->__right_); else - return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), __rt), + return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); } return _Pp(iterator(__result), iterator(__result)); @@ -2241,20 +2592,20 @@ pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator, __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const { typedef pair<const_iterator, const_iterator> _Pp; - __node_const_pointer __result = __end_node(); - __node_const_pointer __rt = __root(); + __iter_pointer __result = __end_node(); + __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { - __result = __rt; - __rt = static_cast<__node_const_pointer>(__rt->__left_); + __result = static_cast<__iter_pointer>(__rt); + __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) - __rt = static_cast<__node_const_pointer>(__rt->__right_); + __rt = static_cast<__node_pointer>(__rt->__right_); else - return _Pp(__lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt), - __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result)); + return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), + __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); } return _Pp(const_iterator(__result), const_iterator(__result)); } @@ -2263,13 +2614,13 @@ template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::__node_holder __tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT { - __node_pointer __np = __p.__ptr_; - if (__begin_node() == __np) + __node_pointer __np = __p.__get_np(); + if (__begin_node() == __p.__ptr_) { if (__np->__right_ != nullptr) - __begin_node() = static_cast<__node_pointer>(__np->__right_); + __begin_node() = static_cast<__iter_pointer>(__np->__right_); else - __begin_node() = static_cast<__node_pointer>(__np->__parent_); + __begin_node() = static_cast<__iter_pointer>(__np->__parent_); } --size(); __tree_remove(__end_node()->__left_, diff --git a/include/__tuple b/include/__tuple index 8c31759774ded..cc9fbbebc0963 100644 --- a/include/__tuple +++ b/include/__tuple @@ -68,6 +68,80 @@ template <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_li // tuple specializations #if !defined(_LIBCPP_HAS_NO_VARIADICS) + +template <size_t...> struct __tuple_indices {}; + +template <class _IdxType, _IdxType... _Values> +struct __integer_sequence { + template <template <class _OIdxType, _OIdxType...> class _ToIndexSeq, class _ToIndexType> + using __convert = _ToIndexSeq<_ToIndexType, _Values...>; + + template <size_t _Sp> + using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>; +}; + +#if !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) +namespace __detail { + +template<typename _Tp, size_t ..._Extra> struct __repeat; +template<typename _Tp, _Tp ..._Np, size_t ..._Extra> struct __repeat<__integer_sequence<_Tp, _Np...>, _Extra...> { + typedef __integer_sequence<_Tp, + _Np..., + sizeof...(_Np) + _Np..., + 2 * sizeof...(_Np) + _Np..., + 3 * sizeof...(_Np) + _Np..., + 4 * sizeof...(_Np) + _Np..., + 5 * sizeof...(_Np) + _Np..., + 6 * sizeof...(_Np) + _Np..., + 7 * sizeof...(_Np) + _Np..., + _Extra...> type; +}; + +template<size_t _Np> struct __parity; +template<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {}; + +template<> struct __make<0> { typedef __integer_sequence<size_t> type; }; +template<> struct __make<1> { typedef __integer_sequence<size_t, 0> type; }; +template<> struct __make<2> { typedef __integer_sequence<size_t, 0, 1> type; }; +template<> struct __make<3> { typedef __integer_sequence<size_t, 0, 1, 2> type; }; +template<> struct __make<4> { typedef __integer_sequence<size_t, 0, 1, 2, 3> type; }; +template<> struct __make<5> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4> type; }; +template<> struct __make<6> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; }; +template<> struct __make<7> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; }; + +template<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; }; +template<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; }; +template<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<5> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<6> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; + +} // namespace detail + +#endif // !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) + +#if __has_builtin(__make_integer_seq) +template <size_t _Ep, size_t _Sp> +using __make_indices_imp = + typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template + __to_tuple_indices<_Sp>; +#else +template <size_t _Ep, size_t _Sp> +using __make_indices_imp = + typename __detail::__make<_Ep - _Sp>::type::template __to_tuple_indices<_Sp>; + +#endif + +template <size_t _Ep, size_t _Sp = 0> +struct __make_tuple_indices +{ + static_assert(_Sp <= _Ep, "__make_tuple_indices input error"); + typedef __make_indices_imp<_Ep, _Sp> type; +}; + + template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple; template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {}; @@ -95,8 +169,6 @@ get(const tuple<_Tp...>&&) _NOEXCEPT; // 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> @@ -151,58 +223,49 @@ get(const array<_Tp, _Size>&&) _NOEXCEPT; #if !defined(_LIBCPP_HAS_NO_VARIADICS) -// __make_tuple_indices -template <size_t...> struct __tuple_indices {}; +// __tuple_types -template <size_t _Sp, class _IntTuple, size_t _Ep> -struct __make_indices_imp; +template <class ..._Tp> struct __tuple_types {}; -template <size_t _Sp, size_t ..._Indices, size_t _Ep> -struct __make_indices_imp<_Sp, __tuple_indices<_Indices...>, _Ep> -{ - typedef typename __make_indices_imp<_Sp+1, __tuple_indices<_Indices..., _Sp>, _Ep>::type type; -}; +#if !__has_builtin(__type_pack_element) -template <size_t _Ep, size_t ..._Indices> -struct __make_indices_imp<_Ep, __tuple_indices<_Indices...>, _Ep> -{ - typedef __tuple_indices<_Indices...> type; -}; +namespace __indexer_detail { -template <size_t _Ep, size_t _Sp = 0> -struct __make_tuple_indices -{ - static_assert(_Sp <= _Ep, "__make_tuple_indices input error"); - typedef typename __make_indices_imp<_Sp, __tuple_indices<>, _Ep>::type type; -}; +template <size_t _Idx, class _Tp> +struct __indexed { using type = _Tp; }; -// __tuple_types +template <class _Types, class _Indexes> struct __indexer; -template <class ..._Tp> struct __tuple_types {}; +template <class ..._Types, size_t ..._Idx> +struct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>> + : __indexed<_Idx, _Types>... +{}; -template <size_t _Ip> -class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<> > -{ -public: - static_assert(_Ip == 0, "tuple_element index out of range"); - static_assert(_Ip != 0, "tuple_element index out of range"); -}; +template <size_t _Idx, class _Tp> +__indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&); -template <class _Hp, class ..._Tp> -class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, __tuple_types<_Hp, _Tp...> > -{ -public: - typedef _Hp type; -}; +} // namespace __indexer_detail + +template <size_t _Idx, class ..._Types> +using __type_pack_element = typename decltype( + __indexer_detail::__at_index<_Idx>( + __indexer_detail::__indexer< + __tuple_types<_Types...>, + typename __make_tuple_indices<sizeof...(_Types)>::type + >{}) + )::type; +#endif -template <size_t _Ip, class _Hp, class ..._Tp> -class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Hp, _Tp...> > +template <size_t _Ip, class ..._Types> +class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Types...>> { public: - typedef typename tuple_element<_Ip-1, __tuple_types<_Tp...> >::type type; + static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range"); + typedef __type_pack_element<_Ip, _Types...> type; }; + template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> > : public integral_constant<size_t, sizeof...(_Tp)> @@ -211,6 +274,46 @@ class _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> > template <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type {}; +template <bool _ApplyLV, bool _ApplyConst, bool _ApplyVolatile> +struct __apply_cv_mf; +template <> +struct __apply_cv_mf<false, false, false> { + template <class _Tp> using __apply = _Tp; +}; +template <> +struct __apply_cv_mf<false, true, false> { + template <class _Tp> using __apply = const _Tp; +}; +template <> +struct __apply_cv_mf<false, false, true> { + template <class _Tp> using __apply = volatile _Tp; +}; +template <> +struct __apply_cv_mf<false, true, true> { + template <class _Tp> using __apply = const volatile _Tp; +}; +template <> +struct __apply_cv_mf<true, false, false> { + template <class _Tp> using __apply = _Tp&; +}; +template <> +struct __apply_cv_mf<true, true, false> { + template <class _Tp> using __apply = const _Tp&; +}; +template <> +struct __apply_cv_mf<true, false, true> { + template <class _Tp> using __apply = volatile _Tp&; +}; +template <> +struct __apply_cv_mf<true, true, true> { + template <class _Tp> using __apply = const volatile _Tp&; +}; +template <class _Tp, class _RawTp = typename remove_reference<_Tp>::type> +using __apply_cv_t = __apply_cv_mf< + is_lvalue_reference<_Tp>::value, + is_const<_RawTp>::value, + is_volatile<_RawTp>::value>; + // __make_tuple_types // __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a @@ -218,58 +321,72 @@ template <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type // _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>. If _Tuple is a // lvalue_reference type, then __tuple_types<_Types&...> is the result. -template <class _TupleTypes, class _Tp, size_t _Sp, size_t _Ep> -struct __make_tuple_types_imp; +template <class _TupleTypes, class _TupleIndices> +struct __make_tuple_types_flat; -template <class ..._Types, class _Tp, size_t _Sp, size_t _Ep> -struct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Sp, _Ep> -{ - typedef typename remove_reference<_Tp>::type _Tpr; - typedef typename __make_tuple_types_imp<__tuple_types<_Types..., - typename conditional<is_lvalue_reference<_Tp>::value, - typename tuple_element<_Sp, _Tpr>::type&, - typename tuple_element<_Sp, _Tpr>::type>::type>, - _Tp, _Sp+1, _Ep>::type type; +template <template <class...> class _Tuple, class ..._Types, size_t ..._Idx> +struct __make_tuple_types_flat<_Tuple<_Types...>, __tuple_indices<_Idx...>> { + // Specialization for pair, tuple, and __tuple_types + template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>> + using __apply_quals = __tuple_types< + typename _ApplyFn::template __apply<__type_pack_element<_Idx, _Types...>>... + >; }; -template <class ..._Types, class _Tp, size_t _Ep> -struct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Ep, _Ep> -{ - typedef __tuple_types<_Types...> type; +template <class _Vt, size_t _Np, size_t ..._Idx> +struct __make_tuple_types_flat<array<_Vt, _Np>, __tuple_indices<_Idx...>> { + template <size_t> + using __value_type = _Vt; + template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>> + using __apply_quals = __tuple_types< + typename _ApplyFn::template __apply<__value_type<_Idx>>... + >; }; -template <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value, size_t _Sp = 0> +template <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value, + size_t _Sp = 0, + bool _SameSize = (_Ep == tuple_size<typename remove_reference<_Tp>::type>::value)> struct __make_tuple_types { static_assert(_Sp <= _Ep, "__make_tuple_types input error"); - typedef typename __make_tuple_types_imp<__tuple_types<>, _Tp, _Sp, _Ep>::type type; + using _RawTp = typename remove_cv<typename remove_reference<_Tp>::type>::type; + using _Maker = __make_tuple_types_flat<_RawTp, typename __make_tuple_indices<_Ep, _Sp>::type>; + using type = typename _Maker::template __apply_quals<_Tp>; }; -// __tuple_convertible - -template <class, class> -struct __tuple_convertible_imp : public false_type {}; - -template <class _Tp0, class ..._Tp, class _Up0, class ..._Up> -struct __tuple_convertible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > - : public integral_constant<bool, - is_convertible<_Tp0, _Up0>::value && - __tuple_convertible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; +template <class ..._Types, size_t _Ep> +struct __make_tuple_types<tuple<_Types...>, _Ep, 0, true> { + typedef __tuple_types<_Types...> type; +}; -template <> -struct __tuple_convertible_imp<__tuple_types<>, __tuple_types<> > - : public true_type {}; +template <class ..._Types, size_t _Ep> +struct __make_tuple_types<__tuple_types<_Types...>, _Ep, 0, true> { + typedef __tuple_types<_Types...> type; +}; -template <bool, class, class> -struct __tuple_convertible_apply : public false_type {}; +template <bool ..._Preds> +struct __all_dummy; + +template <bool ..._Pred> +using __all = is_same<__all_dummy<_Pred...>, __all_dummy<(_Pred, true)...>>; + +struct __tuple_sfinae_base { + template <template <class, class...> class _Trait, + class ..._LArgs, class ..._RArgs> + static auto __do_test(__tuple_types<_LArgs...>, __tuple_types<_RArgs...>) + -> __all<typename enable_if<_Trait<_LArgs, _RArgs>::value, bool>::type{true}...>; + template <template <class...> class> + static auto __do_test(...) -> false_type; + + template <class _FromArgs, class _ToArgs> + using __constructible = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{})); + template <class _FromArgs, class _ToArgs> + using __convertible = decltype(__do_test<is_convertible>(_FromArgs{}, _ToArgs{})); + template <class _FromArgs, class _ToArgs> + using __assignable = decltype(__do_test<is_assignable>(_ToArgs{}, _FromArgs{})); +}; -template <class _Tp, class _Up> -struct __tuple_convertible_apply<true, _Tp, _Up> - : public __tuple_convertible_imp< - typename __make_tuple_types<_Tp>::type - , typename __make_tuple_types<_Up>::type - > -{}; +// __tuple_convertible template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, bool = __tuple_like<_Up>::value> @@ -278,36 +395,14 @@ struct __tuple_convertible template <class _Tp, class _Up> struct __tuple_convertible<_Tp, _Up, true, true> - : public __tuple_convertible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == - tuple_size<_Up>::value, _Tp, _Up> -{}; - -// __tuple_constructible - -template <class, class> -struct __tuple_constructible_imp : public false_type {}; - -template <class _Tp0, class ..._Tp, class _Up0, class ..._Up> -struct __tuple_constructible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > - : public integral_constant<bool, - is_constructible<_Up0, _Tp0>::value && - __tuple_constructible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; - -template <> -struct __tuple_constructible_imp<__tuple_types<>, __tuple_types<> > - : public true_type {}; - -template <bool _SameSize, class, class> -struct __tuple_constructible_apply : public false_type {}; - -template <class _Tp, class _Up> -struct __tuple_constructible_apply<true, _Tp, _Up> - : public __tuple_constructible_imp< + : public __tuple_sfinae_base::__convertible< typename __make_tuple_types<_Tp>::type , typename __make_tuple_types<_Up>::type > {}; +// __tuple_constructible + template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, bool = __tuple_like<_Up>::value> struct __tuple_constructible @@ -315,36 +410,14 @@ struct __tuple_constructible template <class _Tp, class _Up> struct __tuple_constructible<_Tp, _Up, true, true> - : public __tuple_constructible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == - tuple_size<_Up>::value, _Tp, _Up> -{}; - -// __tuple_assignable - -template <class, class> -struct __tuple_assignable_imp : public false_type {}; - -template <class _Tp0, class ..._Tp, class _Up0, class ..._Up> -struct __tuple_assignable_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > - : public integral_constant<bool, - is_assignable<_Up0&, _Tp0>::value && - __tuple_assignable_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; - -template <> -struct __tuple_assignable_imp<__tuple_types<>, __tuple_types<> > - : public true_type {}; - -template <bool, class, class> -struct __tuple_assignable_apply : public false_type {}; - -template <class _Tp, class _Up> -struct __tuple_assignable_apply<true, _Tp, _Up> - : __tuple_assignable_imp< + : public __tuple_sfinae_base::__constructible< typename __make_tuple_types<_Tp>::type , typename __make_tuple_types<_Up>::type > {}; +// __tuple_assignable + template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, bool = __tuple_like<_Up>::value> struct __tuple_assignable @@ -352,8 +425,10 @@ struct __tuple_assignable template <class _Tp, class _Up> struct __tuple_assignable<_Tp, _Up, true, true> - : public __tuple_assignable_apply<tuple_size<typename remove_reference<_Tp>::type>::value == - tuple_size<_Up>::value, _Tp, _Up> + : public __tuple_sfinae_base::__assignable< + typename __make_tuple_types<_Tp>::type + , typename __make_tuple_types<_Up&>::type + > {}; #endif // _LIBCPP_HAS_NO_VARIADICS diff --git a/include/__undef___deallocate b/include/__undef___deallocate index 2b4ad99dad381..52f4d9987e211 100644 --- a/include/__undef___deallocate +++ b/include/__undef___deallocate @@ -9,10 +9,12 @@ //===----------------------------------------------------------------------===// #ifdef __deallocate +#if !defined(_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS) #if defined(_MSC_VER) && !defined(__clang__) _LIBCPP_WARNING("macro __deallocate is incompatible with C++. #undefining __deallocate") #else #warning: macro __deallocate is incompatible with C++. #undefining __deallocate #endif +#endif #undef __deallocate #endif diff --git a/include/__undef_min_max b/include/__undef_min_max index 5df9412c64fd3..d3c31388cead8 100644 --- a/include/__undef_min_max +++ b/include/__undef_min_max @@ -9,21 +9,25 @@ //===----------------------------------------------------------------------===// #ifdef min +#if !defined(_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS) #if defined(_MSC_VER) && ! defined(__clang__) _LIBCPP_WARNING("macro min is incompatible with C++. Try #define NOMINMAX " "before any Windows header. #undefing min") #else #warning: macro min is incompatible with C++. #undefing min #endif +#endif #undef min #endif #ifdef max +#if !defined(_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS) #if defined(_MSC_VER) && ! defined(__clang__) _LIBCPP_WARNING("macro max is incompatible with C++. Try #define NOMINMAX " "before any Windows header. #undefing max") #else #warning: macro max is incompatible with C++. #undefing max #endif +#endif #undef max #endif diff --git a/include/algorithm b/include/algorithm index 71e5df37dfeb5..7a6db7abd26db 100644 --- a/include/algorithm +++ b/include/algorithm @@ -543,6 +543,12 @@ template<class T, class Compare> T min(initializer_list<T> t, Compare comp); // constexpr in C++14 +template<class T> + constexpr const T& clamp( const T& v, const T& lo, const T& hi ); // C++17 + +template<class T, class Compare> + constexpr const T& clamp( const T& v, const T& lo, const T& hi, Compare comp ); // C++17 + template <class ForwardIterator> ForwardIterator max_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14 @@ -624,7 +630,7 @@ template <class BidirectionalIterator, class Compare> #include <initializer_list> #include <type_traits> #include <cstring> -#include <utility> +#include <utility> // needed to provide swap_ranges. #include <memory> #include <iterator> #include <cstddef> @@ -1415,20 +1421,20 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, // search template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> -_ForwardIterator1 +pair<_ForwardIterator1, _ForwardIterator1> __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) { if (__first2 == __last2) - return __first1; // Everything matches an empty sequence + return make_pair(__first1, __first1); // Everything matches an empty sequence while (true) { // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks while (true) { if (__first1 == __last1) // return __last1 if no element matches *__first2 - return __last1; + return make_pair(__last1, __last1); if (__pred(*__first1, *__first2)) break; ++__first1; @@ -1439,9 +1445,9 @@ __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, while (true) { if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern) - return __first1; + return make_pair(__first1, __m1); if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found - return __last1; + return make_pair(__last1, __last1); if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1 { ++__first1; @@ -1452,20 +1458,21 @@ __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, } template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> -_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 +_LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_RandomAccessIterator1, _RandomAccessIterator1> __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag) { - typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _D1; - typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _D2; + typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1; + typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2; // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern - _D2 __len2 = __last2 - __first2; + const _D2 __len2 = __last2 - __first2; if (__len2 == 0) - return __first1; - _D1 __len1 = __last1 - __first1; + return make_pair(__first1, __first1); + const _D1 __len1 = __last1 - __first1; if (__len1 < __len2) - return __last1; + return make_pair(__last1, __last1); const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here while (true) { @@ -1473,7 +1480,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, while (true) { if (__first1 == __s) - return __last1; + return make_pair(__last1, __last1); if (__pred(*__first1, *__first2)) break; ++__first1; @@ -1505,7 +1512,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, if (__pred(*__first1, *__first2)) break; case 0: - return __last1; + return make_pair(__last1, __last1); } __phase2: #endif // !_LIBCPP_UNROLL_LOOPS @@ -1515,7 +1522,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, while (true) { if (++__m2 == __last2) - return __first1; + return make_pair(__first1, __first1 + __len2); ++__m1; // no need to check range on __m1 because __s guarantees we have enough source if (!__pred(*__m1, *__m2)) { @@ -1555,7 +1562,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, if (!__pred(*__m1, *__m2)) break; case 0: - return __first1; + return make_pair(__first1, __first1 + __len2); } __continue: ++__first1; @@ -1571,8 +1578,9 @@ search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, { return _VSTD::__search<typename add_lvalue_reference<_BinaryPredicate>::type> (__first1, __last1, __first2, __last2, __pred, - typename std::iterator_traits<_ForwardIterator1>::iterator_category(), - typename std::iterator_traits<_ForwardIterator2>::iterator_category()); + typename iterator_traits<_ForwardIterator1>::iterator_category(), + typename iterator_traits<_ForwardIterator2>::iterator_category()) + .first; } template <class _ForwardIterator1, class _ForwardIterator2> @@ -1581,8 +1589,8 @@ _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { - typedef typename std::iterator_traits<_ForwardIterator1>::value_type __v1; - typedef typename std::iterator_traits<_ForwardIterator2>::value_type __v2; + typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; + typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); } @@ -2657,6 +2665,27 @@ max(initializer_list<_Tp> __t) #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS +#if _LIBCPP_STD_VER > 14 +// clamp +template<class _Tp, class _Compare> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +const _Tp& +clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp) +{ + _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp"); + return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v; + +} + +template<class _Tp> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +const _Tp& +clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi) +{ + return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>()); +} +#endif + // minmax_element template <class _ForwardIterator, class _Compare> @@ -5725,34 +5754,6 @@ prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); } -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value, - _Tp ->::type -__rotate_left(_Tp __t, _Tp __n = 1) -{ - const unsigned __bits = static_cast<unsigned>(sizeof(_Tp) * __CHAR_BIT__ - 1); - __n &= __bits; - return static_cast<_Tp>((__t << __n) | (static_cast<typename make_unsigned<_Tp>::type>(__t) >> (__bits - __n))); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value, - _Tp ->::type -__rotate_right(_Tp __t, _Tp __n = 1) -{ - const unsigned __bits = static_cast<unsigned>(sizeof(_Tp) * __CHAR_BIT__ - 1); - __n &= __bits; - return static_cast<_Tp>((__t << (__bits - __n)) | (static_cast<typename make_unsigned<_Tp>::type>(__t) >> __n)); -} - _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_ALGORITHM diff --git a/include/array b/include/array index 8866eaf6b4634..719286d52ea3d 100644 --- a/include/array +++ b/include/array @@ -34,7 +34,7 @@ struct array // No explicit construct/copy/destroy for aggregate type void fill(const T& u); - void swap(array& a) noexcept(noexcept(swap(declval<T&>(), declval<T&>()))); + void swap(array& a) noexcept(is_nothrow_swappable_v<T>); // iterators: iterator begin() noexcept; @@ -141,8 +141,15 @@ struct _LIBCPP_TYPE_VIS_ONLY array _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) {_VSTD::fill_n(__elems_, _Size, __u);} _LIBCPP_INLINE_VISIBILITY - void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) - {_VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);} + void swap(array& __a) _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value) + { __swap_dispatch((std::integral_constant<bool, _Size == 0>()), __a); } + + _LIBCPP_INLINE_VISIBILITY + void __swap_dispatch(std::true_type, array&) {} + + _LIBCPP_INLINE_VISIBILITY + void __swap_dispatch(std::false_type, array& __a) + { _VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);} // iterators: _LIBCPP_INLINE_VISIBILITY @@ -276,11 +283,12 @@ template <class _Tp, size_t _Size> inline _LIBCPP_INLINE_VISIBILITY typename enable_if < + _Size == 0 || __is_swappable<_Tp>::value, void >::type -swap(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) - _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) +swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y) + _NOEXCEPT_(noexcept(__x.swap(__y))) { __x.swap(__y); } diff --git a/include/atomic b/include/atomic index abec2a0b565a3..11f2152e5bc6b 100644 --- a/include/atomic +++ b/include/atomic @@ -17,6 +17,10 @@ namespace std { +// feature test macro + +#define __cpp_lib_atomic_is_always_lock_free // as specified by SG10 + // order and consistency typedef enum memory_order @@ -89,6 +93,7 @@ void template <class T> struct atomic { + static constexpr bool is_always_lock_free; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; @@ -127,6 +132,7 @@ struct atomic template <> struct atomic<integral> { + static constexpr bool is_always_lock_free; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; @@ -202,6 +208,7 @@ struct atomic<integral> template <class T> struct atomic<T*> { + static constexpr bool is_always_lock_free; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; @@ -508,6 +515,15 @@ typedef atomic<uint_fast32_t> atomic_uint_fast32_t; typedef atomic<int_fast64_t> atomic_int_fast64_t; typedef atomic<uint_fast64_t> atomic_uint_fast64_t; +typedef atomic<int8_t> atomic_int8_t; +typedef atomic<uint8_t> atomic_uint8_t; +typedef atomic<int16_t> atomic_int16_t; +typedef atomic<uint16_t> atomic_uint16_t; +typedef atomic<int32_t> atomic_int32_t; +typedef atomic<uint32_t> atomic_uint32_t; +typedef atomic<int64_t> atomic_int64_t; +typedef atomic<uint64_t> atomic_uint64_t; + typedef atomic<intptr_t> atomic_intptr_t; typedef atomic<uintptr_t> atomic_uintptr_t; typedef atomic<size_t> atomic_size_t; @@ -540,6 +556,11 @@ void atomic_signal_fence(memory_order m) noexcept; #error <atomic> is not implemented #endif +#if _LIBCPP_STD_VER > 14 +// FIXME: use the right feature test macro value as chose by SG10. +# define __cpp_lib_atomic_is_always_lock_free 201603L +#endif + _LIBCPP_BEGIN_NAMESPACE_STD typedef enum memory_order @@ -825,6 +846,17 @@ kill_dependency(_Tp __y) _NOEXCEPT return __y; } +#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE +#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE +#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE +#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE +#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE +#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE +#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE +#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE +#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE +#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE + // general atomic<T> template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value> @@ -832,6 +864,10 @@ struct __atomic_base // false { mutable _Atomic(_Tp) __a_; +#if defined(__cpp_lib_atomic_is_always_lock_free) + static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0); +#endif + _LIBCPP_INLINE_VISIBILITY bool is_lock_free() const volatile _NOEXCEPT { @@ -920,6 +956,11 @@ private: #endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS }; +#if defined(__cpp_lib_atomic_is_always_lock_free) +template <class _Tp, bool __b> +_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free; +#endif + // atomic<Integral> template <class _Tp> @@ -1657,7 +1698,7 @@ typedef struct atomic_flag #endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS _LIBCPP_INLINE_VISIBILITY - atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} + atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS atomic_flag(const atomic_flag&) = delete; @@ -1779,6 +1820,15 @@ typedef atomic<uint_fast32_t> atomic_uint_fast32_t; typedef atomic<int_fast64_t> atomic_int_fast64_t; typedef atomic<uint_fast64_t> atomic_uint_fast64_t; +typedef atomic< int8_t> atomic_int8_t; +typedef atomic<uint8_t> atomic_uint8_t; +typedef atomic< int16_t> atomic_int16_t; +typedef atomic<uint16_t> atomic_uint16_t; +typedef atomic< int32_t> atomic_int32_t; +typedef atomic<uint32_t> atomic_uint32_t; +typedef atomic< int64_t> atomic_int64_t; +typedef atomic<uint64_t> atomic_uint64_t; + typedef atomic<intptr_t> atomic_intptr_t; typedef atomic<uintptr_t> atomic_uintptr_t; typedef atomic<size_t> atomic_size_t; @@ -1789,17 +1839,6 @@ typedef atomic<uintmax_t> atomic_uintmax_t; #define ATOMIC_FLAG_INIT {false} #define ATOMIC_VAR_INIT(__v) {__v} -#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE -#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE -#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE -#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE -#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE -#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE -#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE -#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE -#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE -#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE - _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_ATOMIC diff --git a/include/bitset b/include/bitset index 87d7afca5a738..3f9b964e45acb 100644 --- a/include/bitset +++ b/include/bitset @@ -656,7 +656,7 @@ __bitset<0, 0>::__bitset(unsigned long long) _NOEXCEPT } template <size_t _Size> class _LIBCPP_TYPE_VIS_ONLY bitset; -template <size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY hash<bitset<_Size> >; +template <size_t _Size> struct hash<bitset<_Size> >; template <size_t _Size> class _LIBCPP_TYPE_VIS_ONLY bitset diff --git a/include/cctype b/include/cctype index a68c2a06604d6..7fc81344696de 100644 --- a/include/cctype +++ b/include/cctype @@ -44,6 +44,63 @@ int toupper(int c); _LIBCPP_BEGIN_NAMESPACE_STD +#ifdef isalnum +#undef isalnum +#endif + +#ifdef isalpha +#undef isalpha +#endif + +#ifdef isblank +#undef isblank +#endif + +#ifdef iscntrl +#undef iscntrl +#endif + +#ifdef isdigit +#undef isdigit +#endif + +#ifdef isgraph +#undef isgraph +#endif + +#ifdef islower +#undef islower +#endif + +#ifdef isprint +#undef isprint +#endif + +#ifdef ispunct +#undef ispunct +#endif + +#ifdef isspace +#undef isspace +#endif + +#ifdef isupper +#undef isupper +#endif + +#ifdef isxdigit +#undef isxdigit +#endif + +#ifdef tolower +#undef tolower +#endif + +#ifdef toupper +#undef toupper +#endif + + using ::isalnum; using ::isalpha; using ::isblank; diff --git a/include/cmath b/include/cmath index ebbde18168ff7..b3e959405e9ef 100644 --- a/include/cmath +++ b/include/cmath @@ -209,6 +209,10 @@ floating_point hypot (arithmetic x, arithmetic y); float hypotf(float x, float y); long double hypotl(long double x, long double y); +double hypot(double x, double y, double z); // C++17 +float hypot(float x, float y, float z); // C++17 +long double hypot(long double x, long double y, long double z); // C++17 + int ilogb (arithmetic x); int ilogbf(float x); int ilogbl(long double x); @@ -548,6 +552,30 @@ using ::lgamma; using ::lgammaf; #endif // __sun__ +#if _LIBCPP_STD_VER > 14 +inline _LIBCPP_INLINE_VISIBILITY float hypot( float x, float y, float z ) { return sqrt(x*x + y*y + z*z); } +inline _LIBCPP_INLINE_VISIBILITY double hypot( double x, double y, double z ) { return sqrt(x*x + y*y + z*z); } +inline _LIBCPP_INLINE_VISIBILITY long double hypot( long double x, long double y, long double z ) { return sqrt(x*x + y*y + z*z); } + +template <class _A1, class _A2, class _A3> +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value && + std::is_arithmetic<_A3>::value, + std::__promote<_A1, _A2, _A3> +>::type +hypot(_A1 __lcpp_x, _A2 __lcpp_y, _A3 __lcpp_z) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2, _A3>::type __result_type; + static_assert((!(std::is_same<_A1, __result_type>::value && + std::is_same<_A2, __result_type>::value && + std::is_same<_A3, __result_type>::value)), ""); + return hypot((__result_type)__lcpp_x, (__result_type)__lcpp_y, (__result_type)__lcpp_z); +} +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_CMATH diff --git a/include/complex b/include/complex index 2943da1d775ca..f56138fa2d16e 100644 --- a/include/complex +++ b/include/complex @@ -332,7 +332,9 @@ public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f) : __re_(__re), __im_(__im) {} + _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c); + _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;} @@ -388,7 +390,9 @@ public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0) : __re_(__re), __im_(__im) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(const complex<float>& __c); + _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;} @@ -444,7 +448,9 @@ public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L) : __re_(__re), __im_(__im) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(const complex<float>& __c); + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(const complex<double>& __c); _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;} @@ -490,32 +496,32 @@ public: } }; -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR complex<float>::complex(const complex<double>& __c) : __re_(__c.real()), __im_(__c.imag()) {} -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR complex<float>::complex(const complex<long double>& __c) : __re_(__c.real()), __im_(__c.imag()) {} -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR complex<double>::complex(const complex<float>& __c) : __re_(__c.real()), __im_(__c.imag()) {} -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR complex<double>::complex(const complex<long double>& __c) : __re_(__c.real()), __im_(__c.imag()) {} -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR complex<long double>::complex(const complex<float>& __c) : __re_(__c.real()), __im_(__c.imag()) {} -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR complex<long double>::complex(const complex<double>& __c) : __re_(__c.real()), __im_(__c.imag()) {} @@ -1399,7 +1405,7 @@ acos(const complex<_Tp>& __x) } if (isinf(__x.imag())) return complex<_Tp>(__pi/_Tp(2), -__x.imag()); - if (__x.real() == 0) + if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag()))) return complex<_Tp>(__pi/_Tp(2), -__x.imag()); complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) - _Tp(1))); if (signbit(__x.imag())) diff --git a/include/cstring b/include/cstring index d60b9923c6c22..d550695caa42f 100644 --- a/include/cstring +++ b/include/cstring @@ -78,30 +78,13 @@ using ::strcmp; using ::strncmp; using ::strcoll; using ::strxfrm; - using ::memchr; - using ::strchr; - using ::strcspn; - using ::strpbrk; - using ::strrchr; - using ::strspn; - using ::strstr; - -// MSVCRT, GNU libc and its derivates already have the correct prototype in <string.h> #ifdef __cplusplus -#if !defined(__GLIBC__) && !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_) -inline _LIBCPP_INLINE_VISIBILITY char* strchr( char* __s, int __c) {return ::strchr(__s, __c);} -inline _LIBCPP_INLINE_VISIBILITY char* strpbrk( char* __s1, const char* __s2) {return ::strpbrk(__s1, __s2);} -inline _LIBCPP_INLINE_VISIBILITY char* strrchr( char* __s, int __c) {return ::strrchr(__s, __c);} -inline _LIBCPP_INLINE_VISIBILITY void* memchr( void* __s, int __c, size_t __n) {return ::memchr(__s, __c, __n);} -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 diff --git a/include/cwchar b/include/cwchar index ef4806db2bdef..52dde9e18021b 100644 --- a/include/cwchar +++ b/include/cwchar @@ -157,30 +157,11 @@ using ::wcscmp; using ::wcscoll; using ::wcsncmp; using ::wcsxfrm; - -#ifdef _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS using ::wcschr; using ::wcspbrk; using ::wcsrchr; using ::wcsstr; using ::wmemchr; -#else -inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcschr(const wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);} -inline _LIBCPP_INLINE_VISIBILITY wchar_t* wcschr( wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);} - -inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcspbrk(const wchar_t* __s1, const wchar_t* __s2) {return ::wcspbrk(__s1, __s2);} -inline _LIBCPP_INLINE_VISIBILITY wchar_t* wcspbrk( wchar_t* __s1, const wchar_t* __s2) {return ::wcspbrk(__s1, __s2);} - -inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcsrchr(const wchar_t* __s, wchar_t __c) {return ::wcsrchr(__s, __c);} -inline _LIBCPP_INLINE_VISIBILITY wchar_t* wcsrchr( wchar_t* __s, wchar_t __c) {return ::wcsrchr(__s, __c);} - -inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcsstr(const wchar_t* __s1, const wchar_t* __s2) {return ::wcsstr(__s1, __s2);} -inline _LIBCPP_INLINE_VISIBILITY wchar_t* wcsstr( wchar_t* __s1, const wchar_t* __s2) {return ::wcsstr(__s1, __s2);} - -inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wmemchr(const wchar_t* __s, wchar_t __c, size_t __n) {return ::wmemchr(__s, __c, __n);} -inline _LIBCPP_INLINE_VISIBILITY wchar_t* wmemchr( wchar_t* __s, wchar_t __c, size_t __n) {return ::wmemchr(__s, __c, __n);} -#endif - using ::wcscspn; using ::wcslen; using ::wcsspn; diff --git a/include/deque b/include/deque index c6fbd512a1c6e..57650427645ce 100644 --- a/include/deque +++ b/include/deque @@ -2026,7 +2026,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) } else { - value_type __tmp(_VSTD::forward<_Args>(__args)...); + __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...); iterator __b = __base::begin(); iterator __bm1 = _VSTD::prev(__b); __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b)); @@ -2034,7 +2034,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) ++__base::size(); if (__pos > 1) __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b); - *__b = _VSTD::move(__tmp); + *__b = _VSTD::move(__tmp.get()); } } else @@ -2050,14 +2050,14 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) } else { - value_type __tmp(_VSTD::forward<_Args>(__args)...); + __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...); iterator __e = __base::end(); iterator __em1 = _VSTD::prev(__e); __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); ++__base::size(); if (__de > 1) __e = _VSTD::move_backward(__e - __de, __em1, __e); - *--__e = _VSTD::move(__tmp); + *--__e = _VSTD::move(__tmp.get()); } } return __base::begin() + __pos; diff --git a/include/exception b/include/exception index 686e4ecd05783..186d379f08f5f 100644 --- a/include/exception +++ b/include/exception @@ -80,6 +80,10 @@ template <class E> void rethrow_if_nested(const E& e); #include <__config> #include <cstddef> #include <type_traits> +#if defined(_LIBCPP_NO_EXCEPTIONS) +#include <cstdio> +#include <cstdlib> +#endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -251,4 +255,19 @@ rethrow_if_nested(const _Ep&, typename enable_if< } // std +_LIBCPP_BEGIN_NAMESPACE_STD + +template <class _Exception> +_LIBCPP_INLINE_VISIBILITY +inline void __libcpp_throw(_Exception const& __e) { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw __e; +#else + _VSTD::fprintf(stderr, "%s\n", __e.what()); + _VSTD::abort(); +#endif +} + +_LIBCPP_END_NAMESPACE_STD + #endif // _LIBCPP_EXCEPTION diff --git a/include/experimental/__config b/include/experimental/__config index f64a3a90cd125..9a7bbe85d8d3f 100644 --- a/include/experimental/__config +++ b/include/experimental/__config @@ -25,8 +25,26 @@ #define _LIBCPP_END_NAMESPACE_LFTS } } } #define _VSTD_LFTS _VSTD_EXPERIMENTAL::fundamentals_v1 +#define _LIBCPP_BEGIN_NAMESPACE_LFTS_V2 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace fundamentals_v2 { +#define _LIBCPP_END_NAMESPACE_LFTS_V2 } } } +#define _VSTD_LFTS_V2 _VSTD_EXPERIMENTAL::fundamentals_v2 + +#define _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR _LIBCPP_BEGIN_NAMESPACE_LFTS namespace pmr { +#define _LIBCPP_END_NAMESPACE_LFTS_PMR _LIBCPP_END_NAMESPACE_LFTS } +#define _VSTD_LFTS_PMR _VSTD_LFTS::pmr + #define _LIBCPP_BEGIN_NAMESPACE_CHRONO_LFTS _LIBCPP_BEGIN_NAMESPACE_STD \ namespace chrono { namespace experimental { inline namespace fundamentals_v1 { #define _LIBCPP_END_NAMESPACE_CHRONO_LFTS _LIBCPP_END_NAMESPACE_STD } } } +#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM \ + _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL namespace filesystem { \ + inline namespace v1 { + +#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM \ + } } _LIBCPP_END_NAMESPACE_EXPERIMENTAL + + +#define _VSTD_FS ::std::experimental::filesystem::v1 + #endif diff --git a/include/experimental/__memory b/include/experimental/__memory new file mode 100644 index 0000000000000..229fea605bfd3 --- /dev/null +++ b/include/experimental/__memory @@ -0,0 +1,90 @@ +// -*- 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_EXPERIMENTAL___MEMORY +#define _LIBCPP_EXPERIMENTAL___MEMORY + +#include <experimental/__config> +#include <experimental/utility> // for erased_type +#include <__functional_base> +#include <type_traits> + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +template < + class _Tp, class _Alloc + , bool = uses_allocator<_Tp, _Alloc>::value + , bool = __has_allocator_type<_Tp>::value + > +struct __lfts_uses_allocator : public false_type {}; + +template <class _Tp, class _Alloc> +struct __lfts_uses_allocator<_Tp, _Alloc, false, false> : public false_type {}; + +template <class _Tp, class _Alloc, bool HasAlloc> +struct __lfts_uses_allocator<_Tp, _Alloc, true, HasAlloc> : public true_type {}; + +template <class _Tp, class _Alloc> +struct __lfts_uses_allocator<_Tp, _Alloc, false, true> + : public integral_constant<bool + , is_convertible<_Alloc, typename _Tp::allocator_type>::value + || is_same<erased_type, typename _Tp::allocator_type>::value + > +{}; + +template <bool _UsesAlloc, class _Tp, class _Alloc, class ..._Args> +struct __lfts_uses_alloc_ctor_imp +{ + static const int value = 0; +}; + +template <class _Tp, class _Alloc, class ..._Args> +struct __lfts_uses_alloc_ctor_imp<true, _Tp, _Alloc, _Args...> +{ + static const bool __ic_first + = is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; + + static const bool __ic_second = + conditional< + __ic_first, + false_type, + is_constructible<_Tp, _Args..., _Alloc> + >::type::value; + + static_assert(__ic_first || __ic_second, + "Request for uses allocator construction is ill-formed"); + + static const int value = __ic_first ? 1 : 2; +}; + +template <class _Tp, class _Alloc, class ..._Args> +struct __lfts_uses_alloc_ctor + : integral_constant<int, + __lfts_uses_alloc_ctor_imp< + __lfts_uses_allocator<_Tp, _Alloc>::value + , _Tp, _Alloc, _Args... + >::value + > +{}; + +template <class _Tp, class _Alloc, class ..._Args> +inline _LIBCPP_INLINE_VISIBILITY +void __lfts_user_alloc_construct( + _Tp * __store, const _Alloc & __a, _Args &&... __args) +{ + _VSTD::__user_alloc_construct_impl( + typename __lfts_uses_alloc_ctor<_Tp, _Alloc, _Args...>::type() + , __store, __a, _VSTD::forward<_Args>(__args)... + ); +} + +_LIBCPP_END_NAMESPACE_LFTS + +#endif /* _LIBCPP_EXPERIMENTAL___MEMORY */ diff --git a/include/experimental/algorithm b/include/experimental/algorithm index ffaa793b6d4eb..3902111c54ea3 100644 --- a/include/experimental/algorithm +++ b/include/experimental/algorithm @@ -53,7 +53,7 @@ _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); } +{ return __s(__f, __l).first; } template <class _PopulationIterator, class _SampleIterator, class _Distance, diff --git a/include/experimental/any b/include/experimental/any index 603788484dd5a..4c732496c52b4 100644 --- a/include/experimental/any +++ b/include/experimental/any @@ -113,10 +113,12 @@ class any; template <class _ValueType> typename add_pointer<typename add_const<_ValueType>::type>::type +_LIBCPP_INLINE_VISIBILITY any_cast(any const *) _NOEXCEPT; template <class _ValueType> typename add_pointer<_ValueType>::type +_LIBCPP_INLINE_VISIBILITY any_cast(any *) _NOEXCEPT; namespace __any_imp @@ -185,6 +187,7 @@ public: class _ValueType , class = __any_imp::_EnableIfNotAny<_ValueType> > + _LIBCPP_INLINE_VISIBILITY any(_ValueType && __value); _LIBCPP_INLINE_VISIBILITY @@ -212,6 +215,7 @@ public: class _ValueType , class = __any_imp::_EnableIfNotAny<_ValueType> > + _LIBCPP_INLINE_VISIBILITY any & operator=(_ValueType && __rhs); // 6.3.3 any modifiers @@ -221,6 +225,7 @@ public: if (__h) this->__call(_Action::_Destroy); } + _LIBCPP_INLINE_VISIBILITY void swap(any & __rhs) _NOEXCEPT; // 6.3.4 any observers @@ -457,7 +462,6 @@ namespace __any_imp template <class _ValueType, class> -_LIBCPP_INLINE_VISIBILITY any::any(_ValueType && __v) : __h(nullptr) { typedef typename decay<_ValueType>::type _Tp; @@ -468,7 +472,6 @@ any::any(_ValueType && __v) : __h(nullptr) } template <class _ValueType, class> -_LIBCPP_INLINE_VISIBILITY any & any::operator=(_ValueType && __v) { typedef typename decay<_ValueType>::type _Tp; @@ -478,7 +481,7 @@ any & any::operator=(_ValueType && __v) return *this; } -inline _LIBCPP_INLINE_VISIBILITY +inline void any::swap(any & __rhs) _NOEXCEPT { if (__h && __rhs.__h) { @@ -550,7 +553,7 @@ _ValueType any_cast(any && __v) } template <class _ValueType> -inline _LIBCPP_INLINE_VISIBILITY +inline typename add_pointer<typename add_const<_ValueType>::type>::type any_cast(any const * __any) _NOEXCEPT { @@ -560,7 +563,6 @@ any_cast(any const * __any) _NOEXCEPT } template <class _ValueType> -_LIBCPP_INLINE_VISIBILITY typename add_pointer<_ValueType>::type any_cast(any * __any) _NOEXCEPT { diff --git a/include/experimental/deque b/include/experimental/deque new file mode 100644 index 0000000000000..f8495743c1f9e --- /dev/null +++ b/include/experimental/deque @@ -0,0 +1,47 @@ +// -*- C++ -*- +//===--------------------------- deque ------------------------------------===// +// +// 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_DEQUE +#define _LIBCPP_EXPERIMENTAL_DEQUE +/* + experimental/deque synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class T> + using deque = std::deque<T,polymorphic_allocator<T>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <deque> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _ValueT> +using deque = _VSTD::deque<_ValueT, polymorphic_allocator<_ValueT>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_DEQUE */ diff --git a/include/experimental/dynarray b/include/experimental/dynarray index f40a6ca188b8f..4a06908e11b16 100644 --- a/include/experimental/dynarray +++ b/include/experimental/dynarray @@ -159,9 +159,13 @@ private: public: + _LIBCPP_INLINE_VISIBILITY explicit dynarray(size_type __c); + _LIBCPP_INLINE_VISIBILITY dynarray(size_type __c, const value_type& __v); + _LIBCPP_INLINE_VISIBILITY dynarray(const dynarray& __d); + _LIBCPP_INLINE_VISIBILITY dynarray(initializer_list<value_type>); // We're not implementing these right now. @@ -176,6 +180,7 @@ public: // dynarray(allocator_arg_t, const _Alloc& __alloc, initializer_list<value_type>); dynarray& operator=(const dynarray&) = delete; + _LIBCPP_INLINE_VISIBILITY ~dynarray(); // iterators: @@ -219,7 +224,7 @@ public: }; template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline dynarray<_Tp>::dynarray(size_type __c) : dynarray () { __base_ = __allocate (__c); @@ -229,7 +234,7 @@ dynarray<_Tp>::dynarray(size_type __c) : dynarray () } template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline dynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray () { __base_ = __allocate (__c); @@ -239,7 +244,7 @@ dynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray () } template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline dynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray () { size_t sz = __il.size(); @@ -251,7 +256,7 @@ dynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray () } template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray () { size_t sz = __d.size(); @@ -263,7 +268,7 @@ dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray () } template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline dynarray<_Tp>::~dynarray() { value_type *__data = data () + __size_; diff --git a/include/experimental/filesystem b/include/experimental/filesystem new file mode 100644 index 0000000000000..7de93fdf8f150 --- /dev/null +++ b/include/experimental/filesystem @@ -0,0 +1,2052 @@ +// -*- C++ -*- +//===--------------------------- filesystem -------------------------------===// +// +// 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_FILESYSTEM +#define _LIBCPP_EXPERIMENTAL_FILESYSTEM +/* + filesystem synopsis + + namespace std { namespace experimental { namespace filesystem { inline namespace v1 { + + class path; + + void swap(path& lhs, path& rhs) _NOEXCEPT; + size_t hash_value(const path& p) _NOEXCEPT; + + bool operator==(const path& lhs, const path& rhs) _NOEXCEPT; + bool operator!=(const path& lhs, const path& rhs) _NOEXCEPT; + bool operator< (const path& lhs, const path& rhs) _NOEXCEPT; + bool operator<=(const path& lhs, const path& rhs) _NOEXCEPT; + bool operator> (const path& lhs, const path& rhs) _NOEXCEPT; + bool operator>=(const path& lhs, const path& rhs) _NOEXCEPT; + + path operator/ (const path& lhs, const path& rhs); + + template <class charT, class traits> + basic_ostream<charT, traits>& + operator<<(basic_ostream<charT, traits>& os, const path& p); + + template <class charT, class traits> + basic_istream<charT, traits>& + operator>>(basic_istream<charT, traits>& is, path& p); + + template <class Source> + path u8path(const Source& source); + template <class InputIterator> + path u8path(InputIterator first, InputIterator last); + + class filesystem_error; + class directory_entry; + + class directory_iterator; + + // enable directory_iterator range-based for statements + directory_iterator begin(directory_iterator iter) noexcept; + directory_iterator end(const directory_iterator&) noexcept; + + class recursive_directory_iterator; + + // enable recursive_directory_iterator range-based for statements + recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; + recursive_directory_iterator end(const recursive_directory_iterator&) noexcept; + + class file_status; + + struct space_info + { + uintmax_t capacity; + uintmax_t free; + uintmax_t available; + }; + + enum class file_type; + enum class perms; + enum class copy_options; + enum class directory_options; + + typedef chrono::time_point<trivial-clock> file_time_type; + + // operational functions + + path absolute(const path& p, const path& base=current_path()); + + path canonical(const path& p, const path& base = current_path()); + path canonical(const path& p, error_code& ec); + path canonical(const path& p, const path& base, error_code& ec); + + void copy(const path& from, const path& to); + void copy(const path& from, const path& to, error_code& ec) _NOEXCEPT; + void copy(const path& from, const path& to, copy_options options); + void copy(const path& from, const path& to, copy_options options, + error_code& ec) _NOEXCEPT; + + bool copy_file(const path& from, const path& to); + bool copy_file(const path& from, const path& to, error_code& ec) _NOEXCEPT; + bool copy_file(const path& from, const path& to, copy_options option); + bool copy_file(const path& from, const path& to, copy_options option, + error_code& ec) _NOEXCEPT; + + void copy_symlink(const path& existing_symlink, const path& new_symlink); + void copy_symlink(const path& existing_symlink, const path& new_symlink, + error_code& ec) _NOEXCEPT; + + bool create_directories(const path& p); + bool create_directories(const path& p, error_code& ec) _NOEXCEPT; + + bool create_directory(const path& p); + bool create_directory(const path& p, error_code& ec) _NOEXCEPT; + + bool create_directory(const path& p, const path& attributes); + bool create_directory(const path& p, const path& attributes, + error_code& ec) _NOEXCEPT; + + void create_directory_symlink(const path& to, const path& new_symlink); + void create_directory_symlink(const path& to, const path& new_symlink, + error_code& ec) _NOEXCEPT; + + void create_hard_link(const path& to, const path& new_hard_link); + void create_hard_link(const path& to, const path& new_hard_link, + error_code& ec) _NOEXCEPT; + + void create_symlink(const path& to, const path& new_symlink); + void create_symlink(const path& to, const path& new_symlink, + error_code& ec) _NOEXCEPT; + + path current_path(); + path current_path(error_code& ec); + void current_path(const path& p); + void current_path(const path& p, error_code& ec) _NOEXCEPT; + + bool exists(file_status s) _NOEXCEPT; + bool exists(const path& p); + bool exists(const path& p, error_code& ec) _NOEXCEPT; + + bool equivalent(const path& p1, const path& p2); + bool equivalent(const path& p1, const path& p2, error_code& ec) _NOEXCEPT; + + uintmax_t file_size(const path& p); + uintmax_t file_size(const path& p, error_code& ec) _NOEXCEPT; + + uintmax_t hard_link_count(const path& p); + uintmax_t hard_link_count(const path& p, error_code& ec) _NOEXCEPT; + + bool is_block_file(file_status s) _NOEXCEPT; + bool is_block_file(const path& p); + bool is_block_file(const path& p, error_code& ec) _NOEXCEPT; + + bool is_character_file(file_status s) _NOEXCEPT; + bool is_character_file(const path& p); + bool is_character_file(const path& p, error_code& ec) _NOEXCEPT; + + bool is_directory(file_status s) _NOEXCEPT; + bool is_directory(const path& p); + bool is_directory(const path& p, error_code& ec) _NOEXCEPT; + + bool is_empty(const path& p); + bool is_empty(const path& p, error_code& ec) _NOEXCEPT; + + bool is_fifo(file_status s) _NOEXCEPT; + bool is_fifo(const path& p); + bool is_fifo(const path& p, error_code& ec) _NOEXCEPT; + + bool is_other(file_status s) _NOEXCEPT; + bool is_other(const path& p); + bool is_other(const path& p, error_code& ec) _NOEXCEPT; + + bool is_regular_file(file_status s) _NOEXCEPT; + bool is_regular_file(const path& p); + bool is_regular_file(const path& p, error_code& ec) _NOEXCEPT; + + bool is_socket(file_status s) _NOEXCEPT; + bool is_socket(const path& p); + bool is_socket(const path& p, error_code& ec) _NOEXCEPT; + + bool is_symlink(file_status s) _NOEXCEPT; + bool is_symlink(const path& p); + bool is_symlink(const path& p, error_code& ec) _NOEXCEPT; + + file_time_type last_write_time(const path& p); + file_time_type last_write_time(const path& p, error_code& ec) _NOEXCEPT; + void last_write_time(const path& p, file_time_type new_time); + void last_write_time(const path& p, file_time_type new_time, + error_code& ec) _NOEXCEPT; + + void permissions(const path& p, perms prms); + void permissions(const path& p, perms prms, error_code& ec) _NOEXCEPT; + + path read_symlink(const path& p); + path read_symlink(const path& p, error_code& ec); + + bool remove(const path& p); + bool remove(const path& p, error_code& ec) _NOEXCEPT; + + uintmax_t remove_all(const path& p); + uintmax_t remove_all(const path& p, error_code& ec) _NOEXCEPT; + + void rename(const path& from, const path& to); + void rename(const path& from, const path& to, error_code& ec) _NOEXCEPT; + + void resize_file(const path& p, uintmax_t size); + void resize_file(const path& p, uintmax_t size, error_code& ec) _NOEXCEPT; + + space_info space(const path& p); + space_info space(const path& p, error_code& ec) _NOEXCEPT; + + file_status status(const path& p); + file_status status(const path& p, error_code& ec) _NOEXCEPT; + + bool status_known(file_status s) _NOEXCEPT; + + file_status symlink_status(const path& p); + file_status symlink_status(const path& p, error_code& ec) _NOEXCEPT; + + path system_complete(const path& p); + path system_complete(const path& p, error_code& ec); + + path temp_directory_path(); + path temp_directory_path(error_code& ec); + +} } } } // namespaces std::experimental::filesystem::v1 + +*/ + +#include <experimental/__config> +#include <cstddef> +#include <chrono> +#include <iterator> +#include <iosfwd> +#include <locale> +#include <memory> +#include <stack> +#include <string> +#include <system_error> +#include <utility> +#include <iomanip> // for quoted +#include <experimental/string_view> + +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#define __cpp_lib_experimental_filesystem 201406 + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM + +typedef chrono::time_point<std::chrono::system_clock> file_time_type; + +struct _LIBCPP_TYPE_VIS space_info +{ + uintmax_t capacity; + uintmax_t free; + uintmax_t available; +}; + +enum class _LIBCPP_TYPE_VIS file_type : signed char +{ + none = 0, + not_found = -1, + regular = 1, + directory = 2, + symlink = 3, + block = 4, + character = 5, + fifo = 6, + socket = 7, + unknown = 8 +}; + +enum class _LIBCPP_TYPE_VIS perms : unsigned +{ + none = 0, + + owner_read = 0400, + owner_write = 0200, + owner_exec = 0100, + owner_all = 0700, + + group_read = 040, + group_write = 020, + group_exec = 010, + group_all = 070, + + others_read = 04, + others_write = 02, + others_exec = 01, + others_all = 07, + + all = 0777, + + set_uid = 04000, + set_gid = 02000, + sticky_bit = 01000, + mask = 07777, + unknown = 0xFFFF, + + add_perms = 0x10000, + remove_perms = 0x20000, + symlink_nofollow = 0x40000 +}; + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR perms operator&(perms _LHS, perms _RHS) +{ return static_cast<perms>(static_cast<unsigned>(_LHS) & static_cast<unsigned>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR perms operator|(perms _LHS, perms _RHS) +{ return static_cast<perms>(static_cast<unsigned>(_LHS) | static_cast<unsigned>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR perms operator^(perms _LHS, perms _RHS) +{ return static_cast<perms>(static_cast<unsigned>(_LHS) ^ static_cast<unsigned>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR perms operator~(perms _LHS) +{ return static_cast<perms>(~static_cast<unsigned>(_LHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator&=(perms& _LHS, perms _RHS) +{ return _LHS = _LHS & _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator|=(perms& _LHS, perms _RHS) +{ return _LHS = _LHS | _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator^=(perms& _LHS, perms _RHS) +{ return _LHS = _LHS ^ _RHS; } + +enum class _LIBCPP_TYPE_VIS copy_options : unsigned short +{ + none = 0, + skip_existing = 1, + overwrite_existing = 2, + update_existing = 4, + recursive = 8, + copy_symlinks = 16, + skip_symlinks = 32, + directories_only = 64, + create_symlinks = 128, + create_hard_links = 256, + __in_recursive_copy = 512, +}; + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR copy_options operator&(copy_options _LHS, copy_options _RHS) +{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) & static_cast<unsigned short>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR copy_options operator|(copy_options _LHS, copy_options _RHS) +{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) | static_cast<unsigned short>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR copy_options operator^(copy_options _LHS, copy_options _RHS) +{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^ static_cast<unsigned short>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR copy_options operator~(copy_options _LHS) +{ return static_cast<copy_options>(~static_cast<unsigned short>(_LHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) +{ return _LHS = _LHS & _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) +{ return _LHS = _LHS | _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) +{ return _LHS = _LHS ^ _RHS; } + + +enum class directory_options : unsigned char +{ + none = 0, + follow_directory_symlink = 1, + skip_permission_denied = 2 +}; + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR directory_options operator&(directory_options _LHS, directory_options _RHS) +{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) & static_cast<unsigned char>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR directory_options operator|(directory_options _LHS, directory_options _RHS) +{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) | static_cast<unsigned char>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR directory_options operator^(directory_options _LHS, directory_options _RHS) +{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^ static_cast<unsigned char>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR directory_options operator~(directory_options _LHS) +{ return static_cast<directory_options>(~static_cast<unsigned char>(_LHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator&=(directory_options& _LHS, directory_options _RHS) +{ return _LHS = _LHS & _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator|=(directory_options& _LHS, directory_options _RHS) +{ return _LHS = _LHS | _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator^=(directory_options& _LHS, directory_options _RHS) +{ return _LHS = _LHS ^ _RHS; } + + +class _LIBCPP_TYPE_VIS file_status +{ +public: + // constructors + _LIBCPP_INLINE_VISIBILITY + explicit file_status(file_type __ft = file_type::none, + perms __prms = perms::unknown) _NOEXCEPT + : __ft_(__ft), __prms_(__prms) + {} + + file_status(const file_status&) _NOEXCEPT = default; + file_status(file_status&&) _NOEXCEPT = default; + + _LIBCPP_INLINE_VISIBILITY + ~file_status() {} + + file_status& operator=(const file_status&) _NOEXCEPT = default; + file_status& operator=(file_status&&) _NOEXCEPT = default; + + // observers + _LIBCPP_ALWAYS_INLINE + file_type type() const _NOEXCEPT { + return __ft_; + } + + _LIBCPP_ALWAYS_INLINE + perms permissions() const _NOEXCEPT { + return __prms_; + } + + // modifiers + _LIBCPP_ALWAYS_INLINE + void type(file_type __ft) _NOEXCEPT { + __ft_ = __ft; + } + + _LIBCPP_ALWAYS_INLINE + void permissions(perms __p) _NOEXCEPT { + __prms_ = __p; + } +private: + file_type __ft_; + perms __prms_; +}; + +class _LIBCPP_TYPE_VIS directory_entry; + +template <class _Tp> struct __can_convert_char { + static const bool value = false; +}; +template <> struct __can_convert_char<char> { + static const bool value = true; + using __char_type = char; +}; +template <> struct __can_convert_char<wchar_t> { + static const bool value = true; + using __char_type = wchar_t; +}; +template <> struct __can_convert_char<char16_t> { + static const bool value = true; + using __char_type = char16_t; +}; +template <> struct __can_convert_char<char32_t> { + static const bool value = true; + using __char_type = char32_t; +}; + +template <class _ECharT> +typename enable_if<__can_convert_char<_ECharT>::value, bool>::type +__is_separator(_ECharT __e) { + return __e == _ECharT('/'); +}; + +struct _NullSentinal {}; + +template <class _Tp> +using _Void = void; + +template <class _Tp, class = void> +struct __is_pathable_string : public false_type {}; + +template <class _ECharT, class _Traits, class _Alloc> +struct __is_pathable_string<basic_string<_ECharT, _Traits, _Alloc>, + _Void<typename __can_convert_char<_ECharT>::__char_type>> +: public __can_convert_char<_ECharT> +{ + using _Str = basic_string<_ECharT, _Traits, _Alloc>; + using _Base = __can_convert_char<_ECharT>; + static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); } + static _ECharT __first_or_null(_Str const& __s) { + return __s.empty() ? _ECharT{} : __s[0]; + } +}; + +template <class _Source, + class _DS = typename decay<_Source>::type, + class _UnqualPtrType = typename remove_const< + typename remove_pointer<_DS>::type>::type, + bool _IsCharPtr = is_pointer<_DS>::value && + __can_convert_char<_UnqualPtrType>::value + > +struct __is_pathable_char_array : false_type {}; + +template <class _Source, class _ECharT, class _UPtr> +struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> + : __can_convert_char<typename remove_const<_ECharT>::type> +{ + using _Base = __can_convert_char<typename remove_const<_ECharT>::type>; + + static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } + static _ECharT const* __range_end(const _ECharT* __b) + { + using _Iter = const _ECharT*; + const _ECharT __sentinal = _ECharT{}; + _Iter __e = __b; + for (; *__e != __sentinal; ++__e) + ; + return __e; + } + + static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } +}; + +template <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value, class = void> +struct __is_pathable_iter : false_type {}; + +template <class _Iter> +struct __is_pathable_iter<_Iter, true, + _Void<typename __can_convert_char<typename iterator_traits<_Iter>::value_type>::__char_type>> + : __can_convert_char<typename iterator_traits<_Iter>::value_type> +{ + using _ECharT = typename iterator_traits<_Iter>::value_type; + using _Base = __can_convert_char<_ECharT>; + + static _Iter __range_begin(_Iter __b) { return __b; } + static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; } + + static _ECharT __first_or_null(_Iter __b) { return *__b; } +}; + +template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value, + bool _IsCharIterT = __is_pathable_char_array<_Tp>::value, + bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value + > +struct __is_pathable : false_type { + static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false"); +}; + +template <class _Tp> +struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {}; + + +template <class _Tp> +struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {}; + + +template <class _Tp> +struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {}; + + +template <class _ECharT> +struct _PathCVT { + static_assert(__can_convert_char<_ECharT>::value, "Char type not convertible"); + + typedef __narrow_to_utf8<sizeof(_ECharT)*__CHAR_BIT__> _Narrower; + + static void __append_range(string& __dest, _ECharT const* __b, _ECharT const* __e) { + _Narrower()(back_inserter(__dest), __b, __e); + } + + template <class _Iter> + static void __append_range(string& __dest, _Iter __b, _Iter __e) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + if (__b == __e) return; + basic_string<_ECharT> __tmp(__b, __e); + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); + } + + template <class _Iter> + static void __append_range(string& __dest, _Iter __b, _NullSentinal) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + const _ECharT __sentinal = _ECharT{}; + if (*__b == __sentinal) return; + basic_string<_ECharT> __tmp; + for (; *__b != __sentinal; ++__b) + __tmp.push_back(*__b); + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); + } + + template <class _Source> + static void __append_source(string& __dest, _Source const& __s) + { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s)); + } +}; + +template <> +struct _PathCVT<char> { + template <class _Iter> + static void __append_range(string& __dest, _Iter __b, _Iter __e) { + for (; __b != __e; ++__b) + __dest.push_back(*__b); + } + + template <class _Iter> + static void __append_range(string& __dest, _Iter __b, _NullSentinal) { + const char __sentinal = char{}; + for (; *__b != __sentinal; ++__b) + __dest.push_back(*__b); + } + + template <class _Source> + static void __append_source(string& __dest, _Source const& __s) + { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s)); + } +}; + + +class _LIBCPP_TYPE_VIS path +{ + template <class _SourceOrIter, class _Tp = path&> + using _EnableIfPathable = typename + enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; + + template <class _Tp> + using _SourceChar = typename __is_pathable<_Tp>::__char_type; + + template <class _Tp> + using _SourceCVT = _PathCVT<_SourceChar<_Tp>>; + +public: + typedef char value_type; + typedef basic_string<value_type> string_type; + static _LIBCPP_CONSTEXPR value_type preferred_separator = '/'; + + // constructors and destructor + _LIBCPP_INLINE_VISIBILITY path() _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {} + _LIBCPP_INLINE_VISIBILITY path(path&& __p) _NOEXCEPT : __pn_(_VSTD::move(__p.__pn_)) {} + + _LIBCPP_INLINE_VISIBILITY + path(string_type&& __s) _NOEXCEPT : __pn_(_VSTD::move(__s)) {} + + template < + class _Source, + class = _EnableIfPathable<_Source, void> + > + path(const _Source& __src) { + _SourceCVT<_Source>::__append_source(__pn_, __src); + } + + template <class _InputIt> + path(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + } + + // TODO Implement locale conversions. + template <class _Source, + class = _EnableIfPathable<_Source, void> + > + path(const _Source& __src, const locale& __loc); + template <class _InputIt> + path(_InputIt __first, _InputIt _last, const locale& __loc); + + _LIBCPP_INLINE_VISIBILITY + ~path() = default; + + // assignments + _LIBCPP_INLINE_VISIBILITY + path& operator=(const path& __p) { + __pn_ = __p.__pn_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator=(path&& __p) _NOEXCEPT { + __pn_ = _VSTD::move(__p.__pn_); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator=(string_type&& __s) _NOEXCEPT { + __pn_ = _VSTD::move(__s); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& assign(string_type&& __s) _NOEXCEPT { + __pn_ = _VSTD::move(__s); + return *this; + } + + template <class _Source> + _LIBCPP_INLINE_VISIBILITY + _EnableIfPathable<_Source> + operator=(const _Source& __src) + { return this->assign(__src); } + + + template <class _Source> + _EnableIfPathable<_Source> + assign(const _Source& __src) { + __pn_.clear(); + _SourceCVT<_Source>::__append_source(__pn_, __src); + return *this; + } + + template <class _InputIt> + path& assign(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + __pn_.clear(); + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + +private: + template <class _ECharT> + void __append_sep_if_needed(_ECharT __first_or_null) { + const _ECharT __null_val = {}; + bool __append_sep = !empty() && + !__is_separator(__pn_.back()) && + __first_or_null != __null_val && // non-empty + !__is_separator(__first_or_null); + if (__append_sep) + __pn_ += preferred_separator; + } + +public: + // appends + path& operator/=(const path& __p) { + __append_sep_if_needed(__p.empty() ? char{} : __p.__pn_[0]); + __pn_ += __p.native(); + return *this; + } + + template <class _Source> + _LIBCPP_INLINE_VISIBILITY + _EnableIfPathable<_Source> + operator/=(const _Source& __src) { + return this->append(__src); + } + + template <class _Source> + _EnableIfPathable<_Source> + append(const _Source& __src) { + using _Traits = __is_pathable<_Source>; + using _CVT = _PathCVT<_SourceChar<_Source>>; + __append_sep_if_needed(_Traits::__first_or_null(__src)); + _CVT::__append_source(__pn_, __src); + return *this; + } + + template <class _InputIt> + path& append(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); + using _CVT = _PathCVT<_ItVal>; + if (__first != __last) { + __append_sep_if_needed(*__first); + _CVT::__append_range(__pn_, __first, __last); + } + return *this; + } + + // concatenation + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const path& __x) { + __pn_ += __x.__pn_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const string_type& __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const value_type* __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(value_type __x) { + __pn_ += __x; + return *this; + } + + + template <class _ECharT> + typename enable_if<__can_convert_char<_ECharT>::value, path&>::type + operator+=(_ECharT __x) + { + basic_string<_ECharT> __tmp; + __tmp += __x; + _PathCVT<_ECharT>::__append_source(__pn_, __tmp); + return *this; + } + + template <class _Source> + _EnableIfPathable<_Source> + operator+=(const _Source& __x) { + return this->concat(__x); + } + + template <class _Source> + _EnableIfPathable<_Source> + concat(const _Source& __x) { + _SourceCVT<_Source>::__append_source(__pn_, __x); + return *this; + } + + template <class _InputIt> + path& concat(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + + // modifiers + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT { + __pn_.clear(); + } + + path& make_preferred() { return *this; } + path& remove_filename() { return *this = parent_path(); } + + path& replace_filename(const path& __replacement) { + remove_filename(); + return (*this /= __replacement); + } + + path& replace_extension(const path& __replacement = path()); + + _LIBCPP_INLINE_VISIBILITY + void swap(path& __rhs) _NOEXCEPT { + __pn_.swap(__rhs.__pn_); + } + + // native format observers + _LIBCPP_INLINE_VISIBILITY + const string_type& native() const _NOEXCEPT { + return __pn_; + } + + _LIBCPP_INLINE_VISIBILITY + const value_type* c_str() const _NOEXCEPT { return __pn_.c_str(); } + + _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; } + + template <class _ECharT, class _Traits = char_traits<_ECharT>, + class _Allocator = allocator<_ECharT> > + basic_string<_ECharT, _Traits, _Allocator> + string(const _Allocator& __a = _Allocator()) const { + using _CVT = __widen_from_utf8<sizeof(_ECharT)*__CHAR_BIT__>; + using _Str = basic_string<_ECharT, _Traits, _Allocator>; + _Str __s(__a); + __s.reserve(__pn_.size()); + _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); + return __s; + } + + _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; } + _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const { return string<wchar_t>(); } + _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; } + _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const { return string<char16_t>(); } + _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const { return string<char32_t>(); } + + // generic format observers + template <class _ECharT, class _Traits = char_traits<_ECharT>, + class _Allocator = allocator<_ECharT> + > + basic_string<_ECharT, _Traits, _Allocator> + generic_string(const _Allocator& __a = _Allocator()) const { + return string<_ECharT, _Traits, _Allocator>(__a); + } + + std::string generic_string() const { return __pn_; } + std::wstring generic_wstring() const { return string<wchar_t>(); } + std::string generic_u8string() const { return __pn_; } + std::u16string generic_u16string() const { return string<char16_t>(); } + std::u32string generic_u32string() const { return string<char32_t>(); } + +private: + _LIBCPP_FUNC_VIS int __compare(const value_type*) const; + _LIBCPP_FUNC_VIS string_view __root_name() const; + _LIBCPP_FUNC_VIS string_view __root_directory() const; + _LIBCPP_FUNC_VIS string_view __relative_path() const; + _LIBCPP_FUNC_VIS string_view __parent_path() const; + _LIBCPP_FUNC_VIS string_view __filename() const; + _LIBCPP_FUNC_VIS string_view __stem() const; + _LIBCPP_FUNC_VIS string_view __extension() const; + +public: + // compare + _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const _NOEXCEPT { return __compare(__p.c_str());} + _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { return __compare(__s.c_str()); } + _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { return __compare(__s); } + + // decomposition + _LIBCPP_INLINE_VISIBILITY path root_name() const { return __root_name().to_string(); } + _LIBCPP_INLINE_VISIBILITY path root_directory() const { return __root_directory().to_string(); } + _LIBCPP_INLINE_VISIBILITY path root_path() const { return root_name().append(__root_directory().to_string()); } + _LIBCPP_INLINE_VISIBILITY path relative_path() const { return __relative_path().to_string(); } + _LIBCPP_INLINE_VISIBILITY path parent_path() const { return __parent_path().to_string(); } + _LIBCPP_INLINE_VISIBILITY path filename() const { return __filename().to_string(); } + _LIBCPP_INLINE_VISIBILITY path stem() const { return __stem().to_string();} + _LIBCPP_INLINE_VISIBILITY path extension() const { return __extension().to_string(); } + + // query + _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT { return __pn_.empty(); } + + _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { return !__root_name().empty(); } + _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { return !__root_directory().empty(); } + _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { return !(__root_name().empty() && __root_directory().empty()); } + _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { return !__relative_path().empty(); } + _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { return !__parent_path().empty(); } + _LIBCPP_INLINE_VISIBILITY bool has_filename() const { return !__filename().empty(); } + _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); } + _LIBCPP_INLINE_VISIBILITY bool has_extension() const { return !__extension().empty(); } + + _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { return has_root_directory(); } + _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); } + + // iterators + class _LIBCPP_TYPE_VIS iterator; + typedef iterator const_iterator; + + _LIBCPP_FUNC_VIS iterator begin() const; + _LIBCPP_FUNC_VIS iterator end() const; + +private: + inline _LIBCPP_INLINE_VISIBILITY + path& __assign_view(string_view const& __s) noexcept { __pn_ = __s.to_string(); return *this; } + string_type __pn_; +}; + +inline _LIBCPP_ALWAYS_INLINE +void swap(path& __lhs, path& __rhs) _NOEXCEPT { + __lhs.swap(__rhs); +} + +_LIBCPP_FUNC_VIS +size_t hash_value(const path& __p) _NOEXCEPT; + +inline _LIBCPP_INLINE_VISIBILITY +bool operator==(const path& __lhs, const path& __rhs) _NOEXCEPT +{ return __lhs.compare(__rhs) == 0; } + +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(const path& __lhs, const path& __rhs) _NOEXCEPT +{ return __lhs.compare(__rhs) != 0; } + +inline _LIBCPP_INLINE_VISIBILITY +bool operator<(const path& __lhs, const path& __rhs) _NOEXCEPT +{ return __lhs.compare(__rhs) < 0; } + +inline _LIBCPP_INLINE_VISIBILITY +bool operator<=(const path& __lhs, const path& __rhs) _NOEXCEPT +{ return __lhs.compare(__rhs) <= 0; } + +inline _LIBCPP_INLINE_VISIBILITY +bool operator>(const path& __lhs, const path& __rhs) _NOEXCEPT +{ return __lhs.compare(__rhs) > 0; } + +inline _LIBCPP_INLINE_VISIBILITY +bool operator>=(const path& __lhs, const path& __rhs) _NOEXCEPT +{ return __lhs.compare(__rhs) >= 0; } + +inline _LIBCPP_INLINE_VISIBILITY +path operator/(const path& __lhs, const path& __rhs) { + return path(__lhs) /= __rhs; +} + +template <class _CharT, class _Traits> +_LIBCPP_INLINE_VISIBILITY +typename enable_if<is_same<_CharT, char>::value && + is_same<_Traits, char_traits<char>>::value, + basic_ostream<_CharT, _Traits>& +>::type +operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << std::__quoted(__p.native()); + return __os; +} + +template <class _CharT, class _Traits> +_LIBCPP_INLINE_VISIBILITY +typename enable_if<!is_same<_CharT, char>::value || + !is_same<_Traits, char_traits<char>>::value, + basic_ostream<_CharT, _Traits>& +>::type +operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << std::__quoted(__p.string<_CharT, _Traits>()); + return __os; +} + +template <class _CharT, class _Traits> +_LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) +{ + basic_string<_CharT, _Traits> __tmp; + __is >> __quoted(__tmp); + __p = __tmp; + return __is; +} + +template <class _Source> +_LIBCPP_INLINE_VISIBILITY +typename enable_if<__is_pathable<_Source>::value, path>::type +u8path(const _Source& __s){ + static_assert(is_same<typename __is_pathable<_Source>::__char_type, char>::value, + "u8path(Source const&) requires Source have a character type of type 'char'"); + return path(__s); +} + +template <class _InputIt> +_LIBCPP_INLINE_VISIBILITY +typename enable_if<__is_pathable<_InputIt>::value, path>::type +u8path(_InputIt __f, _InputIt __l) { + static_assert(is_same<typename __is_pathable<_InputIt>::__char_type, char>::value, + "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"); + return path(__f, __l); +} + +class _LIBCPP_TYPE_VIS path::iterator +{ +public: + typedef bidirectional_iterator_tag iterator_category; + typedef path value_type; + typedef std::ptrdiff_t difference_type; + typedef const path* pointer; + typedef const path& reference; +public: + _LIBCPP_INLINE_VISIBILITY + iterator() : __elem_(), __path_ptr_(nullptr), __pos_(0) {} + + iterator(const iterator&) = default; + ~iterator() = default; + + iterator& operator=(const iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { + return __elem_; + } + + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { + return &__elem_; + } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator++() { + return __increment(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator++(int) { + iterator __it(*this); + this->operator++(); + return __it; + } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator--() { + return __decrement(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator--(int) { + iterator __it(*this); + this->operator--(); + return __it; + } + +private: + friend class path; + friend bool operator==(const iterator&, const iterator&); + + _LIBCPP_FUNC_VIS iterator& __increment(); + _LIBCPP_FUNC_VIS iterator& __decrement(); + + path __elem_; + const path* __path_ptr_; + size_t __pos_; +}; + +inline _LIBCPP_INLINE_VISIBILITY +bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) { + return __lhs.__path_ptr_ == __rhs.__path_ptr_ && + __lhs.__pos_ == __rhs.__pos_; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) { + return !(__lhs == __rhs); +} + +class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error +{ +public: + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, error_code __ec) + : system_error(__ec, __what), + __paths_(make_shared<_Storage>(path(), path())) + {} + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, error_code __ec) + : system_error(__ec, __what), + __paths_(make_shared<_Storage>(__p1, path())) + {} + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, const path& __p2, + error_code __ec) + : system_error(__ec, __what), + __paths_(make_shared<_Storage>(__p1, __p2)) + {} + + _LIBCPP_INLINE_VISIBILITY + const path& path1() const _NOEXCEPT { + return __paths_->first; + } + + _LIBCPP_INLINE_VISIBILITY + const path& path2() const _NOEXCEPT { + return __paths_->second; + } + + _LIBCPP_FUNC_VIS + ~filesystem_error() override; // key function + + // TODO(ericwf): Create a custom error message. + //const char* what() const _NOEXCEPT; + +private: + typedef pair<path, path> _Storage; + shared_ptr<_Storage> __paths_; +}; + +// operational functions + +_LIBCPP_FUNC_VIS +path __canonical(const path&, const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +void __copy(const path& __from, const path& __to, copy_options __opt, + error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +bool __copy_file(const path& __from, const path& __to, copy_options __opt, + error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, + error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +bool __create_directories(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +bool __create_directory(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +bool __create_directory(const path& p, const path & attributes, + error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +void __create_directory_symlink(const path& __to, const path& __new_symlink, + error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +void __create_hard_link(const path& __to, const path& __new_hard_link, + error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +void __create_symlink(const path& __to, const path& __new_symlink, + error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +path __current_path(error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +void __current_path(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +bool __equivalent(const path&, const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +uintmax_t __file_size(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +uintmax_t __hard_link_count(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +bool __fs_is_empty(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +file_time_type __last_write_time(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +void __last_write_time(const path& p, file_time_type new_time, + error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +void __permissions(const path& p, perms prms, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +path __read_symlink(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +bool __remove(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +uintmax_t __remove_all(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +void __rename(const path& from, const path& to, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +void __resize_file(const path& p, uintmax_t size, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +space_info __space(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +file_status __status(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +file_status __symlink_status(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +path __system_complete(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +path __temp_directory_path(error_code *__ec=nullptr); + +inline _LIBCPP_INLINE_VISIBILITY +path current_path() { + return __current_path(); +} + +inline _LIBCPP_INLINE_VISIBILITY +path current_path(error_code& __ec) { + return __current_path(&__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void current_path(const path& __p) { + __current_path(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +void current_path(const path& __p, error_code& __ec) _NOEXCEPT { + __current_path(__p, &__ec); +} + +_LIBCPP_FUNC_VIS +path absolute(const path&, const path& __p2 = current_path()); + +inline _LIBCPP_INLINE_VISIBILITY +path canonical(const path& __p, const path& __base = current_path()) { + return __canonical(__p, __base); +} + +inline _LIBCPP_INLINE_VISIBILITY +path canonical(const path& __p, error_code& __ec) { + path __base = __current_path(&__ec); + if (__ec) return {}; + return __canonical(__p, __base, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +path canonical(const path& __p, const path& __base, error_code& __ec) { + return __canonical(__p, __base, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void copy(const path& __from, const path& __to) { + __copy(__from, __to, copy_options::none); +} + +inline _LIBCPP_INLINE_VISIBILITY +void copy(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT { + __copy(__from, __to, copy_options::none, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void copy(const path& __from, const path& __to, copy_options __opt) { + __copy(__from, __to, __opt); +} + +inline _LIBCPP_INLINE_VISIBILITY +void copy(const path& __from, const path& __to, + copy_options __opt, error_code& __ec) _NOEXCEPT { + __copy(__from, __to, __opt, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool copy_file(const path& __from, const path& __to) { + return __copy_file(__from, __to, copy_options::none); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool copy_file(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT { + return __copy_file(__from, __to, copy_options::none, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool copy_file(const path& __from, const path& __to, copy_options __opt) { + return __copy_file(__from, __to, __opt); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool copy_file(const path& __from, const path& __to, + copy_options __opt, error_code& __ec) _NOEXCEPT { + return __copy_file(__from, __to, __opt, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void copy_symlink(const path& __existing, const path& __new) { + __copy_symlink(__existing, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY +void copy_symlink(const path& __ext, const path& __new, error_code& __ec) _NOEXCEPT { + __copy_symlink(__ext, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool create_directories(const path& __p) { + return __create_directories(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool create_directories(const path& __p, error_code& __ec) _NOEXCEPT { + return __create_directories(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool create_directory(const path& __p) { + return __create_directory(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool create_directory(const path& __p, error_code& __ec) _NOEXCEPT { + return __create_directory(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool create_directory(const path& __p, const path& __attrs) { + return __create_directory(__p, __attrs); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool create_directory(const path& __p, const path& __attrs, error_code& __ec) _NOEXCEPT { + return __create_directory(__p, __attrs, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void create_directory_symlink(const path& __to, const path& __new) { + __create_directory_symlink(__to, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY +void create_directory_symlink(const path& __to, const path& __new, + error_code& __ec) _NOEXCEPT { + __create_directory_symlink(__to, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void create_hard_link(const path& __to, const path& __new) { + __create_hard_link(__to, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY +void create_hard_link(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT { + __create_hard_link(__to, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void create_symlink(const path& __to, const path& __new) { + __create_symlink(__to, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY +void create_symlink(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT { + return __create_symlink(__to, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool status_known(file_status __s) _NOEXCEPT { + return __s.type() != file_type::none; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool exists(file_status __s) _NOEXCEPT { + return status_known(__s) && __s.type() != file_type::not_found; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool exists(const path& __p) { + return exists(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool exists(const path& __p, error_code& __ec) _NOEXCEPT { + auto __s = __status(__p, &__ec); + if (status_known(__s)) __ec.clear(); + return exists(__s); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool equivalent(const path& __p1, const path& __p2) { + return __equivalent(__p1, __p2); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool equivalent(const path& __p1, const path& __p2, error_code& __ec) _NOEXCEPT { + return __equivalent(__p1, __p2, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +uintmax_t file_size(const path& __p) { + return __file_size(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +uintmax_t file_size(const path& __p, error_code& __ec) _NOEXCEPT { + return __file_size(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +uintmax_t hard_link_count(const path& __p) { + return __hard_link_count(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +uintmax_t hard_link_count(const path& __p, error_code& __ec) _NOEXCEPT { + return __hard_link_count(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_block_file(file_status __s) _NOEXCEPT { + return __s.type() == file_type::block; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_block_file(const path& __p) { + return is_block_file(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_block_file(const path& __p, error_code& __ec) _NOEXCEPT { + return is_block_file(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_character_file(file_status __s) _NOEXCEPT { + return __s.type() == file_type::character; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_character_file(const path& __p) { + return is_character_file(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_character_file(const path& __p, error_code& __ec) _NOEXCEPT { + return is_character_file(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_directory(file_status __s) _NOEXCEPT { + return __s.type() == file_type::directory; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_directory(const path& __p) { + return is_directory(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_directory(const path& __p, error_code& __ec) _NOEXCEPT { + return is_directory(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_empty(const path& __p) { + return __fs_is_empty(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_empty(const path& __p, error_code& __ec) _NOEXCEPT { + return __fs_is_empty(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_fifo(file_status __s) _NOEXCEPT { + return __s.type() == file_type::fifo; +} +inline _LIBCPP_INLINE_VISIBILITY +bool is_fifo(const path& __p) { + return is_fifo(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_fifo(const path& __p, error_code& __ec) _NOEXCEPT { + return is_fifo(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_regular_file(file_status __s) _NOEXCEPT { + return __s.type() == file_type::regular; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_regular_file(const path& __p) { + return is_regular_file(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_regular_file(const path& __p, error_code& __ec) _NOEXCEPT { + return is_regular_file(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_socket(file_status __s) _NOEXCEPT { + return __s.type() == file_type::socket; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_socket(const path& __p) { + return is_socket(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_socket(const path& __p, error_code& __ec) _NOEXCEPT { + return is_socket(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_symlink(file_status __s) _NOEXCEPT { + return __s.type() == file_type::symlink; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_symlink(const path& __p) { + return is_symlink(__symlink_status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_symlink(const path& __p, error_code& __ec) _NOEXCEPT { + return is_symlink(__symlink_status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_other(file_status __s) _NOEXCEPT { + return exists(__s) + && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_other(const path& __p) { + return is_other(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_other(const path& __p, error_code& __ec) _NOEXCEPT { + return is_other(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +file_time_type last_write_time(const path& __p) { + return __last_write_time(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +file_time_type last_write_time(const path& __p, error_code& __ec) _NOEXCEPT { + return __last_write_time(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void last_write_time(const path& __p, file_time_type __t) { + __last_write_time(__p, __t); +} + +inline _LIBCPP_INLINE_VISIBILITY +void last_write_time(const path& __p, file_time_type __t, error_code& __ec) _NOEXCEPT { + __last_write_time(__p, __t, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void permissions(const path& __p, perms __prms) { + __permissions(__p, __prms); +} + +inline _LIBCPP_INLINE_VISIBILITY +void permissions(const path& __p, perms __prms, error_code& __ec) { + __permissions(__p, __prms, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +path read_symlink(const path& __p) { + return __read_symlink(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +path read_symlink(const path& __p, error_code& __ec) { + return __read_symlink(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool remove(const path& __p) { + return __remove(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool remove(const path& __p, error_code& __ec) _NOEXCEPT { + return __remove(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +uintmax_t remove_all(const path& __p) { + return __remove_all(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +uintmax_t remove_all(const path& __p, error_code& __ec) _NOEXCEPT { + return __remove_all(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void rename(const path& __from, const path& __to) { + return __rename(__from, __to); +} + +inline _LIBCPP_INLINE_VISIBILITY +void rename(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT { + return __rename(__from, __to, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void resize_file(const path& __p, uintmax_t __ns) { + return __resize_file(__p, __ns); +} + +inline _LIBCPP_INLINE_VISIBILITY +void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) _NOEXCEPT { + return __resize_file(__p, __ns, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +space_info space(const path& __p) { + return __space(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +space_info space(const path& __p, error_code& __ec) _NOEXCEPT { + return __space(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +file_status status(const path& __p) { + return __status(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +file_status status(const path& __p, error_code& __ec) _NOEXCEPT { + return __status(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +file_status symlink_status(const path& __p) { + return __symlink_status(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +file_status symlink_status(const path& __p, error_code& __ec) _NOEXCEPT { + return __symlink_status(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +path system_complete(const path& __p) { + return __system_complete(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +path system_complete(const path& __p, error_code& __ec) { + return __system_complete(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +path temp_directory_path() { + return __temp_directory_path(); +} + +inline _LIBCPP_INLINE_VISIBILITY +path temp_directory_path(error_code& __ec) { + return __temp_directory_path(&__ec); +} + + +class directory_entry +{ + typedef _VSTD_FS::path _Path; + +public: + // constructors and destructors + directory_entry() _NOEXCEPT = default; + directory_entry(directory_entry const&) = default; + directory_entry(directory_entry&&) _NOEXCEPT = default; + + _LIBCPP_INLINE_VISIBILITY + explicit directory_entry(_Path const& __p) : __p_(__p) {} + + ~directory_entry() {} + + directory_entry& operator=(directory_entry const&) = default; + directory_entry& operator=(directory_entry&&) _NOEXCEPT = default; + + _LIBCPP_INLINE_VISIBILITY + void assign(_Path const& __p) { + __p_ = __p; + } + + _LIBCPP_INLINE_VISIBILITY + void replace_filename(_Path const& __p) { + __p_ = __p_.parent_path() / __p; + } + + _LIBCPP_INLINE_VISIBILITY + _Path const& path() const _NOEXCEPT { + return __p_; + } + + _LIBCPP_INLINE_VISIBILITY + operator const _Path&() const _NOEXCEPT { + return __p_; + } + + _LIBCPP_INLINE_VISIBILITY + file_status status() const { + return _VSTD_FS::status(__p_); + } + + _LIBCPP_INLINE_VISIBILITY + file_status status(error_code& __ec) const _NOEXCEPT { + return _VSTD_FS::status(__p_, __ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status() const { + return _VSTD_FS::symlink_status(__p_); + } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status(error_code& __ec) const _NOEXCEPT { + return _VSTD_FS::symlink_status(__p_, __ec); + } + + _LIBCPP_INLINE_VISIBILITY + bool operator< (directory_entry const& __rhs) const _NOEXCEPT { + return __p_ < __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator==(directory_entry const& __rhs) const _NOEXCEPT { + return __p_ == __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator!=(directory_entry const& __rhs) const _NOEXCEPT { + return __p_ != __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator<=(directory_entry const& __rhs) const _NOEXCEPT { + return __p_ <= __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator> (directory_entry const& __rhs) const _NOEXCEPT { + return __p_ > __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator>=(directory_entry const& __rhs) const _NOEXCEPT { + return __p_ >= __rhs.__p_; + } +private: + _Path __p_; +}; + + +class directory_iterator; +class recursive_directory_iterator; +class __dir_stream; + +class __dir_element_proxy { +public: + + inline _LIBCPP_INLINE_VISIBILITY + directory_entry operator*() { return _VSTD::move(__elem_); } + +private: + friend class directory_iterator; + friend class recursive_directory_iterator; + explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} + __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(_VSTD::move(__o.__elem_)) {} + directory_entry __elem_; +}; + +class directory_iterator +{ +public: + typedef directory_entry value_type; + typedef ptrdiff_t difference_type; + typedef value_type const* pointer; + typedef value_type const& reference; + typedef input_iterator_tag iterator_category; + +public: + //ctor & dtor + directory_iterator() _NOEXCEPT + { } + + explicit directory_iterator(const path& __p) + : directory_iterator(__p, nullptr) + { } + + directory_iterator(const path& __p, directory_options __opts) + : directory_iterator(__p, nullptr, __opts) + { } + + directory_iterator(const path& __p, error_code& __ec) _NOEXCEPT + : directory_iterator(__p, &__ec) + { } + + directory_iterator(const path& __p, directory_options __opts, + error_code& __ec) _NOEXCEPT + : directory_iterator(__p, &__ec, __opts) + { } + + directory_iterator(const directory_iterator&) = default; + directory_iterator(directory_iterator&&) = default; + directory_iterator& operator=(const directory_iterator&) = default; + + directory_iterator& operator=(directory_iterator&& __o) _NOEXCEPT { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + } + return *this; + } + + ~directory_iterator() = default; + + const directory_entry& operator*() const { + _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); + return __deref(); + } + + const directory_entry* operator->() const + { return &**this; } + + directory_iterator& operator++() + { return __increment(); } + + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + directory_iterator& increment(error_code& __ec) _NOEXCEPT + { return __increment(&__ec); } + +private: + friend bool operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) _NOEXCEPT; + + // construct the dir_stream + _LIBCPP_FUNC_VIS + directory_iterator(const path&, error_code *, directory_options = directory_options::none); + _LIBCPP_FUNC_VIS + directory_iterator& __increment(error_code * __ec = nullptr); + _LIBCPP_FUNC_VIS + const directory_entry& __deref() const; + +private: + shared_ptr<__dir_stream> __imp_; +}; + + +inline _LIBCPP_INLINE_VISIBILITY +bool operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) _NOEXCEPT { + return __lhs.__imp_ == __rhs.__imp_; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(const directory_iterator& __lhs, + const directory_iterator& __rhs) _NOEXCEPT { + return !(__lhs == __rhs); +} + +// enable directory_iterator range-based for statements +inline _LIBCPP_INLINE_VISIBILITY +directory_iterator begin(directory_iterator __iter) _NOEXCEPT { + return __iter; +} + +inline _LIBCPP_INLINE_VISIBILITY +directory_iterator end(const directory_iterator&) _NOEXCEPT { + return directory_iterator(); +} + +class recursive_directory_iterator { +public: + using value_type = directory_entry; + using difference_type = std::ptrdiff_t; + using pointer = directory_entry const *; + using reference = directory_entry const &; + using iterator_category = std::input_iterator_tag; + +public: + // constructors and destructor + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator() _NOEXCEPT + : __rec_(false) + {} + + _LIBCPP_INLINE_VISIBILITY + explicit recursive_directory_iterator(const path& __p, + directory_options __xoptions = directory_options::none) + : recursive_directory_iterator(__p, __xoptions, nullptr) + { } + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, + directory_options __xoptions, error_code& __ec) _NOEXCEPT + : recursive_directory_iterator(__p, __xoptions, &__ec) + { } + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, error_code& __ec) _NOEXCEPT + : recursive_directory_iterator(__p, directory_options::none, &__ec) + { } + + recursive_directory_iterator(const recursive_directory_iterator&) = default; + recursive_directory_iterator(recursive_directory_iterator&&) = default; + + recursive_directory_iterator & + operator=(const recursive_directory_iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator & + operator=(recursive_directory_iterator&& __o) noexcept { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + __rec_ = __o.__rec_; + } + return *this; + } + + ~recursive_directory_iterator() = default; + + _LIBCPP_INLINE_VISIBILITY + const directory_entry& operator*() const + { return __deref(); } + + _LIBCPP_INLINE_VISIBILITY + const directory_entry* operator->() const + { return &__deref(); } + + recursive_directory_iterator& operator++() + { return __increment(); } + + _LIBCPP_INLINE_VISIBILITY + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator& increment(error_code& __ec) _NOEXCEPT + { return __increment(&__ec); } + + _LIBCPP_FUNC_VIS directory_options options() const; + _LIBCPP_FUNC_VIS int depth() const; + + _LIBCPP_INLINE_VISIBILITY + void pop() { __pop(); } + + _LIBCPP_INLINE_VISIBILITY + void pop(error_code& __ec) + { __pop(&__ec); } + + _LIBCPP_INLINE_VISIBILITY + bool recursion_pending() const + { return __rec_; } + + _LIBCPP_INLINE_VISIBILITY + void disable_recursion_pending() + { __rec_ = false; } + +private: + recursive_directory_iterator(const path& __p, directory_options __opt, + error_code *__ec); + + _LIBCPP_FUNC_VIS + const directory_entry& __deref() const; + + _LIBCPP_FUNC_VIS + bool __try_recursion(error_code* __ec); + + _LIBCPP_FUNC_VIS + void __advance(error_code* __ec=nullptr); + + _LIBCPP_FUNC_VIS + recursive_directory_iterator& __increment(error_code *__ec=nullptr); + + _LIBCPP_FUNC_VIS + void __pop(error_code* __ec=nullptr); + + friend bool operator==(const recursive_directory_iterator&, + const recursive_directory_iterator&) _NOEXCEPT; + + struct __shared_imp; + shared_ptr<__shared_imp> __imp_; + bool __rec_; +}; // class recursive_directory_iterator + + +_LIBCPP_INLINE_VISIBILITY +inline bool operator==(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) _NOEXCEPT +{ + return __lhs.__imp_ == __rhs.__imp_; +} + +_LIBCPP_INLINE_VISIBILITY +inline bool operator!=(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) _NOEXCEPT +{ + return !(__lhs == __rhs); +} +// enable recursive_directory_iterator range-based for statements +inline _LIBCPP_INLINE_VISIBILITY +recursive_directory_iterator begin(recursive_directory_iterator __iter) _NOEXCEPT { + return __iter; +} + +inline _LIBCPP_INLINE_VISIBILITY +recursive_directory_iterator end(const recursive_directory_iterator&) _NOEXCEPT { + return recursive_directory_iterator(); +} + +_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM + +#endif // _LIBCPP_EXPERIMENTAL_FILESYSTEM diff --git a/include/experimental/forward_list b/include/experimental/forward_list new file mode 100644 index 0000000000000..55e195f446f55 --- /dev/null +++ b/include/experimental/forward_list @@ -0,0 +1,47 @@ +// -*- C++ -*- +//===--------------------------- forward_list -----------------------------===// +// +// 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_FORWARD_LIST +#define _LIBCPP_EXPERIMENTAL_FORWARD_LIST +/* + experimental/forward_list synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class T> + using forward_list = std::forward_list<T,polymorphic_allocator<T>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <forward_list> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _ValueT> +using forward_list = _VSTD::forward_list<_ValueT, polymorphic_allocator<_ValueT>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_FORWARD_LIST */ diff --git a/include/experimental/functional b/include/experimental/functional index c7a78695b8091..75fc8e99f3529 100644 --- a/include/experimental/functional +++ b/include/experimental/functional @@ -119,9 +119,12 @@ public: template <typename _ForwardIterator2> _LIBCPP_INLINE_VISIBILITY - _ForwardIterator2 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const + pair<_ForwardIterator2, _ForwardIterator2> + operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const { - return _VSTD::search(__f, __l, __first_, __last_, __pred_); + return _VSTD::__search(__f, __l, __first_, __last_, __pred_, + typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category(), + typename _VSTD::iterator_traits<_ForwardIterator2>::iterator_category()); } private: @@ -233,7 +236,7 @@ public: } template <typename _RandomAccessIterator2> - _RandomAccessIterator2 + pair<_RandomAccessIterator2, _RandomAccessIterator2> operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { static_assert ( std::is_same< @@ -242,12 +245,12 @@ public: >::value, "Corpus and Pattern iterators must point to the same type" ); - if (__f == __l ) return __l; // empty corpus - if (__first_ == __last_) return __f; // empty pattern + if (__f == __l ) return make_pair(__l, __l); // empty corpus + if (__first_ == __last_) return make_pair(__f, __f); // empty pattern // If the pattern is larger than the corpus, we can't find it! if ( __pattern_length_ > _VSTD::distance (__f, __l)) - return __l; + return make_pair(__l, __l); // Do the search return this->__search(__f, __l); @@ -262,7 +265,8 @@ public: // TODO private: shared_ptr<vector<difference_type>> __suffix_; template <typename _RandomAccessIterator2> - _RandomAccessIterator2 __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const + pair<_RandomAccessIterator2, _RandomAccessIterator2> + __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { _RandomAccessIterator2 __cur = __f; const _RandomAccessIterator2 __last = __l - __pattern_length_; @@ -278,7 +282,7 @@ public: // TODO private: __j--; // We matched - we're done! if ( __j == 0 ) - return __cur; + return make_pair(__cur, __cur + __pattern_length_); } // Since we didn't match, figure out how far to skip forward @@ -290,7 +294,7 @@ public: // TODO private: __cur += __suffix[ __j ]; } - return __l; // We didn't find anything + return make_pair(__l, __l); // We didn't find anything } @@ -384,8 +388,8 @@ public: } } - template <typename _RandomAccessIterator2> - _RandomAccessIterator2 + template <typename _RandomAccessIterator2> + pair<_RandomAccessIterator2, _RandomAccessIterator2> operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { static_assert ( std::is_same< @@ -394,12 +398,12 @@ public: >::value, "Corpus and Pattern iterators must point to the same type" ); - if (__f == __l ) return __l; // empty corpus - if (__first_ == __last_) return __f; // empty pattern + if (__f == __l ) return make_pair(__l, __l); // empty corpus + if (__first_ == __last_) return make_pair(__f, __f); // empty pattern // If the pattern is larger than the corpus, we can't find it! if ( __pattern_length_ > _VSTD::distance (__f, __l)) - return __l; + return make_pair(__l, __l); // Do the search return this->__search(__f, __l); @@ -413,7 +417,8 @@ private: shared_ptr<skip_table_type> __skip_; template <typename _RandomAccessIterator2> - _RandomAccessIterator2 __search ( _RandomAccessIterator2 __f, _RandomAccessIterator2 __l ) const { + pair<_RandomAccessIterator2, _RandomAccessIterator2> + __search ( _RandomAccessIterator2 __f, _RandomAccessIterator2 __l ) const { _RandomAccessIterator2 __cur = __f; const _RandomAccessIterator2 __last = __l - __pattern_length_; const skip_table_type & __skip = *__skip_.get(); @@ -427,12 +432,12 @@ private: __j--; // We matched - we're done! if ( __j == 0 ) - return __cur; + return make_pair(__cur, __cur + __pattern_length_); } __cur += __skip[__cur[__pattern_length_-1]]; } - return __l; + return make_pair(__l, __l); } }; diff --git a/include/experimental/iterator b/include/experimental/iterator new file mode 100644 index 0000000000000..da593febe2b4f --- /dev/null +++ b/include/experimental/iterator @@ -0,0 +1,114 @@ +// -*- C++ -*- +//===----------------------------- iterator -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_ITERATOR +#define _LIBCPP_EXPERIMENTAL_ITERATOR + +/* +namespace std { + namespace experimental { + inline namespace fundamentals_v2 { + + template <class DelimT, class charT = char, class traits = char_traits<charT>> + class ostream_joiner { + public: + typedef charT char_type; + typedef traits traits_type; + typedef basic_ostream<charT, traits> ostream_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + ostream_joiner(ostream_type& s, const DelimT& delimiter); + ostream_joiner(ostream_type& s, DelimT&& delimiter); + + template<typename T> + ostream_joiner& operator=(const T& value); + + ostream_joiner& operator*() noexcept; + ostream_joiner& operator++() noexcept; + ostream_joiner& operator++(int) noexcept; + private: + ostream_type* out_stream; // exposition only + DelimT delim; // exposition only + bool first_element; // exposition only + }; + + template <class charT, class traits, class DelimT> + ostream_joiner<decay_t<DelimT>, charT, traits> + make_ostream_joiner(basic_ostream<charT, traits>& os, DelimT&& delimiter); + + } // inline namespace fundamentals_v2 + } // namespace experimental +} // namespace std + +*/ + +#include <experimental/__config> + +#if _LIBCPP_STD_VER > 11 + +#include <iterator> + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +class ostream_joiner { +public: + + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_ostream<char_type,traits_type> ostream_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + ostream_joiner(ostream_type& __os, _Delim&& __d) + : __out(_VSTD::addressof(__os)), __delim(_VSTD::move(__d)), __first(true) {} + + ostream_joiner(ostream_type& __os, const _Delim& __d) + : __out(_VSTD::addressof(__os)), __delim(__d), __first(true) {} + + + template<typename _Tp> + ostream_joiner& operator=(const _Tp& __v) + { + if (!__first) + *__out << __delim; + __first = false; + *__out << __v; + return *this; + } + + ostream_joiner& operator*() _NOEXCEPT { return *this; } + ostream_joiner& operator++() _NOEXCEPT { return *this; } + ostream_joiner& operator++(int) _NOEXCEPT { return *this; } + +private: + ostream_type* __out; + _Delim __delim; + bool __first; +}; + + +template <class _CharT, class _Traits, class _Delim> +ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits> +make_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d) +{ return ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); } + +_LIBCPP_END_NAMESPACE_LFTS + +#endif /* _LIBCPP_STD_VER > 11 */ + +#endif // _LIBCPP_EXPERIMENTAL_ITERATOR diff --git a/include/experimental/list b/include/experimental/list new file mode 100644 index 0000000000000..1678ee3e93cb3 --- /dev/null +++ b/include/experimental/list @@ -0,0 +1,47 @@ +// -*- C++ -*- +//===--------------------------- list ------------------------------------===// +// +// 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_LIST +#define _LIBCPP_EXPERIMENTAL_LIST +/* + experimental/list synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class T> + using list = std::list<T,polymorphic_allocator<T>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <list> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _ValueT> +using list = _VSTD::list<_ValueT, polymorphic_allocator<_ValueT>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_LIST */ diff --git a/include/experimental/map b/include/experimental/map new file mode 100644 index 0000000000000..cff2c5e52c0dc --- /dev/null +++ b/include/experimental/map @@ -0,0 +1,57 @@ +// -*- C++ -*- +//===----------------------------- map ------------------------------------===// +// +// 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_MAP +#define _LIBCPP_EXPERIMENTAL_MAP +/* + experimental/map synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class Key, class T, class Compare = less<Key>> + using map = std::map<Key, T, Compare, + polymorphic_allocator<pair<const Key,T>>>; + + template <class Key, class T, class Compare = less<Key>> + using multimap = std::multimap<Key, T, Compare, + polymorphic_allocator<pair<const Key,T>>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <map> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _Key, class _Value, class _Compare = less<_Key>> +using map = _VSTD::map<_Key, _Value, _Compare, + polymorphic_allocator<pair<const _Key, _Value>>>; + +template <class _Key, class _Value, class _Compare = less<_Key>> +using multimap = _VSTD::multimap<_Key, _Value, _Compare, + polymorphic_allocator<pair<const _Key, _Value>>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_MAP */ diff --git a/include/experimental/memory_resource b/include/experimental/memory_resource new file mode 100644 index 0000000000000..9b345210ee5e1 --- /dev/null +++ b/include/experimental/memory_resource @@ -0,0 +1,422 @@ +// -*- C++ -*- +//===------------------------ memory_resource -----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE +#define _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE + +/** + experimental/memory_resource synopsis + +// C++1y + +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + class memory_resource; + + bool operator==(const memory_resource& a, + const memory_resource& b) noexcept; + bool operator!=(const memory_resource& a, + const memory_resource& b) noexcept; + + template <class Tp> class polymorphic_allocator; + + template <class T1, class T2> + bool operator==(const polymorphic_allocator<T1>& a, + const polymorphic_allocator<T2>& b) noexcept; + template <class T1, class T2> + bool operator!=(const polymorphic_allocator<T1>& a, + const polymorphic_allocator<T2>& b) noexcept; + + // The name resource_adaptor_imp is for exposition only. + template <class Allocator> class resource_adaptor_imp; + + template <class Allocator> + using resource_adaptor = resource_adaptor_imp< + allocator_traits<Allocator>::rebind_alloc<char>>; + + // Global memory resources + memory_resource* new_delete_resource() noexcept; + memory_resource* null_memory_resource() noexcept; + + // The default memory resource + memory_resource* set_default_resource(memory_resource* r) noexcept; + memory_resource* get_default_resource() noexcept; + + // Standard memory resources + struct pool_options; + class synchronized_pool_resource; + class unsynchronized_pool_resource; + class monotonic_buffer_resource; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <experimental/__memory> +#include <limits> +#include <memory> +#include <new> +#include <stdexcept> +#include <tuple> +#include <type_traits> +#include <utility> +#include <cstddef> +#include <cstdlib> +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +// Round __s up to next multiple of __a. +inline _LIBCPP_INLINE_VISIBILITY +size_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT +{ + _LIBCPP_ASSERT(__s + __a > __s, "aligned allocation size overflows"); + return (__s + __a - 1) & ~(__a - 1); +} + +// 8.5, memory.resource +class _LIBCPP_TYPE_VIS_ONLY memory_resource +{ + static const size_t __max_align = alignof(max_align_t); + +// 8.5.2, memory.resource.public +public: + virtual ~memory_resource() = default; + + _LIBCPP_INLINE_VISIBILITY + void* allocate(size_t __bytes, size_t __align = __max_align) + { return do_allocate(__bytes, __align); } + + _LIBCPP_INLINE_VISIBILITY + void deallocate(void * __p, size_t __bytes, size_t __align = __max_align) + { do_deallocate(__p, __bytes, __align); } + + _LIBCPP_INLINE_VISIBILITY + bool is_equal(memory_resource const & __other) const _NOEXCEPT + { return do_is_equal(__other); } + +// 8.5.3, memory.resource.priv +protected: + virtual void* do_allocate(size_t, size_t) = 0; + virtual void do_deallocate(void*, size_t, size_t) = 0; + virtual bool do_is_equal(memory_resource const &) const _NOEXCEPT = 0; +}; + +// 8.5.4, memory.resource.eq +inline _LIBCPP_INLINE_VISIBILITY +bool operator==(memory_resource const & __lhs, + memory_resource const & __rhs) _NOEXCEPT +{ + return &__lhs == &__rhs || __lhs.is_equal(__rhs); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(memory_resource const & __lhs, + memory_resource const & __rhs) _NOEXCEPT +{ + return !(__lhs == __rhs); +} + +_LIBCPP_FUNC_VIS +memory_resource * new_delete_resource() _NOEXCEPT; + +_LIBCPP_FUNC_VIS +memory_resource * null_memory_resource() _NOEXCEPT; + +_LIBCPP_FUNC_VIS +memory_resource * get_default_resource() _NOEXCEPT; + +_LIBCPP_FUNC_VIS +memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT; + +// 8.6, memory.polymorphic.allocator.class + +// 8.6.1, memory.polymorphic.allocator.overview +template <class _ValueType> +class _LIBCPP_TYPE_VIS_ONLY polymorphic_allocator +{ +public: + typedef _ValueType value_type; + + // 8.6.2, memory.polymorphic.allocator.ctor + _LIBCPP_INLINE_VISIBILITY + polymorphic_allocator() _NOEXCEPT + : __res_(_VSTD_LFTS_PMR::get_default_resource()) + {} + + _LIBCPP_INLINE_VISIBILITY + polymorphic_allocator(memory_resource * __r) _NOEXCEPT + : __res_(__r) + {} + + polymorphic_allocator(polymorphic_allocator const &) = default; + + template <class _Tp> + _LIBCPP_INLINE_VISIBILITY + polymorphic_allocator(polymorphic_allocator<_Tp> const & __other) _NOEXCEPT + : __res_(__other.resource()) + {} + + polymorphic_allocator & + operator=(polymorphic_allocator const &) = delete; + + // 8.6.3, memory.polymorphic.allocator.mem + _LIBCPP_INLINE_VISIBILITY + _ValueType* allocate(size_t __n) { + if (__n > max_size()) { + __libcpp_throw(length_error( + "std::experimental::pmr::polymorphic_allocator<T>::allocate(size_t n)" + " 'n' exceeds maximum supported size")); + } + return static_cast<_ValueType*>( + __res_->allocate(__n * sizeof(_ValueType), alignof(_ValueType)) + ); + } + + _LIBCPP_INLINE_VISIBILITY + void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT { + _LIBCPP_ASSERT(__n <= max_size(), + "deallocate called for size which exceeds max_size()"); + __res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType)); + } + + template <class _Tp, class ..._Ts> + _LIBCPP_INLINE_VISIBILITY + void construct(_Tp* __p, _Ts &&... __args) + { + _VSTD_LFTS::__lfts_user_alloc_construct( + __p, resource(), _VSTD::forward<_Ts>(__args)... + ); + } + + template <class _T1, class _T2, class ..._Args1, class ..._Args2> + _LIBCPP_INLINE_VISIBILITY + void construct(pair<_T1, _T2>* __p, piecewise_construct_t, + tuple<_Args1...> __x, tuple<_Args2...> __y) + { + ::new ((void*)__p) pair<_T1, _T2>(piecewise_construct + , __transform_tuple( + typename __lfts_uses_alloc_ctor< + _T1, memory_resource*, _Args1... + >::type() + , _VSTD::move(__x) + , typename __make_tuple_indices<sizeof...(_Args1)>::type{} + ) + , __transform_tuple( + typename __lfts_uses_alloc_ctor< + _T2, memory_resource*, _Args2... + >::type() + , _VSTD::move(__y) + , typename __make_tuple_indices<sizeof...(_Args2)>::type{} + ) + ); + } + + template <class _T1, class _T2> + _LIBCPP_INLINE_VISIBILITY + void construct(pair<_T1, _T2>* __p) { + construct(__p, piecewise_construct, tuple<>(), tuple<>()); + } + + template <class _T1, class _T2, class _Up, class _Vp> + _LIBCPP_INLINE_VISIBILITY + void construct(pair<_T1, _T2> * __p, _Up && __u, _Vp && __v) { + construct(__p, piecewise_construct + , _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__u)) + , _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__v))); + } + + template <class _T1, class _T2, class _U1, class _U2> + _LIBCPP_INLINE_VISIBILITY + void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> const & __pr) { + construct(__p, piecewise_construct + , _VSTD::forward_as_tuple(__pr.first) + , _VSTD::forward_as_tuple(__pr.second)); + } + + template <class _T1, class _T2, class _U1, class _U2> + _LIBCPP_INLINE_VISIBILITY + void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> && __pr){ + construct(__p, piecewise_construct + , _VSTD::forward_as_tuple(_VSTD::forward<_U1>(__pr.first)) + , _VSTD::forward_as_tuple(_VSTD::forward<_U2>(__pr.second))); + } + + template <class _Tp> + _LIBCPP_INLINE_VISIBILITY + void destroy(_Tp * __p) _NOEXCEPT + { __p->~_Tp(); } + + _LIBCPP_INLINE_VISIBILITY + size_t max_size() const _NOEXCEPT + { return numeric_limits<size_t>::max() / sizeof(value_type); } + + _LIBCPP_INLINE_VISIBILITY + polymorphic_allocator + select_on_container_copy_construction() const _NOEXCEPT + { return polymorphic_allocator(); } + + _LIBCPP_INLINE_VISIBILITY + memory_resource * resource() const _NOEXCEPT + { return __res_; } + +private: + template <class ..._Args, size_t ..._Idx> + _LIBCPP_INLINE_VISIBILITY + tuple<_Args&&...> + __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, + __tuple_indices<_Idx...>) const + { + return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...); + } + + template <class ..._Args, size_t ..._Idx> + _LIBCPP_INLINE_VISIBILITY + tuple<allocator_arg_t const&, memory_resource*, _Args&&...> + __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t, + __tuple_indices<_Idx...>) const + { + using _Tup = tuple<allocator_arg_t const&, memory_resource*, _Args&&...>; + return _Tup(allocator_arg, resource(), + _VSTD::get<_Idx>(_VSTD::move(__t))...); + } + + template <class ..._Args, size_t ..._Idx> + _LIBCPP_INLINE_VISIBILITY + tuple<_Args&&..., memory_resource*> + __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t, + __tuple_indices<_Idx...>) const + { + using _Tup = tuple<_Args&&..., memory_resource*>; + return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., resource()); + } + + memory_resource * __res_; +}; + +// 8.6.4, memory.polymorphic.allocator.eq + +template <class _Tp, class _Up> +inline _LIBCPP_INLINE_VISIBILITY +bool operator==(polymorphic_allocator<_Tp> const & __lhs, + polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT +{ + return *__lhs.resource() == *__rhs.resource(); +} + +template <class _Tp, class _Up> +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(polymorphic_allocator<_Tp> const & __lhs, + polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT +{ + return !(__lhs == __rhs); +} + +// 8.7, memory.resource.adaptor + +// 8.7.1, memory.resource.adaptor.overview +template <class _CharAlloc> +class _LIBCPP_TYPE_VIS_ONLY __resource_adaptor_imp + : public memory_resource +{ + using _CTraits = allocator_traits<_CharAlloc>; + static_assert(is_same<typename _CTraits::value_type, char>::value + && is_same<typename _CTraits::pointer, char*>::value + && is_same<typename _CTraits::void_pointer, void*>::value, ""); + + static const size_t _MaxAlign = alignof(max_align_t); + + using _Alloc = typename _CTraits::template rebind_alloc< + typename aligned_storage<_MaxAlign, _MaxAlign>::type + >; + + using _ValueType = typename _Alloc::value_type; + + _Alloc __alloc_; + +public: + typedef _CharAlloc allocator_type; + + __resource_adaptor_imp() = default; + __resource_adaptor_imp(__resource_adaptor_imp const &) = default; + __resource_adaptor_imp(__resource_adaptor_imp &&) = default; + + // 8.7.2, memory.resource.adaptor.ctor + + _LIBCPP_INLINE_VISIBILITY + explicit __resource_adaptor_imp(allocator_type const & __a) + : __alloc_(__a) + {} + + _LIBCPP_INLINE_VISIBILITY + explicit __resource_adaptor_imp(allocator_type && __a) + : __alloc_(_VSTD::move(__a)) + {} + + __resource_adaptor_imp & + operator=(__resource_adaptor_imp const &) = default; + + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const + { return __alloc_; } + +// 8.7.3, memory.resource.adaptor.mem +protected: + virtual void * do_allocate(size_t __bytes, size_t) + { + if (__bytes > __max_size()) { + __libcpp_throw(length_error( + "std::experimental::pmr::resource_adaptor<T>::do_allocate(size_t bytes, size_t align)" + " 'bytes' exceeds maximum supported size")); + } + size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign; + return __alloc_.allocate(__s); + } + + virtual void do_deallocate(void * __p, size_t __bytes, size_t) + { + _LIBCPP_ASSERT(__bytes <= __max_size(), + "do_deallocate called for size which exceeds the maximum allocation size"); + size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign; + __alloc_.deallocate((_ValueType*)__p, __s); + } + + virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT { + __resource_adaptor_imp const * __p + = dynamic_cast<__resource_adaptor_imp const *>(&__other); + return __p ? __alloc_ == __p->__alloc_ : false; + } + +private: + _LIBCPP_INLINE_VISIBILITY + size_t __max_size() const _NOEXCEPT { + return numeric_limits<size_t>::max() - _MaxAlign; + } +}; + +template <class _Alloc> +using resource_adaptor = __resource_adaptor_imp< + typename allocator_traits<_Alloc>::template rebind_alloc<char> + >; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE */ diff --git a/include/experimental/optional b/include/experimental/optional index a384882a1e129..3912438ec1041 100644 --- a/include/experimental/optional +++ b/include/experimental/optional @@ -517,7 +517,11 @@ public: constexpr value_type const& value() const { if (!this->__engaged_) +#ifndef _LIBCPP_NO_EXCEPTIONS throw bad_optional_access(); +#else + assert(!"bad optional access"); +#endif return this->__val_; } @@ -525,7 +529,11 @@ public: value_type& value() { if (!this->__engaged_) +#ifndef _LIBCPP_NO_EXCEPTIONS throw bad_optional_access(); +#else + assert(!"bad optional access"); +#endif return this->__val_; } diff --git a/include/experimental/propagate_const b/include/experimental/propagate_const new file mode 100644 index 0000000000000..f267ba275c2f5 --- /dev/null +++ b/include/experimental/propagate_const @@ -0,0 +1,576 @@ +// -*- C++ -*- +//===------------------------ propagate_const -----------------------------===// +// +// 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_PROPAGATE_CONST +#define _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST +/* + propagate_const synopsis + + namespace std { namespace experimental { inline namespace fundamentals_v2 { + + // [propagate_const] + template <class T> class propagate_const; + + // [propagate_const.underlying], underlying pointer access + constexpr const _Tp& _VSTD_LFTS_V2::get_underlying(const propagate_const<T>& pt) noexcept; + constexpr T& _VSTD_LFTS_V2::get_underlying(propagate_const<T>& pt) noexcept; + + // [propagate_const.relational], relational operators + template <class T> constexpr bool operator==(const propagate_const<T>& pt, nullptr_t); + template <class T> constexpr bool operator==(nullptr_t, const propagate_const<T>& pu); + template <class T> constexpr bool operator!=(const propagate_const<T>& pt, nullptr_t); + template <class T> constexpr bool operator!=(nullptr_t, const propagate_const<T>& pu); + template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const _Up& u); + template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const _Up& u); + template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const _Up& u); + template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const _Up& u); + template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const _Up& u); + template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const _Up& u); + template <class T, class U> constexpr bool operator==(const _Tp& t, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator!=(const _Tp& t, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator<(const _Tp& t, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator>(const _Tp& t, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator<=(const _Tp& t, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator>=(const _Tp& t, const propagate_const<_Up>& pu); + + // [propagate_const.algorithms], specialized algorithms + template <class T> constexpr void swap(propagate_const<T>& pt, propagate_const<T>& pu) noexcept(see below); + + template <class T> + class propagate_const + { + + public: + typedef remove_reference_t<decltype(*declval<T&>())> element_type; + + // [propagate_const.ctor], constructors + constexpr propagate_const() = default; + propagate_const(const propagate_const& p) = delete; + constexpr propagate_const(propagate_const&& p) = default; + template <class U> EXPLICIT constexpr propagate_const(propagate_const<_Up>&& pu); // see below + template <class U> EXPLICIT constexpr propagate_const(U&& u); // see below + + // [propagate_const.assignment], assignment + propagate_const& operator=(const propagate_const& p) = delete; + constexpr propagate_const& operator=(propagate_const&& p) = default; + template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu); + template <class U> constexpr propagate_const& operator=(U&& u); // see below + + // [propagate_const.const_observers], const observers + explicit constexpr operator bool() const; + constexpr const element_type* operator->() const; + constexpr operator const element_type*() const; // Not always defined + constexpr const element_type& operator*() const; + constexpr const element_type* get() const; + + // [propagate_const.non_const_observers], non-const observers + constexpr element_type* operator->(); + constexpr operator element_type*(); // Not always defined + constexpr element_type& operator*(); + constexpr element_type* get(); + + // [propagate_const.modifiers], modifiers + constexpr void swap(propagate_const& pt) noexcept(see below) + + private: + T t_; // exposition only + }; + + } // namespace fundamentals_v2 + } // namespace experimental + + // [propagate_const.hash], hash support + template <class T> struct hash<experimental::fundamentals_v2::propagate_const<T>>; + + // [propagate_const.comparison_function_objects], comparison function objects + template <class T> struct equal_to<experimental::fundamentals_v2::propagate_const<T>>; + template <class T> struct not_equal_to<experimental::fundamentals_v2::propagate_const<T>>; + template <class T> struct less<experimental::fundamentals_v2::propagate_const<T>>; + template <class T> struct greater<experimental::fundamentals_v2::propagate_const<T>>; + template <class T> struct less_equal<experimental::fundamentals_v2::propagate_const<T>>; + template <class T> struct greater_equal<experimental::fundamentals_v2::propagate_const<T>>; + +} // namespace std + +*/ + +#include <experimental/__config> +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 11 + +#include <type_traits> +#include <utility> +#include <functional> + +_LIBCPP_BEGIN_NAMESPACE_LFTS_V2 + + +template <class _Tp> +class propagate_const; +template <class _Up> _LIBCPP_CONSTEXPR const _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; +template <class _Up> _LIBCPP_CONSTEXPR _Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; + +template <class _Tp> +class propagate_const +{ +public: + typedef remove_reference_t<decltype(*_VSTD::declval<_Tp&>())> element_type; + + static_assert(!is_array<_Tp>::value, + "Instantiation of propagate_const with an array type is ill-formed."); + static_assert(!is_reference<_Tp>::value, + "Instantiation of propagate_const with a reference type is ill-formed."); + static_assert(!(is_pointer<_Tp>::value && is_function<typename remove_pointer<_Tp>::type>::value), + "Instantiation of propagate_const with a function-pointer type is ill-formed."); + static_assert(!(is_pointer<_Tp>::value && is_same<typename remove_cv<typename remove_pointer<_Tp>::type>::type, void>::value), + "Instantiation of propagate_const with a pointer to (possibly cv-qualified) void is ill-formed."); + +private: + template <class _Up> + static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u) + { + return __u; + } + + template <class _Up> + static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u) + { + return __get_pointer(__u.get()); + } + + template <class _Up> + static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u) + { + return __u; + } + + template <class _Up> + static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u) + { + return __get_pointer(__u.get()); + } + + template <class _Up> + struct __is_propagate_const : false_type + { + }; + + template <class _Up> + struct __is_propagate_const<propagate_const<_Up>> : true_type + { + }; + + _Tp __t_; + +public: + + template <class _Up> friend _LIBCPP_CONSTEXPR const _Up& ::_VSTD_LFTS_V2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; + template <class _Up> friend _LIBCPP_CONSTEXPR _Up& ::_VSTD_LFTS_V2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; + + _LIBCPP_CONSTEXPR propagate_const() = default; + + propagate_const(const propagate_const&) = delete; + + _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default; + + template <class _Up, enable_if_t<!is_convertible<_Up, _Tp>::value && + is_constructible<_Tp, _Up&&>::value,bool> = true> + explicit _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) + : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) + { + } + + template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && + is_constructible<_Tp, _Up&&>::value,bool> = false> + _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) + : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) + { + } + + template <class _Up, enable_if_t<!is_convertible<_Up&&, _Tp>::value && + is_constructible<_Tp, _Up&&>::value && + !__is_propagate_const<decay_t<_Up>>::value,bool> = true> + explicit _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) + : __t_(std::forward<_Up>(__u)) + { + } + + template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && + is_constructible<_Tp, _Up&&>::value && + !__is_propagate_const<decay_t<_Up>>::value,bool> = false> + _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) + : __t_(std::forward<_Up>(__u)) + { + } + + propagate_const& operator=(const propagate_const&) = delete; + + _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default; + + template <class _Up> + _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu) + { + __t_ = std::move(_VSTD_LFTS_V2::get_underlying(__pu)); + return *this; + } + + template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>> + _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u) + { + __t_ = std::forward<_Up>(__u); + return *this; + } + + _LIBCPP_CONSTEXPR const element_type* get() const + { + return __get_pointer(__t_); + } + + _LIBCPP_CONSTEXPR element_type* get() + { + return __get_pointer(__t_); + } + + explicit _LIBCPP_CONSTEXPR operator bool() const + { + return get() != nullptr; + } + + _LIBCPP_CONSTEXPR const element_type* operator->() const + { + return get(); + } + + template <class _Tp_ = _Tp, class _Up = enable_if_t<is_convertible< + const _Tp_, const element_type *>::value>> + _LIBCPP_CONSTEXPR operator const element_type *() const { + return get(); + } + + _LIBCPP_CONSTEXPR const element_type& operator*() const + { + return *get(); + } + + _LIBCPP_CONSTEXPR element_type* operator->() + { + return get(); + } + + template <class _Tp_ = _Tp, class _Up = enable_if_t< + is_convertible<_Tp_, element_type *>::value>> + _LIBCPP_CONSTEXPR operator element_type *() { + return get(); + } + + _LIBCPP_CONSTEXPR element_type& operator*() + { + return *get(); + } + + _LIBCPP_CONSTEXPR void swap(propagate_const& __pt) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) + { + using _VSTD::swap; + swap(__t_, __pt.__t_); + } +}; + + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, nullptr_t) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) == nullptr; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator==(nullptr_t, const propagate_const<_Tp>& __pt) +{ + return nullptr == _VSTD_LFTS_V2::get_underlying(__pt); +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, nullptr_t) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) != nullptr; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator!=(nullptr_t, const propagate_const<_Tp>& __pt) +{ + return nullptr != _VSTD_LFTS_V2::get_underlying(__pt); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, + const propagate_const<_Up>& __pu) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) == _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, + const propagate_const<_Up>& __pu) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) != _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, + const propagate_const<_Up>& __pu) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) < _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, + const propagate_const<_Up>& __pu) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) > _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, + const propagate_const<_Up>& __pu) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) <= _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, + const propagate_const<_Up>& __pu) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) >= _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, const _Up& __u) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) == __u; +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, const _Up& __u) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) != __u; +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, const _Up& __u) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) < __u; +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, const _Up& __u) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) > __u; +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, const _Up& __u) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) <= __u; +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, const _Up& __u) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) >= __u; +} + + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator==(const _Tp& __t, const propagate_const<_Up>& __pu) +{ + return __t == _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator!=(const _Tp& __t, const propagate_const<_Up>& __pu) +{ + return __t != _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator<(const _Tp& __t, const propagate_const<_Up>& __pu) +{ + return __t < _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator>(const _Tp& __t, const propagate_const<_Up>& __pu) +{ + return __t > _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator<=(const _Tp& __t, const propagate_const<_Up>& __pu) +{ + return __t <= _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator>=(const _Tp& __t, const propagate_const<_Up>& __pu) +{ + return __t >= _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR void swap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) +{ + using _VSTD::swap; + swap(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT +{ + return __pt.__t_; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT +{ + return __pt.__t_; +} + +_LIBCPP_END_NAMESPACE_LFTS_V2 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template <class _Tp> +struct hash<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef size_t result_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type; + + size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const + { + return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1)); + } +}; + +template <class _Tp> +struct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; + + bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, + const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const + { + return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); + } +}; + +template <class _Tp> +struct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; + + bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, + const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const + { + return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); + } +}; + +template <class _Tp> +struct less<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; + + bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, + const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const + { + return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); + } +}; + +template <class _Tp> +struct greater<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; + + bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, + const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const + { + return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); + } +}; + +template <class _Tp> +struct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; + + bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, + const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const + { + return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); + } +}; + +template <class _Tp> +struct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; + + bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, + const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const + { + return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 11 +#endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST + diff --git a/include/experimental/regex b/include/experimental/regex new file mode 100644 index 0000000000000..d38891c374bb4 --- /dev/null +++ b/include/experimental/regex @@ -0,0 +1,62 @@ +// -*- C++ -*- +//===----------------------------- regex ----------------------------------===// +// +// 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_REGEX +#define _LIBCPP_EXPERIMENTAL_REGEX +/* + experimental/regex synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class BidirectionalIterator> + using match_results = + std::match_results<BidirectionalIterator, + polymorphic_allocator<sub_match<BidirectionalIterator>>>; + + typedef match_results<const char*> cmatch; + typedef match_results<const wchar_t*> wcmatch; + typedef match_results<string::const_iterator> smatch; + typedef match_results<wstring::const_iterator> wsmatch; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <regex> +#include <experimental/string> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _BiDirIter> +using match_results = + _VSTD::match_results<_BiDirIter, + polymorphic_allocator<_VSTD::sub_match<_BiDirIter>>>; + +typedef match_results<const char*> cmatch; +typedef match_results<const wchar_t*> wcmatch; +typedef match_results<_VSTD_LFTS_PMR::string::const_iterator> smatch; +typedef match_results<_VSTD_LFTS_PMR::wstring::const_iterator> wsmatch; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_REGEX */ diff --git a/include/experimental/set b/include/experimental/set new file mode 100644 index 0000000000000..20cf6d4a38901 --- /dev/null +++ b/include/experimental/set @@ -0,0 +1,57 @@ +// -*- C++ -*- +//===--------------------------- list ------------------------------------===// +// +// 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_SET +#define _LIBCPP_EXPERIMENTAL_SET +/* + experimental/set synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class Key, class T, class Compare = less<Key>> + using set = std::set<Key, T, Compare, + polymorphic_allocator<pair<const Key,T>>>; + + template <class Key, class T, class Compare = less<Key>> + using multiset = std::multiset<Key, T, Compare, + polymorphic_allocator<pair<const Key,T>>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <set> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _Value, class _Compare = less<_Value>> +using set = _VSTD::set<_Value, _Compare, + polymorphic_allocator<_Value>>; + +template <class _Value, class _Compare = less<_Value>> +using multiset = _VSTD::multiset<_Value, _Compare, + polymorphic_allocator<_Value>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_SET */ diff --git a/include/experimental/string b/include/experimental/string new file mode 100644 index 0000000000000..8b8545128f2ac --- /dev/null +++ b/include/experimental/string @@ -0,0 +1,62 @@ +// -*- C++ -*- +//===--------------------------- string ----------------------------------===// +// +// 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_STRING +#define _LIBCPP_EXPERIMENTAL_STRING +/* + experimental/string synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + // basic_string using polymorphic allocator in namespace pmr + template <class charT, class traits = char_traits<charT>> + using basic_string = + std::basic_string<charT, traits, polymorphic_allocator<charT>>; + + // basic_string typedef names using polymorphic allocator in namespace + // std::experimental::pmr + typedef basic_string<char> string; + typedef basic_string<char16_t> u16string; + typedef basic_string<char32_t> u32string; + typedef basic_string<wchar_t> wstring; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <string> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _CharT, class _Traits = char_traits<_CharT>> +using basic_string = + _VSTD::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>; + +typedef basic_string<char> string; +typedef basic_string<char16_t> u16string; +typedef basic_string<char32_t> u32string; +typedef basic_string<wchar_t> wstring; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_STRING */ diff --git a/include/experimental/string_view b/include/experimental/string_view index 2a20d7caa6878..0a7239b4c0bb9 100644 --- a/include/experimental/string_view +++ b/include/experimental/string_view @@ -180,6 +180,7 @@ namespace std { #include <algorithm> #include <iterator> #include <ostream> +#include <stdexcept> #include <iomanip> #include <__debug> @@ -227,7 +228,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS basic_string_view(const _CharT* __s, size_type __len) : __data(__s), __size(__len) { -// _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): recieved nullptr"); +// _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr"); } _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY @@ -280,7 +281,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS const_reference at(size_type __pos) const { return __pos >= size() - ? (throw out_of_range("string_view::at"), __data[0]) + ? (__libcpp_throw(out_of_range("string_view::at")), __data[0]) : __data[__pos]; } @@ -351,7 +352,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const { if ( __pos > size()) - throw out_of_range("string_view::copy"); + __libcpp_throw(out_of_range("string_view::copy")); size_type __rlen = _VSTD::min( __n, size() - __pos ); _VSTD::copy_n(begin() + __pos, __rlen, __s ); return __rlen; @@ -365,7 +366,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS // size_type __rlen = _VSTD::min( __n, size() - __pos ); // return basic_string_view(data() + __pos, __rlen); return __pos > size() - ? throw out_of_range("string_view::substr") + ? (__libcpp_throw((out_of_range("string_view::substr"))), basic_string_view()) : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos)); } @@ -413,7 +414,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT { - _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): recieved nullptr"); + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); return _VSTD::__str_find<value_type, size_type, traits_type, npos> (data(), size(), __s.data(), __pos, __s.size()); } @@ -428,7 +429,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find(const _CharT* __s, size_type __pos, size_type __n) const { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): recieved nullptr"); + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr"); return _VSTD::__str_find<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -436,7 +437,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find(const _CharT* __s, size_type __pos = 0) const { - _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): recieved nullptr"); + _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr"); return _VSTD::__str_find<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -445,7 +446,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT { - _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): recieved nullptr"); + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __s.data(), __pos, __s.size()); } @@ -460,7 +461,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): recieved nullptr"); + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr"); return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -468,7 +469,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type rfind(const _CharT* __s, size_type __pos=npos) const { - _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): recieved nullptr"); + _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr"); return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -477,7 +478,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT { - _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): recieved nullptr"); + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr"); return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> (data(), size(), __s.data(), __pos, __s.size()); } @@ -489,7 +490,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): recieved nullptr"); + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr"); return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -497,7 +498,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find_first_of(const _CharT* __s, size_type __pos=0) const { - _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): recieved nullptr"); + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr"); return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -506,7 +507,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT { - _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): recieved nullptr"); + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr"); return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> (data(), size(), __s.data(), __pos, __s.size()); } @@ -518,7 +519,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): recieved nullptr"); + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr"); return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -526,7 +527,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find_last_of(const _CharT* __s, size_type __pos=npos) const { - _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): recieved nullptr"); + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr"); return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -535,7 +536,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT { - _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): recieved nullptr"); + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr"); return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s.data(), __pos, __s.size()); } @@ -550,7 +551,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): recieved nullptr"); + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr"); return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -558,7 +559,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const { - _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): recieved nullptr"); + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr"); return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -567,7 +568,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT { - _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): recieved nullptr"); + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr"); return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s.data(), __pos, __s.size()); } @@ -582,7 +583,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): recieved nullptr"); + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr"); return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -590,7 +591,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const { - _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): recieved nullptr"); + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr"); return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } diff --git a/include/experimental/tuple b/include/experimental/tuple index 50d1e0555bc4a..e00d2ec1a92fb 100644 --- a/include/experimental/tuple +++ b/include/experimental/tuple @@ -57,9 +57,10 @@ _LIBCPP_CONSTEXPR size_t tuple_size_v = tuple_size<_Tp>::value; template <class _Fn, class _Tuple, size_t ..._Id> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_AFTER_CXX11 decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t, integer_sequence<size_t, _Id...>) { - return _VSTD::__invoke( + return _VSTD::__invoke_constexpr( _VSTD::forward<_Fn>(__f), _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))... ); diff --git a/include/experimental/unordered_map b/include/experimental/unordered_map new file mode 100644 index 0000000000000..1f998c2d4c7e3 --- /dev/null +++ b/include/experimental/unordered_map @@ -0,0 +1,65 @@ +// -*- C++ -*- +//===------------------------- unordered_map ------------------------------===// +// +// 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_UNORDERED_MAP +#define _LIBCPP_EXPERIMENTAL_UNORDERED_MAP +/* + experimental/unordered_map synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class Key, class T, + class Hash = hash<Key>, + class Pred = equal_to<Key>> + using unordered_map = + std::unordered_map<Key, T, Hash, Pred, + polymorphic_allocator<pair<const Key,T>>>; + + template <class Key, class T, + class Hash = hash<Key>, + class Pred = equal_to<Key>> + using unordered_multimap = + std::unordered_multimap<Key, T, Hash, Pred, + polymorphic_allocator<pair<const Key,T>>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <unordered_map> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _Key, class _Value, + class _Hash = hash<_Key>, class _Pred = equal_to<_Key>> +using unordered_map = _VSTD::unordered_map<_Key, _Value, _Hash, _Pred, + polymorphic_allocator<pair<const _Key, _Value>>>; + +template <class _Key, class _Value, + class _Hash = hash<_Key>, class _Pred = equal_to<_Key>> +using unordered_multimap = _VSTD::unordered_multimap<_Key, _Value, _Hash, _Pred, + polymorphic_allocator<pair<const _Key, _Value>>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_UNORDERED_MAP */ diff --git a/include/experimental/unordered_set b/include/experimental/unordered_set new file mode 100644 index 0000000000000..d00a837534018 --- /dev/null +++ b/include/experimental/unordered_set @@ -0,0 +1,59 @@ +// -*- C++ -*- +//===------------------------- unordered_set ------------------------------===// +// +// 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_UNORDERED_SET +#define _LIBCPP_EXPERIMENTAL_UNORDERED_SET +/* + experimental/unordered_set synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class T, class Hash = hash<T>, class Pred = equal_to<T>> + using unordered_set = std::unordered_set<T, Hash, Pred, + polymorphic_allocator<T>>; + + template <class T, class Hash = hash<T>, class Pred = equal_to<T>> + using unordered_multiset = std::unordered_multiset<T, Hash, Pred, + polymorphic_allocator<T>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <unordered_set> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _Value, + class _Hash = hash<_Value>, class _Pred = equal_to<_Value>> +using unordered_set = _VSTD::unordered_set<_Value, _Hash, _Pred, + polymorphic_allocator<_Value>>; + +template <class _Value, + class _Hash = hash<_Value>, class _Pred = equal_to<_Value>> +using unordered_multiset = _VSTD::unordered_multiset<_Value, _Hash, _Pred, + polymorphic_allocator<_Value>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_UNORDERED_SET */ diff --git a/include/experimental/vector b/include/experimental/vector new file mode 100644 index 0000000000000..bd10492bfefc0 --- /dev/null +++ b/include/experimental/vector @@ -0,0 +1,47 @@ +// -*- C++ -*- +//===--------------------------- vector ------------------------------------===// +// +// 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_VECTOR +#define _LIBCPP_EXPERIMENTAL_VECTOR +/* + experimental/vector synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class T> + using vector = std::vector<T, polymorphic_allocator<T>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <vector> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _ValueT> +using vector = _VSTD::vector<_ValueT, polymorphic_allocator<_ValueT>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_VECTOR */ diff --git a/include/ext/hash_map b/include/ext/hash_map index 3ac27b2ca330b..5e1e9f542b179 100644 --- a/include/ext/hash_map +++ b/include/ext/hash_map @@ -309,7 +309,7 @@ class __hash_map_node_destructor { typedef _Alloc allocator_type; typedef allocator_traits<allocator_type> __alloc_traits; - typedef typename __alloc_traits::value_type::value_type value_type; + typedef typename __alloc_traits::value_type::__node_value_type value_type; public: typedef typename __alloc_traits::pointer pointer; private: @@ -549,6 +549,7 @@ public: _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;} template <class _InputIterator> + _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); _LIBCPP_INLINE_VISIBILITY @@ -674,7 +675,7 @@ hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k) template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) @@ -820,6 +821,7 @@ public: _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator, const value_type& __x) {return insert(__x);} template <class _InputIterator> + _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); _LIBCPP_INLINE_VISIBILITY @@ -927,7 +929,7 @@ hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) diff --git a/include/ext/hash_set b/include/ext/hash_set index c4bb89843d552..91850b566d5b1 100644 --- a/include/ext/hash_set +++ b/include/ext/hash_set @@ -282,6 +282,7 @@ public: _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;} template <class _InputIterator> + _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); _LIBCPP_INLINE_VISIBILITY @@ -385,7 +386,7 @@ hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set( template <class _Value, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void hash_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) @@ -502,6 +503,7 @@ public: _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator, const value_type& __x) {return insert(__x);} template <class _InputIterator> + _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); _LIBCPP_INLINE_VISIBILITY @@ -606,7 +608,7 @@ hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( template <class _Value, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void hash_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) diff --git a/include/forward_list b/include/forward_list index 4f9ecf49bd58c..18b300d847037 100644 --- a/include/forward_list +++ b/include/forward_list @@ -183,15 +183,69 @@ template <class T, class Allocator> _LIBCPP_BEGIN_NAMESPACE_STD template <class _Tp, class _VoidPtr> struct __forward_list_node; +template <class _NodePtr> struct __forward_begin_node; + + +template <class> +struct __forward_list_node_value_type; + +template <class _Tp, class _VoidPtr> +struct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > { + typedef _Tp type; +}; + +template <class _NodePtr> +struct __forward_node_traits { + + typedef typename remove_cv< + typename pointer_traits<_NodePtr>::element_type>::type __node; + typedef typename __forward_list_node_value_type<__node>::type __node_value_type; + typedef _NodePtr __node_pointer; + typedef __forward_begin_node<_NodePtr> __begin_node; + typedef typename __rebind_pointer<_NodePtr, __begin_node>::type + __begin_node_pointer; + typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer; + +#if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB) + typedef __begin_node_pointer __iter_node_pointer; +#else + typedef typename conditional< + is_pointer<__void_pointer>::value, + __begin_node_pointer, + __node_pointer + >::type __iter_node_pointer; +#endif + + typedef typename conditional< + is_same<__iter_node_pointer, __node_pointer>::value, + __begin_node_pointer, + __node_pointer + >::type __non_iter_node_pointer; + + _LIBCPP_INLINE_VISIBILITY + static __iter_node_pointer __as_iter_node(__iter_node_pointer __p) { + return __p; + } + _LIBCPP_INLINE_VISIBILITY + static __iter_node_pointer __as_iter_node(__non_iter_node_pointer __p) { + return static_cast<__iter_node_pointer>(static_cast<__void_pointer>(__p)); + } +}; template <class _NodePtr> struct __forward_begin_node { typedef _NodePtr pointer; + typedef typename __rebind_pointer<_NodePtr, __forward_begin_node>::type __begin_node_pointer; pointer __next_; - _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + __begin_node_pointer __next_as_begin() const { + return static_cast<__begin_node_pointer>(__next_); + } }; template <class _Tp, class _VoidPtr> @@ -211,26 +265,49 @@ struct __forward_list_node value_type __value_; }; + template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TYPE_VIS_ONLY forward_list; template<class _NodeConstPtr> class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator; template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __forward_list_iterator { - typedef _NodePtr __node_pointer; + typedef __forward_node_traits<_NodePtr> __traits; + typedef typename __traits::__node_pointer __node_pointer; + typedef typename __traits::__begin_node_pointer __begin_node_pointer; + typedef typename __traits::__iter_node_pointer __iter_node_pointer; + typedef typename __traits::__void_pointer __void_pointer; - __node_pointer __ptr_; + __iter_node_pointer __ptr_; + + _LIBCPP_INLINE_VISIBILITY + __begin_node_pointer __get_begin() const { + return static_cast<__begin_node_pointer>( + static_cast<__void_pointer>(__ptr_)); + } + _LIBCPP_INLINE_VISIBILITY + __node_pointer __get_unsafe_node_pointer() const { + return static_cast<__node_pointer>( + static_cast<__void_pointer>(__ptr_)); + } _LIBCPP_INLINE_VISIBILITY - explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} + explicit __forward_list_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT + : __ptr_(__traits::__as_iter_node(__p)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT + : __ptr_(__traits::__as_iter_node(__p)) {} template<class, class> friend class _LIBCPP_TYPE_VIS_ONLY forward_list; template<class> friend class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator; public: typedef forward_iterator_tag iterator_category; - typedef typename pointer_traits<__node_pointer>::element_type::value_type - value_type; + typedef typename __traits::__node_value_type value_type; typedef value_type& reference; typedef typename pointer_traits<__node_pointer>::difference_type difference_type; @@ -240,14 +317,16 @@ public: __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {} _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __ptr_->__value_;} + reference operator*() const {return __get_unsafe_node_pointer()->__value_;} _LIBCPP_INLINE_VISIBILITY - pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);} + pointer operator->() const { + return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__value_); + } _LIBCPP_INLINE_VISIBILITY __forward_list_iterator& operator++() { - __ptr_ = __ptr_->__next_; + __ptr_ = __traits::__as_iter_node(__ptr_->__next_); return *this; } _LIBCPP_INLINE_VISIBILITY @@ -271,29 +350,50 @@ public: template <class _NodeConstPtr> class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator { - typedef _NodeConstPtr __node_const_pointer; + static_assert((!is_const<typename pointer_traits<_NodeConstPtr>::element_type>::value), ""); + typedef _NodeConstPtr _NodePtr; + + typedef __forward_node_traits<_NodePtr> __traits; + typedef typename __traits::__node __node; + typedef typename __traits::__node_pointer __node_pointer; + typedef typename __traits::__begin_node_pointer __begin_node_pointer; + typedef typename __traits::__iter_node_pointer __iter_node_pointer; + typedef typename __traits::__void_pointer __void_pointer; - __node_const_pointer __ptr_; + __iter_node_pointer __ptr_; + + __begin_node_pointer __get_begin() const { + return static_cast<__begin_node_pointer>( + static_cast<__void_pointer>(__ptr_)); + } + __node_pointer __get_unsafe_node_pointer() const { + return static_cast<__node_pointer>( + static_cast<__void_pointer>(__ptr_)); + } _LIBCPP_INLINE_VISIBILITY - explicit __forward_list_const_iterator(__node_const_pointer __p) _NOEXCEPT - : __ptr_(__p) {} + explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT + : __ptr_(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT + : __ptr_(__traits::__as_iter_node(__p)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT + : __ptr_(__traits::__as_iter_node(__p)) {} - typedef typename remove_const - < - typename pointer_traits<__node_const_pointer>::element_type - >::type __node; - typedef typename __rebind_pointer<__node_const_pointer, __node>::type __node_pointer; template<class, class> friend class forward_list; public: typedef forward_iterator_tag iterator_category; - typedef typename __node::value_type value_type; + typedef typename __traits::__node_value_type value_type; typedef const value_type& reference; - typedef typename pointer_traits<__node_const_pointer>::difference_type + typedef typename pointer_traits<__node_pointer>::difference_type difference_type; - typedef typename __rebind_pointer<__node_const_pointer, const value_type>::type pointer; + typedef typename __rebind_pointer<__node_pointer, const value_type>::type + pointer; _LIBCPP_INLINE_VISIBILITY __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {} @@ -302,14 +402,15 @@ public: : __ptr_(__p.__ptr_) {} _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __ptr_->__value_;} + reference operator*() const {return __get_unsafe_node_pointer()->__value_;} _LIBCPP_INLINE_VISIBILITY - pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);} + pointer operator->() const {return pointer_traits<pointer>::pointer_to( + __get_unsafe_node_pointer()->__value_);} _LIBCPP_INLINE_VISIBILITY __forward_list_const_iterator& operator++() { - __ptr_ = __ptr_->__next_; + __ptr_ = __traits::__as_iter_node(__ptr_->__next_); return *this; } _LIBCPP_INLINE_VISIBILITY @@ -343,21 +444,21 @@ protected: 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 __rebind_alloc_helper<allocator_traits<allocator_type>, __begin_node>::type __begin_node_allocator; - typedef typename allocator_traits<__begin_node_allocator>::pointer __begin_node_pointer; + 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_; _LIBCPP_INLINE_VISIBILITY - __node_pointer __before_begin() _NOEXCEPT - {return static_cast<__node_pointer>(pointer_traits<__begin_node_pointer>:: - pointer_to(__before_begin_.first()));} + __begin_node_pointer __before_begin() _NOEXCEPT + {return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_.first());} _LIBCPP_INLINE_VISIBILITY - __node_const_pointer __before_begin() const _NOEXCEPT - {return static_cast<__node_const_pointer>(pointer_traits<__begin_node_pointer>:: - pointer_to(const_cast<__begin_node&>(__before_begin_.first())));} + __begin_node_pointer __before_begin() const _NOEXCEPT + {return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_.first()));} _LIBCPP_INLINE_VISIBILITY __node_allocator& __alloc() _NOEXCEPT @@ -379,8 +480,10 @@ protected: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES public: + _LIBCPP_INLINE_VISIBILITY __forward_list_base(__forward_list_base&& __x) _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value); + _LIBCPP_INLINE_VISIBILITY __forward_list_base(__forward_list_base&& __x, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -405,6 +508,7 @@ protected: __node_traits::propagate_on_container_move_assignment::value>());} public: + _LIBCPP_INLINE_VISIBILITY void swap(__forward_list_base& __x) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT; @@ -438,7 +542,7 @@ private: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x) _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) : __before_begin_(_VSTD::move(__x.__before_begin_)) @@ -447,7 +551,7 @@ __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x, const allocator_type& __a) : __before_begin_(__begin_node(), __node_allocator(__a)) @@ -468,7 +572,7 @@ __forward_list_base<_Tp, _Alloc>::~__forward_list_base() } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void __forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x) #if _LIBCPP_STD_VER >= 14 @@ -505,9 +609,10 @@ class _LIBCPP_TYPE_VIS_ONLY forward_list { typedef __forward_list_base<_Tp, _Alloc> base; typedef typename base::__node_allocator __node_allocator; - typedef typename base::__node __node; - typedef typename base::__node_traits __node_traits; - typedef typename base::__node_pointer __node_pointer; + typedef typename base::__node __node; + typedef typename base::__node_traits __node_traits; + typedef typename base::__node_pointer __node_pointer; + typedef typename base::__begin_node_pointer __begin_node_pointer; public: typedef _Tp value_type; @@ -530,6 +635,7 @@ public: forward_list() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) {} // = default; + _LIBCPP_INLINE_VISIBILITY explicit forward_list(const allocator_type& __a); explicit forward_list(size_type __n); #if _LIBCPP_STD_VER > 11 @@ -566,12 +672,14 @@ public: forward_list& operator=(const forward_list& __x); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY forward_list& operator=(forward_list&& __x) _NOEXCEPT_( __node_traits::propagate_on_container_move_assignment::value && is_nothrow_move_assignable<allocator_type>::value); #endif #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY forward_list& operator=(initializer_list<value_type> __il); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS @@ -584,6 +692,7 @@ public: assign(_InputIterator __f, _InputIterator __l); void assign(size_type __n, const value_type& __v); #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY void assign(initializer_list<value_type> __il); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS @@ -714,7 +823,7 @@ public: template <class _Compare> void merge(forward_list& __x, _Compare __comp); _LIBCPP_INLINE_VISIBILITY void sort() {sort(__less<value_type>());} - template <class _Compare> void sort(_Compare __comp); + template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp); void reverse() _NOEXCEPT; private: @@ -737,7 +846,7 @@ private: }; template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a) : base(__a) { @@ -751,8 +860,8 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n) __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); - for (__node_pointer __p = base::__before_begin(); __n > 0; --__n, - __p = __p->__next_) + for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, + __p = __p->__next_as_begin()) { __h.reset(__node_traits::allocate(__a, 1)); __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); @@ -772,8 +881,8 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __a __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); - for (__node_pointer __p = base::__before_begin(); __n > 0; --__n, - __p = __p->__next_) + for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, + __p = __p->__next_as_begin()) { __h.reset(__node_traits::allocate(__a, 1)); __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); @@ -911,7 +1020,7 @@ forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(forward_list&& __x) _NOEXCEPT_( @@ -928,7 +1037,7 @@ forward_list<_Tp, _Alloc>::operator=(forward_list&& __x) #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il) { @@ -976,7 +1085,7 @@ forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v) #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il) { @@ -1049,7 +1158,7 @@ template <class... _Args> typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args) { - __node_pointer const __r = __p.__ptr_; + __begin_node_pointer const __r = __p.__get_begin(); __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); @@ -1066,7 +1175,7 @@ template <class _Tp, class _Alloc> typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v) { - __node_pointer const __r = __p.__ptr_; + __begin_node_pointer const __r = __p.__get_begin(); __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); @@ -1082,7 +1191,7 @@ template <class _Tp, class _Alloc> typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v) { - __node_pointer const __r = __p.__ptr_; + __begin_node_pointer const __r = __p.__get_begin(); __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); @@ -1097,7 +1206,7 @@ typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, const value_type& __v) { - __node_pointer __r = __p.__ptr_; + __begin_node_pointer __r = __p.__get_begin(); if (__n > 0) { __node_allocator& __a = base::__alloc(); @@ -1132,7 +1241,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, #endif // _LIBCPP_NO_EXCEPTIONS __last->__next_ = __r->__next_; __r->__next_ = __first; - __r = __last; + __r = static_cast<__begin_node_pointer>(__last); } return iterator(__r); } @@ -1147,7 +1256,7 @@ typename enable_if forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l) { - __node_pointer __r = __p.__ptr_; + __begin_node_pointer __r = __p.__get_begin(); if (__f != __l) { __node_allocator& __a = base::__alloc(); @@ -1182,7 +1291,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, #endif // _LIBCPP_NO_EXCEPTIONS __last->__next_ = __r->__next_; __r->__next_ = __first; - __r = __last; + __r = static_cast<__begin_node_pointer>(__last); } return iterator(__r); } @@ -1191,7 +1300,7 @@ template <class _Tp, class _Alloc> typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::erase_after(const_iterator __f) { - __node_pointer __p = __f.__ptr_; + __begin_node_pointer __p = __f.__get_begin(); __node_pointer __n = __p->__next_; __p->__next_ = __n->__next_; __node_allocator& __a = base::__alloc(); @@ -1204,21 +1313,22 @@ template <class _Tp, class _Alloc> typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l) { - __node_pointer __e = __l.__ptr_; + __node_pointer __e = __l.__get_unsafe_node_pointer(); if (__f != __l) { - __node_pointer __p = __f.__ptr_; - __node_pointer __n = __p->__next_; + __begin_node_pointer __bp = __f.__get_begin(); + + __node_pointer __n = __bp->__next_; if (__n != __e) { - __p->__next_ = __e; + __bp->__next_ = __e; __node_allocator& __a = base::__alloc(); do { - __p = __n->__next_; + __node_pointer __tmp = __n->__next_; __node_traits::destroy(__a, _VSTD::addressof(__n->__value_)); __node_traits::deallocate(__a, __n, 1); - __n = __p; + __n = __tmp; } while (__n != __e); } } @@ -1245,8 +1355,8 @@ forward_list<_Tp, _Alloc>::resize(size_type __n) __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); - for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n, - __ptr = __ptr->__next_) + for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, + __ptr = __ptr->__next_as_begin()) { __h.reset(__node_traits::allocate(__a, 1)); __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); @@ -1277,8 +1387,8 @@ forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v) __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); - for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n, - __ptr = __ptr->__next_) + for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, + __ptr = __ptr->__next_as_begin()) { __h.reset(__node_traits::allocate(__a, 1)); __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); @@ -1296,14 +1406,14 @@ forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, { if (!__x.empty()) { - if (__p.__ptr_->__next_ != nullptr) + if (__p.__get_begin()->__next_ != nullptr) { const_iterator __lm1 = __x.before_begin(); - while (__lm1.__ptr_->__next_ != nullptr) + while (__lm1.__get_begin()->__next_ != nullptr) ++__lm1; - __lm1.__ptr_->__next_ = __p.__ptr_->__next_; + __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; } - __p.__ptr_->__next_ = __x.__before_begin()->__next_; + __p.__get_begin()->__next_ = __x.__before_begin()->__next_; __x.__before_begin()->__next_ = nullptr; } } @@ -1317,9 +1427,9 @@ forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, const_iterator __lm1 = _VSTD::next(__i); if (__p != __i && __p != __lm1) { - __i.__ptr_->__next_ = __lm1.__ptr_->__next_; - __lm1.__ptr_->__next_ = __p.__ptr_->__next_; - __p.__ptr_->__next_ = __lm1.__ptr_; + __i.__get_begin()->__next_ = __lm1.__get_begin()->__next_; + __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; + __p.__get_begin()->__next_ = __lm1.__get_unsafe_node_pointer(); } } @@ -1332,13 +1442,13 @@ forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, if (__f != __l && __p != __f) { const_iterator __lm1 = __f; - while (__lm1.__ptr_->__next_ != __l.__ptr_) + while (__lm1.__get_begin()->__next_ != __l.__get_begin()) ++__lm1; if (__f != __lm1) { - __lm1.__ptr_->__next_ = __p.__ptr_->__next_; - __p.__ptr_->__next_ = __f.__ptr_->__next_; - __f.__ptr_->__next_ = __l.__ptr_; + __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; + __p.__get_begin()->__next_ = __f.__get_begin()->__next_; + __f.__get_begin()->__next_ = __l.__get_unsafe_node_pointer(); } } } @@ -1382,9 +1492,9 @@ forward_list<_Tp, _Alloc>::remove(const value_type& __v) { forward_list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing iterator __e = end(); - for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;) + for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) { - if (__i.__ptr_->__next_->__value_ == __v) + if (__i.__get_begin()->__next_->__value_ == __v) { iterator __j = _VSTD::next(__i, 2); for (; __j != __e && *__j == __v; ++__j) @@ -1405,9 +1515,9 @@ void forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred) { iterator __e = end(); - for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;) + for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) { - if (__pred(__i.__ptr_->__next_->__value_)) + if (__pred(__i.__get_begin()->__next_->__value_)) { iterator __j = _VSTD::next(__i, 2); for (; __j != __e && __pred(*__j); ++__j) @@ -1432,7 +1542,7 @@ forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) iterator __j = _VSTD::next(__i); for (; __j != __e && __binary_pred(*__i, *__j); ++__j) ; - if (__i.__ptr_->__next_ != __j.__ptr_) + if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer()) erase_after(__i, __j); __i = __j; } @@ -1499,7 +1609,7 @@ forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2, template <class _Tp, class _Alloc> template <class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline void forward_list<_Tp, _Alloc>::sort(_Compare __comp) { @@ -1530,7 +1640,7 @@ forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz, } difference_type __sz1 = __sz / 2; difference_type __sz2 = __sz - __sz1; - __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__ptr_; + __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer(); __node_pointer __f2 = __t->__next_; __t->__next_ = nullptr; return __merge(__sort(__f1, __sz1, __comp), diff --git a/include/fstream b/include/fstream index 1f289eddc56f5..3cb3b13bd10f1 100644 --- a/include/fstream +++ b/include/fstream @@ -200,14 +200,17 @@ public: // 27.9.1.3 Assign/swap: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_filebuf& operator=(basic_filebuf&& __rhs); #endif void swap(basic_filebuf& __rhs); // 27.9.1.4 Members: + _LIBCPP_INLINE_VISIBILITY bool is_open() const; #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE basic_filebuf* open(const char* __s, ios_base::openmode __mode); + _LIBCPP_INLINE_VISIBILITY basic_filebuf* open(const string& __s, ios_base::openmode __mode); #endif basic_filebuf* close(); @@ -340,7 +343,7 @@ basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_filebuf<_CharT, _Traits>& basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) { @@ -458,7 +461,7 @@ swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline bool basic_filebuf<_CharT, _Traits>::is_open() const { @@ -547,7 +550,7 @@ basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) { @@ -603,7 +606,9 @@ basic_filebuf<_CharT, _Traits>::underflow() } else { - memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); + _LIBCPP_ASSERT ( !(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" ); + if (__extbufend_ != __extbufnext_) + memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); size_t __nmemb = _VSTD::min(static_cast<size_t>(__ibs_ - __unget_sz), @@ -1008,26 +1013,35 @@ public: typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; + _LIBCPP_INLINE_VISIBILITY basic_ifstream(); #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + _LIBCPP_INLINE_VISIBILITY explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in); + _LIBCPP_INLINE_VISIBILITY explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in); #endif #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_ifstream(basic_ifstream&& __rhs); #endif #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_ifstream& operator=(basic_ifstream&& __rhs); #endif + _LIBCPP_INLINE_VISIBILITY void swap(basic_ifstream& __rhs); + _LIBCPP_INLINE_VISIBILITY basic_filebuf<char_type, traits_type>* rdbuf() const; + _LIBCPP_INLINE_VISIBILITY 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 + _LIBCPP_INLINE_VISIBILITY void close(); private: @@ -1035,7 +1049,7 @@ private: }; template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ifstream<_CharT, _Traits>::basic_ifstream() : basic_istream<char_type, traits_type>(&__sb_) { @@ -1043,7 +1057,7 @@ basic_ifstream<_CharT, _Traits>::basic_ifstream() #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode) : basic_istream<char_type, traits_type>(&__sb_) { @@ -1052,7 +1066,7 @@ basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openm } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode) : basic_istream<char_type, traits_type>(&__sb_) { @@ -1064,7 +1078,7 @@ basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::ope #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs) : basic_istream<char_type, traits_type>(_VSTD::move(__rhs)), __sb_(_VSTD::move(__rhs.__sb_)) @@ -1073,7 +1087,7 @@ basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ifstream<_CharT, _Traits>& basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) { @@ -1085,7 +1099,7 @@ basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) { @@ -1102,7 +1116,7 @@ swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_filebuf<_CharT, _Traits>* basic_ifstream<_CharT, _Traits>::rdbuf() const { @@ -1110,7 +1124,7 @@ basic_ifstream<_CharT, _Traits>::rdbuf() const } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline bool basic_ifstream<_CharT, _Traits>::is_open() const { @@ -1140,7 +1154,7 @@ basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mo #endif template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_ifstream<_CharT, _Traits>::close() { @@ -1161,24 +1175,33 @@ public: typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; + _LIBCPP_INLINE_VISIBILITY basic_ofstream(); + _LIBCPP_INLINE_VISIBILITY explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out); + _LIBCPP_INLINE_VISIBILITY explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_ofstream(basic_ofstream&& __rhs); #endif #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_ofstream& operator=(basic_ofstream&& __rhs); #endif + _LIBCPP_INLINE_VISIBILITY void swap(basic_ofstream& __rhs); + _LIBCPP_INLINE_VISIBILITY basic_filebuf<char_type, traits_type>* rdbuf() const; + _LIBCPP_INLINE_VISIBILITY 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 + _LIBCPP_INLINE_VISIBILITY void close(); private: @@ -1186,7 +1209,7 @@ private: }; template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ofstream<_CharT, _Traits>::basic_ofstream() : basic_ostream<char_type, traits_type>(&__sb_) { @@ -1194,7 +1217,7 @@ basic_ofstream<_CharT, _Traits>::basic_ofstream() #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode) : basic_ostream<char_type, traits_type>(&__sb_) { @@ -1203,7 +1226,7 @@ basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openm } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode) : basic_ostream<char_type, traits_type>(&__sb_) { @@ -1215,7 +1238,7 @@ basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::ope #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs) : basic_ostream<char_type, traits_type>(_VSTD::move(__rhs)), __sb_(_VSTD::move(__rhs.__sb_)) @@ -1224,7 +1247,7 @@ basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ofstream<_CharT, _Traits>& basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) { @@ -1236,7 +1259,7 @@ basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) { @@ -1253,7 +1276,7 @@ swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_filebuf<_CharT, _Traits>* basic_ofstream<_CharT, _Traits>::rdbuf() const { @@ -1261,7 +1284,7 @@ basic_ofstream<_CharT, _Traits>::rdbuf() const } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline bool basic_ofstream<_CharT, _Traits>::is_open() const { @@ -1291,7 +1314,7 @@ basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mo #endif template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_ofstream<_CharT, _Traits>::close() { @@ -1312,26 +1335,35 @@ public: typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; + _LIBCPP_INLINE_VISIBILITY basic_fstream(); #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + _LIBCPP_INLINE_VISIBILITY explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); + _LIBCPP_INLINE_VISIBILITY explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); #endif #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_fstream(basic_fstream&& __rhs); #endif #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_fstream& operator=(basic_fstream&& __rhs); #endif + _LIBCPP_INLINE_VISIBILITY void swap(basic_fstream& __rhs); + _LIBCPP_INLINE_VISIBILITY basic_filebuf<char_type, traits_type>* rdbuf() const; + _LIBCPP_INLINE_VISIBILITY 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 + _LIBCPP_INLINE_VISIBILITY void close(); private: @@ -1339,7 +1371,7 @@ private: }; template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_fstream<_CharT, _Traits>::basic_fstream() : basic_iostream<char_type, traits_type>(&__sb_) { @@ -1347,7 +1379,7 @@ basic_fstream<_CharT, _Traits>::basic_fstream() #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode) : basic_iostream<char_type, traits_type>(&__sb_) { @@ -1356,7 +1388,7 @@ basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmod } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode) : basic_iostream<char_type, traits_type>(&__sb_) { @@ -1368,7 +1400,7 @@ basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openm #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs) : basic_iostream<char_type, traits_type>(_VSTD::move(__rhs)), __sb_(_VSTD::move(__rhs.__sb_)) @@ -1377,7 +1409,7 @@ basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_fstream<_CharT, _Traits>& basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) { @@ -1389,7 +1421,7 @@ basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) { @@ -1406,7 +1438,7 @@ swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_filebuf<_CharT, _Traits>* basic_fstream<_CharT, _Traits>::rdbuf() const { @@ -1414,7 +1446,7 @@ basic_fstream<_CharT, _Traits>::rdbuf() const } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline bool basic_fstream<_CharT, _Traits>::is_open() const { @@ -1444,7 +1476,7 @@ basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mod #endif template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_fstream<_CharT, _Traits>::close() { diff --git a/include/functional b/include/functional index dbe9b01bbd861..581f965b2b81f 100644 --- a/include/functional +++ b/include/functional @@ -207,6 +207,8 @@ public: template <class Predicate> binary_negate<Predicate> not2(const Predicate& pred); +template <class F> unspecified not_fn(F&& f); // C++17 + template<class T> struct is_bind_expression; template<class T> struct is_placeholder; @@ -407,7 +409,7 @@ public: // function modifiers: void swap(function&) noexcept; template<class F, class Alloc> - void assign(F&&, const Alloc&); + void assign(F&&, const Alloc&); // Removed in C++17 // function capacity: explicit operator bool() const noexcept; @@ -1564,6 +1566,10 @@ class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_ArgTypes...)> typename aligned_storage<3*sizeof(void*)>::type __buf_; __base* __f_; + _LIBCPP_NO_CFI static __base *__as_base(void *p) { + return reinterpret_cast<__base*>(p); + } + template <class _Fp, bool = !is_same<_Fp, function>::value && __invokable<_Fp&, _ArgTypes...>::value> struct __callable; @@ -1626,10 +1632,13 @@ public: // function modifiers: void swap(function&) _NOEXCEPT; + +#if _LIBCPP_STD_VER <= 14 template<class _Fp, class _Alloc> _LIBCPP_INLINE_VISIBILITY void assign(_Fp&& __f, const _Alloc& __a) {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);} +#endif // function capacity: _LIBCPP_INLINE_VISIBILITY @@ -1657,9 +1666,9 @@ function<_Rp(_ArgTypes...)>::function(const function& __f) { if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { - __f_ = (__base*)&__buf_; + __f_ = __as_base(&__buf_); __f.__f_->__clone(__f_); } else @@ -1673,9 +1682,9 @@ function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, { if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { - __f_ = (__base*)&__buf_; + __f_ = __as_base(&__buf_); __f.__f_->__clone(__f_); } else @@ -1687,9 +1696,9 @@ function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT { if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (__base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { - __f_ = (__base*)&__buf_; + __f_ = __as_base(&__buf_); __f.__f_->__clone(__f_); } else @@ -1706,9 +1715,9 @@ function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, { if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (__base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { - __f_ = (__base*)&__buf_; + __f_ = __as_base(&__buf_); __f.__f_->__clone(__f_); } else @@ -1733,8 +1742,7 @@ function<_Rp(_ArgTypes...)>::function(_Fp __f, typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_ArgTypes...)> _FF; if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value) { - __f_ = (__base*)&__buf_; - ::new (__f_) _FF(_VSTD::move(__f)); + __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f)); } else { @@ -1763,8 +1771,7 @@ function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp _ if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value) { - __f_ = (__base*)&__buf_; - ::new (__f_) _FF(_VSTD::move(__f), _Alloc(__a)); + __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f), _Alloc(__a)); } else { @@ -1788,16 +1795,16 @@ template<class _Rp, class ..._ArgTypes> function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT { - if (__f_ == (__base*)&__buf_) + if ((void *)__f_ == &__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); __f_ = 0; if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (__base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { - __f_ = (__base*)&__buf_; + __f_ = __as_base(&__buf_); __f.__f_->__clone(__f_); } else @@ -1812,7 +1819,7 @@ template<class _Rp, class ..._ArgTypes> function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT { - if (__f_ == (__base*)&__buf_) + if ((void *)__f_ == &__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); @@ -1837,7 +1844,7 @@ function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) template<class _Rp, class ..._ArgTypes> function<_Rp(_ArgTypes...)>::~function() { - if (__f_ == (__base*)&__buf_) + if ((void *)__f_ == &__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); @@ -1847,34 +1854,34 @@ template<class _Rp, class ..._ArgTypes> void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT { - if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + if ((void *)__f_ == &__buf_ && (void *)__f.__f_ == &__f.__buf_) { typename aligned_storage<sizeof(__buf_)>::type __tempbuf; - __base* __t = (__base*)&__tempbuf; + __base* __t = __as_base(&__tempbuf); __f_->__clone(__t); __f_->destroy(); __f_ = 0; - __f.__f_->__clone((__base*)&__buf_); + __f.__f_->__clone(__as_base(&__buf_)); __f.__f_->destroy(); __f.__f_ = 0; - __f_ = (__base*)&__buf_; - __t->__clone((__base*)&__f.__buf_); + __f_ = __as_base(&__buf_); + __t->__clone(__as_base(&__f.__buf_)); __t->destroy(); - __f.__f_ = (__base*)&__f.__buf_; + __f.__f_ = __as_base(&__f.__buf_); } - else if (__f_ == (__base*)&__buf_) + else if ((void *)__f_ == &__buf_) { - __f_->__clone((__base*)&__f.__buf_); + __f_->__clone(__as_base(&__f.__buf_)); __f_->destroy(); __f_ = __f.__f_; - __f.__f_ = (__base*)&__f.__buf_; + __f.__f_ = __as_base(&__f.__buf_); } - else if (__f.__f_ == (__base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { - __f.__f_->__clone((__base*)&__buf_); + __f.__f_->__clone(__as_base(&__buf_)); __f.__f_->destroy(); __f.__f_ = __f_; - __f_ = (__base*)&__buf_; + __f_ = __as_base(&__buf_); } else _VSTD::swap(__f_, __f.__f_); @@ -1973,16 +1980,29 @@ namespace placeholders template <int _Np> struct __ph {}; -_LIBCPP_FUNC_VIS extern __ph<1> _1; -_LIBCPP_FUNC_VIS extern __ph<2> _2; -_LIBCPP_FUNC_VIS extern __ph<3> _3; -_LIBCPP_FUNC_VIS extern __ph<4> _4; -_LIBCPP_FUNC_VIS extern __ph<5> _5; -_LIBCPP_FUNC_VIS extern __ph<6> _6; -_LIBCPP_FUNC_VIS extern __ph<7> _7; -_LIBCPP_FUNC_VIS extern __ph<8> _8; -_LIBCPP_FUNC_VIS extern __ph<9> _9; -_LIBCPP_FUNC_VIS extern __ph<10> _10; +#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_BIND) +_LIBCPP_FUNC_VIS extern const __ph<1> _1; +_LIBCPP_FUNC_VIS extern const __ph<2> _2; +_LIBCPP_FUNC_VIS extern const __ph<3> _3; +_LIBCPP_FUNC_VIS extern const __ph<4> _4; +_LIBCPP_FUNC_VIS extern const __ph<5> _5; +_LIBCPP_FUNC_VIS extern const __ph<6> _6; +_LIBCPP_FUNC_VIS extern const __ph<7> _7; +_LIBCPP_FUNC_VIS extern const __ph<8> _8; +_LIBCPP_FUNC_VIS extern const __ph<9> _9; +_LIBCPP_FUNC_VIS extern const __ph<10> _10; +#else +constexpr __ph<1> _1{}; +constexpr __ph<2> _2{}; +constexpr __ph<3> _3{}; +constexpr __ph<4> _4{}; +constexpr __ph<5> _5{}; +constexpr __ph<6> _6{}; +constexpr __ph<7> _7{}; +constexpr __ph<8> _8{}; +constexpr __ph<9> _9{}; +constexpr __ph<10> _10{}; +#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_BIND) } // placeholders @@ -2468,6 +2488,22 @@ struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned long long> { }; +#ifndef _LIBCPP_HAS_NO_INT128 + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash<__int128_t> + : public __scalar_hash<__int128_t> +{ +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash<__uint128_t> + : public __scalar_hash<__uint128_t> +{ +}; + +#endif + template <> struct _LIBCPP_TYPE_VIS_ONLY hash<float> : public __scalar_hash<float> @@ -2564,11 +2600,69 @@ struct _LIBCPP_TYPE_VIS_ONLY hash #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)...); +invoke(_Fn&& __f, _Args&&... __args) + noexcept(noexcept(_VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...))) +{ + return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); +} + +template <class _DecayFunc> +class _LIBCPP_TYPE_VIS_ONLY __not_fn_imp { + _DecayFunc __fd; + +public: + __not_fn_imp() = delete; + + template <class ..._Args> + _LIBCPP_INLINE_VISIBILITY + auto operator()(_Args&& ...__args) & + noexcept(noexcept(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...))) + -> decltype(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)) + { return !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); } + + template <class ..._Args> + _LIBCPP_INLINE_VISIBILITY + auto operator()(_Args&& ...__args) && + noexcept(noexcept(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...))) + -> decltype(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...)) + { return !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...); } + + template <class ..._Args> + _LIBCPP_INLINE_VISIBILITY + auto operator()(_Args&& ...__args) const& + noexcept(noexcept(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...))) + -> decltype(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)) + { return !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); } + + + template <class ..._Args> + _LIBCPP_INLINE_VISIBILITY + auto operator()(_Args&& ...__args) const&& + noexcept(noexcept(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...))) + -> decltype(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...)) + { return !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...); } + +private: + template <class _RawFunc, + class = enable_if_t<!is_same<decay_t<_RawFunc>, __not_fn_imp>::value>> + _LIBCPP_INLINE_VISIBILITY + explicit __not_fn_imp(_RawFunc&& __rf) + : __fd(_VSTD::forward<_RawFunc>(__rf)) {} + + template <class _RawFunc> + friend inline _LIBCPP_INLINE_VISIBILITY + __not_fn_imp<decay_t<_RawFunc>> not_fn(_RawFunc&&); +}; + +template <class _RawFunc> +inline _LIBCPP_INLINE_VISIBILITY +__not_fn_imp<decay_t<_RawFunc>> not_fn(_RawFunc&& __fn) { + return __not_fn_imp<decay_t<_RawFunc>>(_VSTD::forward<_RawFunc>(__fn)); } + #endif // struct hash<T*> in <memory> diff --git a/include/future b/include/future index ce15eafbf7e4c..936060e173b83 100644 --- a/include/future +++ b/include/future @@ -322,7 +322,7 @@ template <class R, class... ArgTypes> class packaged_task<R(ArgTypes...)> { public: - typedef R result_type; + typedef R result_type; // extension // construction and destruction packaged_task() noexcept; @@ -1482,6 +1482,7 @@ template <class _Rp> void promise<_Rp>::set_exception(exception_ptr __p) { + _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" ); if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_exception(__p); @@ -1513,6 +1514,7 @@ template <class _Rp> void promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) { + _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_exception_at_thread_exit(__p); @@ -1629,6 +1631,7 @@ template <class _Rp> void promise<_Rp&>::set_exception(exception_ptr __p) { + _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" ); if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_exception(__p); @@ -1647,6 +1650,7 @@ template <class _Rp> void promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) { + _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_exception_at_thread_exit(__p); @@ -1994,7 +1998,7 @@ template<class _Rp, class ..._ArgTypes> class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)> { public: - typedef _Rp result_type; + typedef _Rp result_type; // extension private: __packaged_task_function<result_type(_ArgTypes...)> __f_; @@ -2123,7 +2127,7 @@ template<class ..._ArgTypes> class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)> { public: - typedef void result_type; + typedef void result_type; // extension private: __packaged_task_function<result_type(_ArgTypes...)> __f_; diff --git a/include/iomanip b/include/iomanip index a5042c7df8105..9efcbe03d1ae7 100644 --- a/include/iomanip +++ b/include/iomanip @@ -512,8 +512,6 @@ put_time(const tm* __tm, const _CharT* __fmt) return __iom_t10<_CharT>(__tm, __fmt); } -#if _LIBCPP_STD_VER > 11 - template <class _CharT, class _Traits, class _ForwardIterator> std::basic_ostream<_CharT, _Traits> & __quoted_output ( basic_ostream<_CharT, _Traits> &__os, @@ -569,7 +567,7 @@ __quoted_input ( basic_istream<_CharT, _Traits> &__is, _String & __string, _Char } -template <class _CharT, class _Iter, class _Traits=char_traits<_CharT>> +template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> > struct __quoted_output_proxy { _Iter __first; @@ -631,22 +629,43 @@ quoted ( const _CharT *__s, _CharT __delim = _CharT('"'), _CharT __escape =_Char return __quoted_output_proxy<_CharT, const _CharT *> ( __s, __end, __delim, __escape ); } + template <class _CharT, class _Traits, class _Allocator> _LIBCPP_INLINE_VISIBILITY __quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> -quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +__quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) { - return __quoted_output_proxy<_CharT, - typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> + return __quoted_output_proxy<_CharT, + typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> ( __s.cbegin(), __s.cend (), __delim, __escape ); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_INLINE_VISIBILITY __quoted_proxy<_CharT, _Traits, _Allocator> -quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +__quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) { return __quoted_proxy<_CharT, _Traits, _Allocator>( __s, __delim, __escape ); } + + +#if _LIBCPP_STD_VER > 11 + +template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_INLINE_VISIBILITY +__quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> +quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +{ + return __quoted(__s, __delim, __escape); +} + +template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_INLINE_VISIBILITY +__quoted_proxy<_CharT, _Traits, _Allocator> +quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +{ + return __quoted(__s, __delim, __escape); +} #endif _LIBCPP_END_NAMESPACE_STD diff --git a/include/ios b/include/ios index 1deb5f613c8a5..cbea478a74a88 100644 --- a/include/ios +++ b/include/ios @@ -231,7 +231,7 @@ typedef ptrdiff_t streamsize; class _LIBCPP_TYPE_VIS ios_base { public: - class _LIBCPP_TYPE_VIS failure; + class _LIBCPP_EXCEPTION_ABI failure; typedef unsigned int fmtflags; static const fmtflags boolalpha = 0x0001; diff --git a/include/iosfwd b/include/iosfwd index eccfd349a4a58..e4149ef22378d 100644 --- a/include/iosfwd +++ b/include/iosfwd @@ -194,6 +194,11 @@ template <class _CharT, // for <stdexcept> typedef basic_string<char, char_traits<char>, allocator<char> > string; typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring; + +// Include other forward declarations here +template <class _Tp, class _Alloc = allocator<_Tp> > +class _LIBCPP_TYPE_VIS_ONLY vector; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_IOSFWD diff --git a/include/istream b/include/istream index 0bcc7eeaf6398..ee694003a3d89 100644 --- a/include/istream +++ b/include/istream @@ -1251,18 +1251,35 @@ streamsize basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n) { __gc_ = 0; - streamsize __c = this->rdbuf()->in_avail(); - switch (__c) - { - case -1: - this->setstate(ios_base::eofbit); - break; - case 0: - break; - default: - read(__s, _VSTD::min(__c, __n)); - break; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __sen(*this, true); + if (__sen) + { + streamsize __c = this->rdbuf()->in_avail(); + switch (__c) + { + case -1: + this->setstate(ios_base::eofbit); + break; + case 0: + break; + default: + read(__s, _VSTD::min(__c, __n)); + break; + } + } + else + this->setstate(ios_base::failbit); +#ifndef _LIBCPP_NO_EXCEPTIONS } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS return __gc_; } diff --git a/include/iterator b/include/iterator index 8d9b31101bdf9..abd142e85aa3d 100644 --- a/include/iterator +++ b/include/iterator @@ -131,8 +131,9 @@ bool operator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -typename reverse_iterator<Iterator1>::difference_type -operator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); +auto +operator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y) +-> decltype(__y.base() - __x.base()); template <class Iterator> reverse_iterator<Iterator> @@ -149,7 +150,7 @@ public: typedef Container container_type; typedef void value_type; typedef void difference_type; - typedef back_insert_iterator<Cont>& reference; + typedef void reference; typedef void pointer; explicit back_insert_iterator(Container& x); @@ -170,7 +171,7 @@ public: typedef Container container_type; typedef void value_type; typedef void difference_type; - typedef front_insert_iterator<Cont>& reference; + typedef void reference; typedef void pointer; explicit front_insert_iterator(Container& x); @@ -192,7 +193,7 @@ public: typedef Container container_type; typedef void value_type; typedef void difference_type; - typedef insert_iterator<Cont>& reference; + typedef void reference; typedef void pointer; insert_iterator(Container& x, typename Container::iterator i); @@ -205,6 +206,73 @@ public: template <class Container, class Iterator> insert_iterator<Container> inserter(Container& x, Iterator i); +template <class Iterator> +class move_iterator { +public: + typedef Iterator iterator_type; + typedef typename iterator_traits<Iterator>::difference_type difference_type; + typedef Iterator pointer; + typedef typename iterator_traits<Iterator>::value_type value_type; + typedef typename iterator_traits<Iterator>::iterator_category iterator_category; + typedef value_type&& reference; + + move_iterator(); + explicit move_iterator(Iterator i); + template <class U> move_iterator(const move_iterator<U>& u); + template <class U> move_iterator& operator=(const move_iterator<U>& u); + iterator_type base() const; + reference operator*() const; + pointer operator->() const; + move_iterator& operator++(); + move_iterator operator++(int); + move_iterator& operator--(); + move_iterator operator--(int); + move_iterator operator+(difference_type n) const; + move_iterator& operator+=(difference_type n); + move_iterator operator-(difference_type n) const; + move_iterator& operator-=(difference_type n); + unspecified operator[](difference_type n) const; +private: + Iterator current; // exposition only +}; + +template <class Iterator1, class Iterator2> +bool +operator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +auto +operator-(const move_iterator<Iterator1>& x, + const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base()); + +template <class Iterator> +move_iterator<Iterator> operator+(typename move_iterator<Iterator>::difference_type n, + const move_iterator<Iterator>& x); + +template <class Iterator> +move_iterator<Iterator> make_move_iterator(const Iterator& i); + + template <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t> class istream_iterator : public iterator<input_iterator_tag, T, Distance, const T*, const T&> @@ -340,10 +408,10 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept; */ #include <__config> +#include <iosfwd> // for forward declarations of vector and string. #include <__functional_base> #include <type_traits> #include <cstddef> -#include <iosfwd> #include <initializer_list> #ifdef __APPLE__ #include <Availability.h> @@ -632,6 +700,16 @@ operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& return __x.base() >= __y.base(); } +#ifndef _LIBCPP_CXX03_LANG +template <class _Iter1, class _Iter2> +inline _LIBCPP_INLINE_VISIBILITY +auto +operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +-> decltype(__y.base() - __x.base()) +{ + return __y.base() - __x.base(); +} +#else template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY typename reverse_iterator<_Iter1>::difference_type @@ -639,6 +717,7 @@ operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& _ { return __y.base() - __x.base(); } +#endif template <class _Iter> inline _LIBCPP_INLINE_VISIBILITY @@ -663,7 +742,7 @@ class _LIBCPP_TYPE_VIS_ONLY back_insert_iterator void, void, void, - back_insert_iterator<_Container>&> + void> { protected: _Container* container; @@ -696,7 +775,7 @@ class _LIBCPP_TYPE_VIS_ONLY front_insert_iterator void, void, void, - front_insert_iterator<_Container>&> + void> { protected: _Container* container; @@ -729,7 +808,7 @@ class _LIBCPP_TYPE_VIS_ONLY insert_iterator void, void, void, - insert_iterator<_Container>&> + void> { protected: _Container* container; @@ -772,14 +851,14 @@ private: _Tp __value_; public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(0), __value_() {} - _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(&__s) + _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s)) { if (!(*__in_stream_ >> __value_)) __in_stream_ = 0; } _LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;} - _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return &(operator*());} + _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return _VSTD::addressof((operator*()));} _LIBCPP_INLINE_VISIBILITY istream_iterator& operator++() { if (!(*__in_stream_ >> __value_)) @@ -811,9 +890,9 @@ private: const char_type* __delim_; public: _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) - : __out_stream_(&__s), __delim_(0) {} + : __out_stream_(_VSTD::addressof(__s)), __delim_(0) {} _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) - : __out_stream_(&__s), __delim_(__delimiter) {} + : __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {} _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_) { *__out_stream_ << __value_; @@ -949,9 +1028,14 @@ public: typedef typename iterator_traits<iterator_type>::iterator_category iterator_category; typedef typename iterator_traits<iterator_type>::value_type value_type; typedef typename iterator_traits<iterator_type>::difference_type difference_type; - typedef typename iterator_traits<iterator_type>::pointer pointer; + typedef iterator_type pointer; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - typedef value_type&& reference; + typedef typename iterator_traits<iterator_type>::reference __reference; + typedef typename conditional< + is_reference<__reference>::value, + typename remove_reference<__reference>::type&&, + __reference + >::type reference; #else typedef typename iterator_traits<iterator_type>::reference reference; #endif @@ -964,10 +1048,7 @@ public: _LIBCPP_INLINE_VISIBILITY reference operator*() const { return static_cast<reference>(*__i); } - _LIBCPP_INLINE_VISIBILITY pointer operator->() const { - typename iterator_traits<iterator_type>::reference __ref = *__i; - return &__ref; - } + _LIBCPP_INLINE_VISIBILITY pointer operator->() const { return __i;} _LIBCPP_INLINE_VISIBILITY move_iterator& operator++() {++__i; return *this;} _LIBCPP_INLINE_VISIBILITY move_iterator operator++(int) {move_iterator __tmp(*this); ++__i; return __tmp;} @@ -1036,6 +1117,16 @@ operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) return __x.base() <= __y.base(); } +#ifndef _LIBCPP_CXX03_LANG +template <class _Iter1, class _Iter2> +inline _LIBCPP_INLINE_VISIBILITY +auto +operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +-> decltype(__x.base() - __y.base()) +{ + return __x.base() - __y.base(); +} +#else template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY typename move_iterator<_Iter1>::difference_type @@ -1043,6 +1134,7 @@ operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { return __x.base() - __y.base(); } +#endif template <class _Iter> inline _LIBCPP_INLINE_VISIBILITY @@ -1094,10 +1186,18 @@ _LIBCPP_INLINE_VISIBILITY bool operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +#ifndef _LIBCPP_CXX03_LANG +template <class _Iter1, class _Iter2> +_LIBCPP_INLINE_VISIBILITY +auto +operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +-> decltype(__x.base() - __y.base()); +#else template <class _Iter1, class _Iter2> _LIBCPP_INLINE_VISIBILITY typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +#endif template <class _Iter> _LIBCPP_INLINE_VISIBILITY @@ -1185,7 +1285,7 @@ public: _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to dereference a non-dereferenceable iterator"); #endif - return (pointer)&reinterpret_cast<const volatile char&>(*__i); + return (pointer)_VSTD::addressof(*__i); } _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT { @@ -1279,10 +1379,18 @@ private: bool operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +#ifndef _LIBCPP_CXX03_LANG + template <class _Iter1, class _Iter2> + friend + auto + operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT + -> decltype(__x.base() - __y.base()); +#else template <class _Iter1, class _Iter2> friend typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +#endif template <class _Iter1> friend @@ -1388,6 +1496,20 @@ operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEX return !(__y < __x); } +#ifndef _LIBCPP_CXX03_LANG +template <class _Iter1, class _Iter2> +inline _LIBCPP_INLINE_VISIBILITY +auto +operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +-> decltype(__x.base() - __y.base()) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), + "Attempted to subtract incompatible iterators"); +#endif + return __x.base() - __y.base(); +} +#else template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY typename __wrap_iter<_Iter1>::difference_type @@ -1399,6 +1521,7 @@ operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC #endif return __x.base() - __y.base(); } +#endif template <class _Iter> inline _LIBCPP_INLINE_VISIBILITY diff --git a/include/list b/include/list index 44b20e2fa28cc..cff0a853eff9c 100644 --- a/include/list +++ b/include/list @@ -570,10 +570,13 @@ protected: const __node_allocator& __node_alloc() const _NOEXCEPT {return __size_alloc_.second();} + _LIBCPP_INLINE_VISIBILITY static void __unlink_nodes(__link_pointer __f, __link_pointer __l) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY __list_imp() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value); + _LIBCPP_INLINE_VISIBILITY __list_imp(const allocator_type& __a); ~__list_imp(); void clear() _NOEXCEPT; @@ -666,7 +669,7 @@ private: // Unlink nodes [__f, __l] template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void __list_imp<_Tp, _Alloc>::__unlink_nodes(__link_pointer __f, __link_pointer __l) _NOEXCEPT @@ -676,7 +679,7 @@ __list_imp<_Tp, _Alloc>::__unlink_nodes(__link_pointer __f, __link_pointer __l) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline __list_imp<_Tp, _Alloc>::__list_imp() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) : __size_alloc_(0) @@ -684,7 +687,7 @@ __list_imp<_Tp, _Alloc>::__list_imp() } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline __list_imp<_Tp, _Alloc>::__list_imp(const allocator_type& __a) : __size_alloc_(0, __node_allocator(__a)) { @@ -858,15 +861,19 @@ public: list(const list& __c); list(const list& __c, const allocator_type& __a); + _LIBCPP_INLINE_VISIBILITY list& operator=(const list& __c); #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS list(initializer_list<value_type> __il); list(initializer_list<value_type> __il, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY list(list&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value); + _LIBCPP_INLINE_VISIBILITY list(list&& __c, const allocator_type& __a); + _LIBCPP_INLINE_VISIBILITY list& operator=(list&& __c) _NOEXCEPT_( __node_alloc_traits::propagate_on_container_move_assignment::value && @@ -888,6 +895,7 @@ public: {assign(__il.begin(), __il.end());} #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY @@ -1024,9 +1032,11 @@ public: void remove(const value_type& __x); template <class _Pred> void remove_if(_Pred __pred); + _LIBCPP_INLINE_VISIBILITY void unique(); template <class _BinaryPred> void unique(_BinaryPred __binary_pred); + _LIBCPP_INLINE_VISIBILITY void merge(list& __c); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY @@ -1039,8 +1049,10 @@ public: _LIBCPP_INLINE_VISIBILITY void merge(list&& __c, _Comp __comp) {merge(__c, __comp);} #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY void sort(); template <class _Comp> + _LIBCPP_INLINE_VISIBILITY void sort(_Comp __comp); void reverse() _NOEXCEPT; @@ -1057,8 +1069,11 @@ public: #endif // _LIBCPP_DEBUG_LEVEL >= 2 private: + _LIBCPP_INLINE_VISIBILITY static void __link_nodes (__link_pointer __p, __link_pointer __f, __link_pointer __l); + _LIBCPP_INLINE_VISIBILITY void __link_nodes_at_front(__link_pointer __f, __link_pointer __l); + _LIBCPP_INLINE_VISIBILITY void __link_nodes_at_back (__link_pointer __f, __link_pointer __l); iterator __iterator(size_type __n); template <class _Comp> @@ -1071,7 +1086,7 @@ private: // Link in nodes [__f, __l] just prior to __p template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::__link_nodes(__link_pointer __p, __link_pointer __f, __link_pointer __l) { @@ -1083,7 +1098,7 @@ list<_Tp, _Alloc>::__link_nodes(__link_pointer __p, __link_pointer __f, __link_p // Link in nodes [__f, __l] at the front of the list template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l) { @@ -1095,7 +1110,7 @@ list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l) // Link in nodes [__f, __l] at the front of the list template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::__link_nodes_at_back(__link_pointer __f, __link_pointer __l) { @@ -1107,7 +1122,7 @@ list<_Tp, _Alloc>::__link_nodes_at_back(__link_pointer __f, __link_pointer __l) template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::__iterator(size_type __n) { @@ -1243,7 +1258,7 @@ list<_Tp, _Alloc>::list(initializer_list<value_type> __il) #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list& __c) { @@ -1258,7 +1273,7 @@ list<_Tp, _Alloc>::operator=(const list& __c) #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline list<_Tp, _Alloc>::list(list&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) : base(allocator_type(_VSTD::move(__c.__node_alloc()))) @@ -1270,7 +1285,7 @@ list<_Tp, _Alloc>::list(list&& __c) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline list<_Tp, _Alloc>::list(list&& __c, const allocator_type& __a) : base(__a) { @@ -1287,7 +1302,7 @@ list<_Tp, _Alloc>::list(list&& __c, const allocator_type& __a) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(list&& __c) _NOEXCEPT_( @@ -1355,7 +1370,7 @@ list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline _Alloc list<_Tp, _Alloc>::get_allocator() const _NOEXCEPT { @@ -2108,7 +2123,7 @@ list<_Tp, _Alloc>::remove_if(_Pred __pred) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::unique() { @@ -2131,7 +2146,7 @@ list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::merge(list& __c) { @@ -2193,7 +2208,7 @@ list<_Tp, _Alloc>::merge(list& __c, _Comp __comp) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::sort() { @@ -2202,7 +2217,7 @@ list<_Tp, _Alloc>::sort() template <class _Tp, class _Alloc> template <class _Comp> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::sort(_Comp __comp) { diff --git a/include/locale b/include/locale index 84cb5a5ef6cd7..3d804e86f4d1a 100644 --- a/include/locale +++ b/include/locale @@ -180,6 +180,7 @@ template <class charT> class messages_byname; #include <__config> #include <__locale> +#include <__debug> #include <algorithm> #include <memory> #include <ios> @@ -213,6 +214,12 @@ template <class charT> class messages_byname; #pragma GCC system_header #endif +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS +#include <__bsd_locale_defaults.h> +#else +#include <__bsd_locale_fallbacks.h> +#endif + _LIBCPP_BEGIN_NAMESPACE_STD #if defined(__APPLE__) || defined(__FreeBSD__) @@ -228,189 +235,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD typedef _VSTD::remove_pointer<locale_t>::type __locale_struct; typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr; -#ifndef _LIBCPP_LOCALE__L_EXTENSIONS -typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii; -#endif - -// OSX has nice foo_l() functions that let you turn off use of the global -// 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(__GLIBC__) - -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS -decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>())) -inline _LIBCPP_INLINE_VISIBILITY -__mb_cur_max_l(locale_t __l) -{ - return MB_CUR_MAX_L(__l); -} -#else // _LIBCPP_LOCALE__L_EXTENSIONS -inline _LIBCPP_ALWAYS_INLINE -decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l) -{ - __locale_raii __current(uselocale(__l), uselocale); - return MB_CUR_MAX; -} -#endif // _LIBCPP_LOCALE__L_EXTENSIONS - -inline _LIBCPP_ALWAYS_INLINE -wint_t __btowc_l(int __c, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return btowc_l(__c, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return btowc(__c); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -int __wctob_l(wint_t __c, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return wctob_l(__c, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return wctob(__c); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, - size_t __len, mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return wcsnrtombs(__dest, __src, __nwc, __len, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return wcrtomb_l(__s, __wc, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return wcrtomb(__s, __wc, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, - size_t __len, mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbsnrtowcs(__dest, __src, __nms, __len, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, - mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbrtowc_l(__pwc, __s, __n, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbrtowc(__pwc, __s, __n, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbtowc_l(__pwc, __pmb, __max, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbtowc(__pwc, __pmb, __max); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbrlen_l(__s, __n, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbrlen(__s, __n, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -lconv *__localeconv_l(locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return localeconv_l(__l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return localeconv(); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, - mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbsrtowcs_l(__dest, __src, __len, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbsrtowcs(__dest, __src, __len, __ps); -#endif -} - -inline -int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { - va_list __va; - va_start(__va, __format); -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __res = vsnprintf_l(__s, __n, __l, __format, __va); -#else - __locale_raii __current(uselocale(__l), uselocale); - int __res = vsnprintf(__s, __n, __format, __va); -#endif - va_end(__va); - return __res; -} - -inline -int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) { - va_list __va; - va_start(__va, __format); -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __res = vasprintf_l(__s, __l, __format, __va); -#else - __locale_raii __current(uselocale(__l), uselocale); - int __res = vasprintf(__s, __format, __va); -#endif - va_end(__va); - return __res; -} - -inline -int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { - va_list __va; - va_start(__va, __format); -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __res = vsscanf_l(__s, __l, __format, __va); -#else - __locale_raii __current(uselocale(__l), uselocale); - int __res = vsscanf(__s, __format, __va); -#endif - va_end(__va); - return __res; -} - -#endif // __linux__ // __scan_keyword // Scans [__b, __e) until a match is found in the basic_strings range @@ -933,6 +757,28 @@ __num_get_unsigned_integral(const char* __a, const char* __a_end, } template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_Tp __do_strtod(const char* __a, char** __p2); + +template <> +inline _LIBCPP_INLINE_VISIBILITY +float __do_strtod<float>(const char* __a, char** __p2) { + return strtof_l(__a, __p2, _LIBCPP_GET_C_LOCALE); +} + +template <> +inline _LIBCPP_INLINE_VISIBILITY +double __do_strtod<double>(const char* __a, char** __p2) { + return strtod_l(__a, __p2, _LIBCPP_GET_C_LOCALE); +} + +template <> +inline _LIBCPP_INLINE_VISIBILITY +long double __do_strtod<long double>(const char* __a, char** __p2) { + return strtold_l(__a, __p2, _LIBCPP_GET_C_LOCALE); +} + +template <class _Tp> _Tp __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) { @@ -941,7 +787,7 @@ __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) typename remove_reference<decltype(errno)>::type __save_errno = errno; errno = 0; char *__p2; - long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE); + _Tp __ld = __do_strtod<_Tp>(__a, &__p2); typename remove_reference<decltype(errno)>::type __current_errno = errno; if (__current_errno == 0) errno = __save_errno; @@ -952,7 +798,7 @@ __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) } else if (__current_errno == ERANGE) __err = ios_base::failbit; - return static_cast<_Tp>(__ld); + return __ld; } __err = ios_base::failbit; return 0; @@ -1188,11 +1034,7 @@ num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, } // Stage 3 __buf.resize(__a_end - __a); -#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(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) -#endif + if (__libcpp_sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) __err = ios_base::failbit; // EOF checked if (__b == __e) @@ -1556,13 +1398,9 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, this->__format_int(__fmt+1, __len, true, __iob.flags()); const unsigned __nbuf = (numeric_limits<long>::digits / 3) + ((numeric_limits<long>::digits % 3) != 0) - + 1; + + 2; char __nar[__nbuf]; -#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), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1588,11 +1426,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits<long long>::digits % 3) != 0) + 2; char __nar[__nbuf]; -#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), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1618,11 +1452,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits<unsigned long>::digits % 3) != 0) + 1; char __nar[__nbuf]; -#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), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1648,11 +1478,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits<unsigned long long>::digits % 3) != 0) + 1; char __nar[__nbuf]; -#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), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1679,34 +1505,17 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char* __nb = __nar; int __nc; if (__specify_precision) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, + __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#else - __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, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); unique_ptr<char, void(*)(void*)> __nbh(0, free); if (__nc > static_cast<int>(__nbuf-1)) { if (__specify_precision) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#else - __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#endif + __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); else -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#endif + __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); if (__nb == 0) __throw_bad_alloc(); __nbh.reset(__nb); @@ -1747,34 +1556,17 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char* __nb = __nar; int __nc; if (__specify_precision) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, - (int)__iob.precision(), __v); -#else - __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, + __nc = __libcpp_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, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); unique_ptr<char, void(*)(void*)> __nbh(0, free); if (__nc > static_cast<int>(__nbuf-1)) { if (__specify_precision) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#else - __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#endif + __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); else -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); if (__nb == 0) __throw_bad_alloc(); __nbh.reset(__nb); @@ -1810,11 +1602,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char __fmt[6] = "%p"; const unsigned __nbuf = 20; char __nar[__nbuf]; -#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), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar @@ -3526,11 +3314,7 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, // secure memory for digit storage if (__n > __bs-1) { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units)); -#else - __n = __asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units); -#endif + __n = static_cast<size_t>(__libcpp_asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units)); if (__bb == 0) __throw_bad_alloc(); __hn.reset(__bb); @@ -3850,7 +3634,7 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)), __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)), __cvtptr_(__wc.__cvtptr_), - __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_) + __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtcount_) { __wc.__cvtptr_ = nullptr; } @@ -4140,7 +3924,9 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow() } else { - memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); + _LIBCPP_ASSERT(!(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" ); + if (__extbufend_ != __extbufnext_) + memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz), diff --git a/include/map b/include/map index 87add437a5452..b8aa7a6d7a5d1 100644 --- a/include/map +++ b/include/map @@ -162,7 +162,7 @@ public: void swap(map& m) noexcept(allocator_traits<allocator_type>::is_always_equal::value && - __is_nothrow_swappable<key_compare>::value); // C++17 + is_nothrow_swappable<key_compare>::value); // C++17 // observers: allocator_type get_allocator() const noexcept; @@ -357,7 +357,7 @@ public: void swap(multimap& m) noexcept(allocator_traits<allocator_type>::is_always_equal::value && - __is_nothrow_swappable<key_compare>::value); // C++17 + is_nothrow_swappable<key_compare>::value); // C++17 // observers: allocator_type get_allocator() const noexcept; @@ -564,13 +564,11 @@ class __map_node_destructor { typedef _Allocator allocator_type; typedef allocator_traits<allocator_type> __alloc_traits; - typedef typename __alloc_traits::value_type::value_type value_type; + public: typedef typename __alloc_traits::pointer pointer; -private: - typedef typename value_type::value_type::first_type first_type; - typedef typename value_type::value_type::second_type second_type; +private: allocator_type& __na_; __map_node_destructor& operator=(const __map_node_destructor&); @@ -615,7 +613,7 @@ template <class _Key, class _Tp, class _Compare, class _Allocator> class multimap; template <class _TreeIterator> class __map_const_iterator; -#if __cplusplus >= 201103L +#ifndef _LIBCPP_CXX03_LANG template <class _Key, class _Tp> union __value_type @@ -628,33 +626,29 @@ union __value_type value_type __cc; __nc_value_type __nc; - template <class ..._Args> - _LIBCPP_INLINE_VISIBILITY - __value_type(_Args&& ...__args) - : __cc(std::forward<_Args>(__args)...) {} - - _LIBCPP_INLINE_VISIBILITY - __value_type(const __value_type& __v) - : __cc(__v.__cc) {} - - _LIBCPP_INLINE_VISIBILITY - __value_type(__value_type& __v) - : __cc(__v.__cc) {} - - _LIBCPP_INLINE_VISIBILITY - __value_type(__value_type&& __v) - : __nc(std::move(__v.__nc)) {} - _LIBCPP_INLINE_VISIBILITY __value_type& operator=(const __value_type& __v) {__nc = __v.__cc; return *this;} _LIBCPP_INLINE_VISIBILITY __value_type& operator=(__value_type&& __v) - {__nc = std::move(__v.__nc); return *this;} + {__nc = _VSTD::move(__v.__nc); return *this;} + template <class _ValueTp, + class = typename enable_if< + __is_same_uncvref<_ValueTp, value_type>::value + >::type + > _LIBCPP_INLINE_VISIBILITY - ~__value_type() {__cc.~value_type();} + __value_type& operator=(_ValueTp&& __v) { + __nc = _VSTD::forward<_ValueTp>(__v); return *this; + } + +private: + __value_type() _LIBCPP_EQUAL_DELETE; + ~__value_type() _LIBCPP_EQUAL_DELETE; + __value_type(const __value_type& __v) _LIBCPP_EQUAL_DELETE; + __value_type(__value_type&& __v) _LIBCPP_EQUAL_DELETE; }; #else @@ -668,18 +662,11 @@ struct __value_type value_type __cc; - _LIBCPP_INLINE_VISIBILITY - __value_type() {} - - template <class _A0> - _LIBCPP_INLINE_VISIBILITY - __value_type(const _A0& __a0) - : __cc(__a0) {} - - template <class _A0, class _A1> - _LIBCPP_INLINE_VISIBILITY - __value_type(const _A0& __a0, const _A1& __a1) - : __cc(__a0, __a1) {} +private: + __value_type(); + __value_type(__value_type const&); + __value_type& operator=(__value_type const&); + ~__value_type(); }; #endif @@ -697,19 +684,17 @@ struct __extract_key_value_types<__value_type<_Key, _Tp> > template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_iterator { + typedef typename _TreeIterator::_NodeTypes _NodeTypes; + typedef typename _TreeIterator::__pointer_traits __pointer_traits; + _TreeIterator __i_; - typedef typename _TreeIterator::__pointer_traits __pointer_traits; - typedef typename _TreeIterator::value_type __value_type; - typedef typename __extract_key_value_types<__value_type>::__key_type __key_type; - typedef typename __extract_key_value_types<__value_type>::__mapped_type __mapped_type; public: typedef bidirectional_iterator_tag iterator_category; - typedef pair<__key_type, __mapped_type> value_type; + typedef typename _NodeTypes::__map_value_type value_type; typedef typename _TreeIterator::difference_type difference_type; typedef value_type& reference; - typedef typename __rebind_pointer<typename __pointer_traits::pointer, value_type>::type - pointer; + typedef typename _NodeTypes::__map_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __map_iterator() _NOEXCEPT {} @@ -758,19 +743,17 @@ public: template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator { + typedef typename _TreeIterator::_NodeTypes _NodeTypes; + typedef typename _TreeIterator::__pointer_traits __pointer_traits; + _TreeIterator __i_; - typedef typename _TreeIterator::__pointer_traits __pointer_traits; - typedef typename _TreeIterator::value_type __value_type; - typedef typename __extract_key_value_types<__value_type>::__key_type __key_type; - typedef typename __extract_key_value_types<__value_type>::__mapped_type __mapped_type; public: typedef bidirectional_iterator_tag iterator_category; - typedef pair<__key_type, __mapped_type> value_type; + typedef typename _NodeTypes::__map_value_type value_type; typedef typename _TreeIterator::difference_type difference_type; typedef const value_type& reference; - typedef typename __rebind_pointer<typename __pointer_traits::pointer, const value_type>::type - pointer; + typedef typename _NodeTypes::__const_map_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __map_const_iterator() _NOEXCEPT {} @@ -927,7 +910,7 @@ public: _LIBCPP_INLINE_VISIBILITY map& operator=(const map& __m) { -#if __cplusplus >= 201103L +#ifndef _LIBCPP_CXX03_LANG __tree_ = __m.__tree_; #else if (this != &__m) { @@ -1043,7 +1026,7 @@ public: size_type max_size() const _NOEXCEPT {return __tree_.max_size();} mapped_type& operator[](const key_type& __k); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG mapped_type& operator[](key_type&& __k); #endif @@ -1057,18 +1040,18 @@ public: _LIBCPP_INLINE_VISIBILITY value_compare value_comp() const {return value_compare(__tree_.value_comp().key_comp());} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS - +#ifndef _LIBCPP_CXX03_LANG template <class ..._Args> - pair<iterator, bool> - emplace(_Args&& ...__args); + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> emplace(_Args&& ...__args) { + return __tree_.__emplace_unique(_VSTD::forward<_Args>(__args)...); + } template <class ..._Args> - iterator - emplace_hint(const_iterator __p, _Args&& ...__args); - -#endif // _LIBCPP_HAS_NO_VARIADICS + _LIBCPP_INLINE_VISIBILITY + iterator emplace_hint(const_iterator __p, _Args&& ...__args) { + return __tree_.__emplace_hint_unique(__p.__i_, _VSTD::forward<_Args>(__args)...); + } template <class _Pp, class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> @@ -1082,7 +1065,7 @@ public: iterator insert(const_iterator __pos, _Pp&& __p) {return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> @@ -1093,15 +1076,14 @@ public: insert(const_iterator __p, const value_type& __v) {return __tree_.__insert_unique(__p.__i_, __v);} -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) +#ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> - insert( value_type&& __v) {return __tree_.__insert_unique(_VSTD::forward<value_type>(__v));} + insert(value_type&& __v) {return __tree_.__insert_unique(_VSTD::move(__v));} _LIBCPP_INLINE_VISIBILITY - iterator - insert(const_iterator __p, value_type&& __v) - {return __tree_.__insert_unique(__p.__i_, _VSTD::forward<value_type>(__v));} + iterator insert(const_iterator __p, value_type&& __v) + {return __tree_.__insert_unique(__p.__i_, _VSTD::move(__v));} #endif template <class _InputIterator> @@ -1121,62 +1103,45 @@ public: #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); + return __tree_.__emplace_unique_key_args(__k, + _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(__k), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } 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); + return __tree_.__emplace_unique_key_args(__k, + _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(_VSTD::move(__k)), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } 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)...)); + return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, + _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)...)); + return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, + _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(_VSTD::move(__k)), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } template <class _Vp> @@ -1191,7 +1156,7 @@ public: } 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) @@ -1230,8 +1195,7 @@ public: } return emplace_hint(__h, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)); } -#endif -#endif + #endif _LIBCPP_INLINE_VISIBILITY @@ -1332,85 +1296,38 @@ private: typedef typename __base::__node __node; typedef typename __base::__node_allocator __node_allocator; typedef typename __base::__node_pointer __node_pointer; - typedef typename __base::__node_const_pointer __node_const_pointer; typedef typename __base::__node_base_pointer __node_base_pointer; - typedef typename __base::__node_base_const_pointer __node_base_const_pointer; + typedef __map_node_destructor<__node_allocator> _Dp; typedef unique_ptr<__node, _Dp> __node_holder; -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - __node_holder __construct_node(); - template <class _A0> - __node_holder __construct_node(_A0&& __a0); - __node_holder __construct_node_with_key(key_type&& __k); -#ifndef _LIBCPP_HAS_NO_VARIADICS - template <class _A0, class _A1, class ..._Args> - __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args); -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif +#ifdef _LIBCPP_CXX03_LANG __node_holder __construct_node_with_key(const key_type& __k); +#endif + + __node_base_pointer const& + __find_equal_key(__node_base_pointer& __parent, const key_type& __k) const; + _LIBCPP_INLINE_VISIBILITY __node_base_pointer& - __find_equal_key(__node_base_pointer& __parent, const key_type& __k); - __node_base_const_pointer - __find_equal_key(__node_base_const_pointer& __parent, const key_type& __k) const; + __find_equal_key(__node_base_pointer& __parent, const key_type& __k) { + map const* __const_this = this; + return const_cast<__node_base_pointer&>( + __const_this->__find_equal_key(__parent, __k)); + } }; -// Find place to insert if __k doesn't exist -// Set __parent to parent of null leaf -// Return reference to null leaf -// If __k exists, set parent to node of __k and return reference to node of __k -template <class _Key, class _Tp, class _Compare, class _Allocator> -typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer& -map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_pointer& __parent, - const key_type& __k) -{ - __node_pointer __nd = __tree_.__root(); - if (__nd != nullptr) - { - while (true) - { - if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first)) - { - if (__nd->__left_ != nullptr) - __nd = static_cast<__node_pointer>(__nd->__left_); - else - { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent->__left_; - } - } - else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k)) - { - if (__nd->__right_ != nullptr) - __nd = static_cast<__node_pointer>(__nd->__right_); - else - { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent->__right_; - } - } - else - { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent; - } - } - } - __parent = static_cast<__node_base_pointer>(__tree_.__end_node()); - return __parent->__left_; -} // Find __k // Set __parent to parent of null leaf and // return reference to null leaf iv __k does not exist. // If __k exists, set parent to node of __k and return reference to node of __k template <class _Key, class _Tp, class _Compare, class _Allocator> -typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_const_pointer -map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer& __parent, +typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer const& +map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_pointer& __parent, const key_type& __k) const { - __node_const_pointer __nd = __tree_.__root(); + __node_pointer __nd = __tree_.__root(); if (__nd != nullptr) { while (true) @@ -1422,7 +1339,7 @@ map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer else { __parent = static_cast<__node_base_pointer>(__nd); - return const_cast<const __node_base_const_pointer&>(__parent->__left_); + return __parent->__left_; } } else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k)) @@ -1432,7 +1349,7 @@ map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer else { __parent = static_cast<__node_base_pointer>(__nd); - return const_cast<const __node_base_const_pointer&>(__parent->__right_); + return __parent->__right_; } } else @@ -1443,10 +1360,10 @@ map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer } } __parent = static_cast<__node_base_pointer>(__tree_.__end_node()); - return const_cast<const __node_base_const_pointer&>(__parent->__left_); + return __parent->__left_; } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG template <class _Key, class _Tp, class _Compare, class _Allocator> map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a) @@ -1457,69 +1374,14 @@ map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a) const_iterator __e = cend(); while (!__m.empty()) __tree_.__insert_unique(__e.__i_, - _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_)); + _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__nc)); } } -template <class _Key, class _Tp, class _Compare, class _Allocator> -typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder -map<_Key, _Tp, _Compare, _Allocator>::__construct_node() -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first)); - __h.get_deleter().__first_constructed = true; - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class _A0> -typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder -map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0) -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_A0>(__a0)); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Compare, class _Allocator> -typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder -map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(key_type&& __k) -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), _VSTD::move(__k)); - __h.get_deleter().__first_constructed = true; - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); - __h.get_deleter().__second_constructed = true; - return __h; -} - -#ifndef _LIBCPP_HAS_NO_VARIADICS +#endif // !_LIBCPP_CXX03_LANG -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class _A0, class _A1, class ..._Args> -typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder -map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args) -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), - _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1), - _VSTD::forward<_Args>(__args)...); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} -#endif // _LIBCPP_HAS_NO_VARIADICS - -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifdef _LIBCPP_CXX03_LANG template <class _Key, class _Tp, class _Compare, class _Allocator> typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder @@ -1550,25 +1412,29 @@ map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) return __r->__value_.__cc.second; } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#else + +template <class _Key, class _Tp, class _Compare, class _Allocator> +_Tp& +map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) +{ + return __tree_.__emplace_unique_key_args(__k, + _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(__k), + _VSTD::forward_as_tuple()).first->__cc.second; +} template <class _Key, class _Tp, class _Compare, class _Allocator> _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k) { - __node_base_pointer __parent; - __node_base_pointer& __child = __find_equal_key(__parent, __k); - __node_pointer __r = static_cast<__node_pointer>(__child); - if (__child == nullptr) - { - __node_holder __h = __construct_node_with_key(_VSTD::move(__k)); - __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - __r = __h.release(); - } - return __r->__value_.__cc.second; + return __tree_.__emplace_unique_key_args(__k, + _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(_VSTD::move(__k)), + _VSTD::forward_as_tuple()).first->__cc.second; } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // !_LIBCPP_CXX03_LANG template <class _Key, class _Tp, class _Compare, class _Allocator> _Tp& @@ -1587,43 +1453,15 @@ template <class _Key, class _Tp, class _Compare, class _Allocator> const _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const { - __node_base_const_pointer __parent; - __node_base_const_pointer __child = __find_equal_key(__parent, __k); + __node_base_pointer __parent; + __node_base_pointer __child = __find_equal_key(__parent, __k); #ifndef _LIBCPP_NO_EXCEPTIONS if (__child == nullptr) throw out_of_range("map::at: key not found"); #endif // _LIBCPP_NO_EXCEPTIONS - return static_cast<__node_const_pointer>(__child)->__value_.__cc.second; -} - -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class ..._Args> -pair<typename map<_Key, _Tp, _Compare, _Allocator>::iterator, bool> -map<_Key, _Tp, _Compare, _Allocator>::emplace(_Args&& ...__args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - pair<iterator, bool> __r = __tree_.__node_insert_unique(__h.get()); - if (__r.second) - __h.release(); - return __r; -} - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class ..._Args> -typename map<_Key, _Tp, _Compare, _Allocator>::iterator -map<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p, - _Args&& ...__args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - iterator __r = __tree_.__node_insert_unique(__p.__i_, __h.get()); - if (__r.__i_.__ptr_ == __h.get()) - __h.release(); - return __r; + return static_cast<__node_pointer>(__child)->__value_.__cc.second; } -#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) template <class _Key, class _Tp, class _Compare, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY @@ -1799,7 +1637,7 @@ public: _LIBCPP_INLINE_VISIBILITY multimap& operator=(const multimap& __m) { -#if __cplusplus >= 201103L +#ifndef _LIBCPP_CXX03_LANG __tree_ = __m.__tree_; #else if (this != &__m) { @@ -1921,18 +1759,19 @@ public: value_compare value_comp() const {return value_compare(__tree_.value_comp().key_comp());} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_CXX03_LANG template <class ..._Args> - iterator - emplace(_Args&& ...__args); + _LIBCPP_INLINE_VISIBILITY + iterator emplace(_Args&& ...__args) { + return __tree_.__emplace_multi(_VSTD::forward<_Args>(__args)...); + } template <class ..._Args> - iterator - emplace_hint(const_iterator __p, _Args&& ...__args); - -#endif // _LIBCPP_HAS_NO_VARIADICS + _LIBCPP_INLINE_VISIBILITY + iterator emplace_hint(const_iterator __p, _Args&& ...__args) { + return __tree_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...); + } template <class _Pp, class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> @@ -1946,23 +1785,22 @@ public: iterator insert(const_iterator __pos, _Pp&& __p) {return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY - iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);} + iterator insert(value_type&& __v) + {return __tree_.__insert_multi(_VSTD::move(__v));} _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, const value_type& __v) - {return __tree_.__insert_multi(__p.__i_, __v);} + iterator insert(const_iterator __p, value_type&& __v) + {return __tree_.__insert_multi(__p.__i_, _VSTD::move(__v));} + +#endif // _LIBCPP_CXX03_LANG -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) _LIBCPP_INLINE_VISIBILITY - iterator insert( value_type&& __v) {return __tree_.__insert_multi(_VSTD::forward<value_type>(__v));} + iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);} _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, value_type&& __v) - {return __tree_.__insert_multi(__p.__i_, _VSTD::forward<value_type>(__v));} -#endif + iterator insert(const_iterator __p, const value_type& __v) + {return __tree_.__insert_multi(__p.__i_, __v);} template <class _InputIterator> _LIBCPP_INLINE_VISIBILITY @@ -2077,24 +1915,12 @@ private: typedef typename __base::__node __node; typedef typename __base::__node_allocator __node_allocator; typedef typename __base::__node_pointer __node_pointer; - typedef typename __base::__node_const_pointer __node_const_pointer; + typedef __map_node_destructor<__node_allocator> _Dp; typedef unique_ptr<__node, _Dp> __node_holder; - -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - __node_holder __construct_node(); - template <class _A0> - __node_holder - __construct_node(_A0&& __a0); -#ifndef _LIBCPP_HAS_NO_VARIADICS - template <class _A0, class _A1, class ..._Args> - __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args); -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES }; -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - +#ifndef _LIBCPP_CXX03_LANG template <class _Key, class _Tp, class _Compare, class _Allocator> multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a) : __tree_(_VSTD::move(__m.__tree_), __a) @@ -2104,82 +1930,10 @@ multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const alloca const_iterator __e = cend(); while (!__m.empty()) __tree_.__insert_multi(__e.__i_, - _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_)); + _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__nc)); } } - -template <class _Key, class _Tp, class _Compare, class _Allocator> -typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder -multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node() -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first)); - __h.get_deleter().__first_constructed = true; - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class _A0> -typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder -multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0) -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_A0>(__a0)); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -#ifndef _LIBCPP_HAS_NO_VARIADICS - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class _A0, class _A1, class ..._Args> -typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder -multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args) -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), - _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1), - _VSTD::forward<_Args>(__args)...); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class ..._Args> -typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator -multimap<_Key, _Tp, _Compare, _Allocator>::emplace(_Args&& ...__args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - iterator __r = __tree_.__node_insert_multi(__h.get()); - __h.release(); - return __r; -} - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class ..._Args> -typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator -multimap<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p, - _Args&& ...__args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - iterator __r = __tree_.__node_insert_multi(__p.__i_, __h.get()); - __h.release(); - return __r; -} - -#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) +#endif template <class _Key, class _Tp, class _Compare, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY diff --git a/include/memory b/include/memory index 3ef687c1774bf..7a3281e17931c 100644 --- a/include/memory +++ b/include/memory @@ -361,6 +361,7 @@ class shared_ptr { public: typedef T element_type; + typedef weak_ptr<T> weak_type; // C++17 // constructors: constexpr shared_ptr() noexcept; @@ -607,6 +608,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space); #include <__functional_base> #include <iosfwd> #include <tuple> +#include <stdexcept> #include <cstring> #if defined(_LIBCPP_NO_EXCEPTIONS) #include <cassert> @@ -1726,7 +1728,12 @@ public: _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT {return _VSTD::addressof(__x);} _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0) - {return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));} + { + if (__n > max_size()) + __libcpp_throw(length_error("allocator<T>::allocate(size_t n)" + " 'n' exceeds maximum supported size")); + return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp))); + } _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT {_VSTD::__deallocate((void*)__p);} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT @@ -1817,7 +1824,12 @@ public: _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT {return _VSTD::addressof(__x);} _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0) - {return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));} + { + if (__n > max_size()) + __libcpp_throw(length_error("allocator<const T>::allocate(size_t n)" + " 'n' exceeds maximum supported size")); + return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp))); + } _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT {_VSTD::__deallocate((void*)__p);} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT @@ -2548,7 +2560,7 @@ public: typename enable_if<__same_or_less_cv_qualified<_Up*, _Tp*>::value>::type* = 0) const _NOEXCEPT { static_assert(sizeof(_Tp) > 0, "default_delete can not delete incomplete type"); - static_assert(!is_void<_Tp>::value, "default_delete can not delete incomplete type"); + static_assert(!is_void<_Tp>::value, "default_delete can not delete void type"); delete [] __ptr; } }; @@ -2918,7 +2930,6 @@ public: return __t; } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Pp> _LIBCPP_INLINE_VISIBILITY typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value, void>::type @@ -2929,29 +2940,13 @@ public: if (__tmp) __ptr_.second()(__tmp); } - _LIBCPP_INLINE_VISIBILITY void reset(nullptr_t) _NOEXCEPT - { - pointer __tmp = __ptr_.first(); - __ptr_.first() = nullptr; - if (__tmp) - __ptr_.second()(__tmp); - } - _LIBCPP_INLINE_VISIBILITY void reset() _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY void reset(nullptr_t = nullptr) _NOEXCEPT { pointer __tmp = __ptr_.first(); __ptr_.first() = nullptr; if (__tmp) __ptr_.second()(__tmp); } -#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY void reset(pointer __p = pointer()) - { - pointer __tmp = __ptr_.first(); - __ptr_.first() = __p; - if (__tmp) - __ptr_.second()(__tmp); - } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY void swap(unique_ptr& __u) {__ptr_.swap(__u.__ptr_);} private: @@ -2975,7 +2970,10 @@ private: template <class _Tp, class _Dp> inline _LIBCPP_INLINE_VISIBILITY -void +typename enable_if< + __is_swappable<_Dp>::value, + void +>::type swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);} template <class _T1, class _D1, class _T2, class _D2> @@ -3167,8 +3165,6 @@ template<class _Tp, class... _Args> #endif // _LIBCPP_STD_VER > 11 -template <class _Tp> struct hash; - template <class _Size> inline _LIBCPP_INLINE_VISIBILITY _Size @@ -3868,6 +3864,9 @@ class _LIBCPP_TYPE_VIS_ONLY shared_ptr { public: typedef _Tp element_type; +#if _LIBCPP_STD_VER > 14 + typedef weak_ptr<_Tp> weak_type; +#endif private: element_type* __ptr_; __shared_weak_count* __cntrl_; @@ -3979,23 +3978,23 @@ public: _LIBCPP_INLINE_VISIBILITY operator=(shared_ptr<_Yp>&& __r); template<class _Yp> + _LIBCPP_INLINE_VISIBILITY typename enable_if < !is_array<_Yp>::value && is_convertible<_Yp*, element_type*>::value, shared_ptr >::type& - _LIBCPP_INLINE_VISIBILITY operator=(auto_ptr<_Yp>&& __r); #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES template<class _Yp> + _LIBCPP_INLINE_VISIBILITY typename enable_if < !is_array<_Yp>::value && is_convertible<_Yp*, element_type*>::value, shared_ptr& >::type - _LIBCPP_INLINE_VISIBILITY operator=(auto_ptr<_Yp> __r); #endif template <class _Yp, class _Dp> @@ -4120,21 +4119,22 @@ public: private: - template <class _Yp> + template <class _Yp, class _OrigPtr> _LIBCPP_INLINE_VISIBILITY void - __enable_weak_this(const enable_shared_from_this<_Yp>* __e) _NOEXCEPT + __enable_weak_this(const enable_shared_from_this<_Yp>* __e, + _OrigPtr* __ptr) _NOEXCEPT { - if (__e) + typedef typename remove_cv<_Yp>::type _RawYp; + if (__e && __e->__weak_this_.expired()) { - __e->__weak_this_.__ptr_ = const_cast<_Yp*>(static_cast<const _Yp*>(__e)); - __e->__weak_this_.__cntrl_ = __cntrl_; - __cntrl_->__add_weak(); + __e->__weak_this_ = shared_ptr<_RawYp>(*this, + const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr))); } } _LIBCPP_INLINE_VISIBILITY - void __enable_weak_this(const volatile void*) _NOEXCEPT {} + void __enable_weak_this(const volatile void*, 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; @@ -4168,7 +4168,7 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p, typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk; __cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), allocator<_Yp>()); __hold.release(); - __enable_weak_this(__p); + __enable_weak_this(__p, __p); } template<class _Tp> @@ -4183,7 +4183,7 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, #endif // _LIBCPP_NO_EXCEPTIONS typedef __shared_ptr_pointer<_Yp*, _Dp, allocator<_Yp> > _CntrlBlk; __cntrl_ = new _CntrlBlk(__p, __d, allocator<_Yp>()); - __enable_weak_this(__p); + __enable_weak_this(__p, __p); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) @@ -4233,7 +4233,7 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get()))) _CntrlBlk(__p, __d, __a); __cntrl_ = _VSTD::addressof(*__hold2.release()); - __enable_weak_this(__p); + __enable_weak_this(__p, __p); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) @@ -4344,7 +4344,7 @@ shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp> __r, { typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk; __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>()); - __enable_weak_this(__r.get()); + __enable_weak_this(__r.get(), __r.get()); __r.release(); } @@ -4372,7 +4372,7 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r, { typedef __shared_ptr_pointer<_Yp*, _Dp, allocator<_Yp> > _CntrlBlk; __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), allocator<_Yp>()); - __enable_weak_this(__r.get()); + __enable_weak_this(__r.get(), __r.get()); } __r.release(); } @@ -4403,7 +4403,7 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r, 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()); + __enable_weak_this(__r.get(), __r.get()); } __r.release(); } @@ -4424,7 +4424,7 @@ shared_ptr<_Tp>::make_shared(_Args&& ...__args) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4443,7 +4443,7 @@ shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _Args&& ...__args) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = _VSTD::addressof(*__hold2.release()); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4462,7 +4462,7 @@ shared_ptr<_Tp>::make_shared() shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4480,7 +4480,7 @@ shared_ptr<_Tp>::make_shared(_A0& __a0) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4498,7 +4498,7 @@ shared_ptr<_Tp>::make_shared(_A0& __a0, _A1& __a1) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4516,7 +4516,7 @@ shared_ptr<_Tp>::make_shared(_A0& __a0, _A1& __a1, _A2& __a2) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4535,7 +4535,7 @@ shared_ptr<_Tp>::allocate_shared(const _Alloc& __a) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = _VSTD::addressof(*__hold2.release()); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4554,7 +4554,7 @@ shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = _VSTD::addressof(*__hold2.release()); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4573,7 +4573,7 @@ shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = _VSTD::addressof(*__hold2.release()); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4592,7 +4592,7 @@ shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& _ shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = _VSTD::addressof(*__hold2.release()); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -5437,6 +5437,16 @@ public: shared_ptr<_Tp const> shared_from_this() const {return shared_ptr<const _Tp>(__weak_this_);} +#if _LIBCPP_STD_VER > 14 + _LIBCPP_INLINE_VISIBILITY + weak_ptr<_Tp> weak_from_this() _NOEXCEPT + { return __weak_this_; } + + _LIBCPP_INLINE_VISIBILITY + weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT + { return __weak_this_; } +#endif // _LIBCPP_STD_VER > 14 + template <class _Up> friend class shared_ptr; }; @@ -5457,9 +5467,8 @@ inline _LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p); -// TODO(EricWF): Enable this for both Clang and GCC. Currently it is only -// enabled with clang. -#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) + +#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) class _LIBCPP_TYPE_VIS __sp_mut { @@ -5546,14 +5555,17 @@ template <class _Tp> bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) { + shared_ptr<_Tp> __temp; __sp_mut& __m = __get_sp_mut(__p); __m.lock(); if (__p->__owner_equivalent(*__v)) { + _VSTD::swap(__temp, *__p); *__p = __w; __m.unlock(); return true; } + _VSTD::swap(__temp, *__v); *__v = *__p; __m.unlock(); return false; @@ -5585,7 +5597,7 @@ atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v return atomic_compare_exchange_weak(__p, __v, __w); } -#endif // defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) +#endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) //enum class struct _LIBCPP_TYPE_VIS pointer_safety @@ -5623,7 +5635,7 @@ _LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& // --- Helper for container swap -- template <typename _Alloc> -_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY void __swap_allocator(_Alloc & __a1, _Alloc & __a2) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT @@ -5649,7 +5661,7 @@ void __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type) } template <typename _Alloc> -_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY void __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {} template <typename _Alloc, typename _Traits=allocator_traits<_Alloc> > @@ -5662,6 +5674,26 @@ struct __noexcept_move_assign_container : public integral_constant<bool, #endif > {}; + +#ifndef _LIBCPP_HAS_NO_VARIADICS +template <class _Tp, class _Alloc> +struct __temp_value { + typedef allocator_traits<_Alloc> _Traits; + + typename aligned_storage<sizeof(_Tp), alignof(_Tp)>::type __v; + _Alloc &__a; + + _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); } + _Tp & get() { return *__addr(); } + + template<class... _Args> + __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) + { _Traits::construct(__a, __addr(), _VSTD::forward<_Args>(__args)...); } + + ~__temp_value() { _Traits::destroy(__a, __addr()); } + }; +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_MEMORY diff --git a/include/mutex b/include/mutex index a0875a568ec67..c047cf943e8ce 100644 --- a/include/mutex +++ b/include/mutex @@ -109,6 +109,19 @@ public: lock_guard& operator=(lock_guard const&) = delete; }; +template <class... MutexTypes> // Variadic lock_guard only provided in ABI V2. +class lock_guard +{ +public: + explicit lock_guard(MutexTypes&... m); + lock_guard(MutexTypes&... m, adopt_lock_t); + ~lock_guard(); + lock_guard(lock_guard const&) = delete; + lock_guard& operator=(lock_guard const&) = delete; +private: + tuple<MutexTypes&...> pm; // exposition only +}; + template <class Mutex> class unique_lock { @@ -179,9 +192,7 @@ template<class Callable, class ...Args> #ifndef _LIBCPP_HAS_NO_VARIADICS #include <tuple> #endif -#ifndef _LIBCPP_HAS_NO_THREADS -#include <sched.h> -#endif +#include <__threading_support> #include <__undef_min_max> @@ -195,7 +206,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD class _LIBCPP_TYPE_VIS recursive_mutex { - pthread_mutex_t __m_; + __libcpp_mutex_t __m_; public: recursive_mutex(); @@ -210,7 +221,7 @@ public: bool try_lock() _NOEXCEPT; void unlock() _NOEXCEPT; - typedef pthread_mutex_t* native_handle_type; + typedef __libcpp_mutex_t* native_handle_type; _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;} }; @@ -262,7 +273,7 @@ class _LIBCPP_TYPE_VIS recursive_timed_mutex mutex __m_; condition_variable __cv_; size_t __count_; - pthread_t __id_; + __libcpp_thread_id __id_; public: recursive_timed_mutex(); ~recursive_timed_mutex(); @@ -288,9 +299,9 @@ bool recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) { using namespace chrono; - pthread_t __id = pthread_self(); + __libcpp_thread_id __id = __libcpp_thread_get_current_id(); unique_lock<mutex> lk(__m_); - if (pthread_equal(__id, __id_)) + if (__libcpp_thread_id_equal(__id, __id_)) { if (__count_ == numeric_limits<size_t>::max()) return false; @@ -362,7 +373,7 @@ lock(_L0& __l0, _L1& __l1) break; } } - sched_yield(); + __libcpp_thread_yield(); { unique_lock<_L1> __u1(__l1); if (__l0.try_lock()) @@ -371,7 +382,7 @@ lock(_L0& __l0, _L1& __l1) break; } } - sched_yield(); + __libcpp_thread_yield(); } } @@ -396,7 +407,7 @@ __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) } } ++__i; - sched_yield(); + __libcpp_thread_yield(); break; case 1: { @@ -412,7 +423,7 @@ __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) __i = 0; else __i += 2; - sched_yield(); + __libcpp_thread_yield(); break; default: __lock_first(__i - 2, __l2, __l3..., __l0, __l1); @@ -429,6 +440,27 @@ lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) __lock_first(0, __l0, __l1, __l2, __l3...); } +template <class _L0> +inline _LIBCPP_INLINE_VISIBILITY +void __unlock(_L0& __l0) { + __l0.unlock(); +} + +template <class _L0, class _L1> +inline _LIBCPP_INLINE_VISIBILITY +void __unlock(_L0& __l0, _L1& __l1) { + __l0.unlock(); + __l1.unlock(); +} + +template <class _L0, class _L1, class _L2, class ..._L3> +inline _LIBCPP_INLINE_VISIBILITY +void __unlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) { + __l0.unlock(); + __l1.unlock(); + _VSTD::__unlock(__l2, __l3...); +} + #endif // _LIBCPP_HAS_NO_VARIADICS #endif // !_LIBCPP_HAS_NO_THREADS @@ -579,6 +611,63 @@ call_once(once_flag& __flag, const _Callable& __func) #endif // _LIBCPP_HAS_NO_VARIADICS + +#if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD) \ + && !defined(_LIBCPP_CXX03_LANG) +template <> +class _LIBCPP_TYPE_VIS_ONLY lock_guard<> { +public: + explicit lock_guard() {} + ~lock_guard() = default; + + _LIBCPP_INLINE_VISIBILITY + explicit lock_guard(adopt_lock_t) {} + + lock_guard(lock_guard const&) = delete; + lock_guard& operator=(lock_guard const&) = delete; +}; + +template <class ..._MArgs> +class _LIBCPP_TYPE_VIS_ONLY lock_guard +{ + static_assert(sizeof...(_MArgs) >= 2, "At least 2 lock types required"); + typedef tuple<_MArgs&...> _MutexTuple; + +public: + _LIBCPP_INLINE_VISIBILITY + explicit lock_guard(_MArgs&... __margs) + : __t_(__margs...) + { + _VSTD::lock(__margs...); + } + + _LIBCPP_INLINE_VISIBILITY + lock_guard(_MArgs&... __margs, adopt_lock_t) + : __t_(__margs...) + { + } + + _LIBCPP_INLINE_VISIBILITY + ~lock_guard() { + typedef typename __make_tuple_indices<sizeof...(_MArgs)>::type _Indices; + __unlock_unpack(_Indices{}, __t_); + } + + lock_guard(lock_guard const&) = delete; + lock_guard& operator=(lock_guard const&) = delete; + +private: + template <size_t ..._Indx> + _LIBCPP_INLINE_VISIBILITY + static void __unlock_unpack(__tuple_indices<_Indx...>, _MutexTuple& __mt) { + _VSTD::__unlock(_VSTD::get<_Indx>(__mt)...); + } + + _MutexTuple __t_; +}; + +#endif // _LIBCPP_ABI_VARIADIC_LOCK_GUARD + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_MUTEX diff --git a/include/queue b/include/queue index 6f49c87acdc56..c657b52f80382 100644 --- a/include/queue +++ b/include/queue @@ -66,7 +66,7 @@ public: template <class... Args> void emplace(Args&&... args); void pop(); - void swap(queue& q) noexcept(noexcept(swap(c, q.c))); + void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>) }; template <class T, class Container> @@ -153,7 +153,8 @@ public: void pop(); void swap(priority_queue& q) - noexcept(noexcept(swap(c, q.c)) && noexcept(swap(comp.q.comp))); + noexcept(is_nothrow_swappable_v<Container> && + is_nothrow_swappable_v<Comp>) }; template <class T, class Container, class Compare> @@ -198,6 +199,7 @@ public: typedef typename container_type::reference reference; typedef typename container_type::const_reference const_reference; typedef typename container_type::size_type size_type; + static_assert((is_same<_Tp, value_type>::value), "" ); protected: container_type c; @@ -368,7 +370,10 @@ operator<=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y) template <class _Tp, class _Container> inline _LIBCPP_INLINE_VISIBILITY -void +typename enable_if< + __is_swappable<_Container>::value, + void +>::type swap(queue<_Tp, _Container>& __x, queue<_Tp, _Container>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { @@ -392,6 +397,7 @@ public: typedef typename container_type::reference reference; typedef typename container_type::const_reference const_reference; typedef typename container_type::size_type size_type; + static_assert((is_same<_Tp, value_type>::value), "" ); protected: container_type c; @@ -430,45 +436,56 @@ public: _LIBCPP_INLINE_VISIBILITY explicit priority_queue(const value_compare& __comp) : c(), comp(__comp) {} + _LIBCPP_INLINE_VISIBILITY priority_queue(const value_compare& __comp, const container_type& __c); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY explicit priority_queue(const value_compare& __comp, container_type&& __c); #endif template <class _InputIter> + _LIBCPP_INLINE_VISIBILITY priority_queue(_InputIter __f, _InputIter __l, const value_compare& __comp = value_compare()); template <class _InputIter> + _LIBCPP_INLINE_VISIBILITY priority_queue(_InputIter __f, _InputIter __l, const value_compare& __comp, const container_type& __c); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _InputIter> + _LIBCPP_INLINE_VISIBILITY priority_queue(_InputIter __f, _InputIter __l, const value_compare& __comp, container_type&& __c); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Alloc> + _LIBCPP_INLINE_VISIBILITY explicit priority_queue(const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type* = 0); template <class _Alloc> + _LIBCPP_INLINE_VISIBILITY priority_queue(const value_compare& __comp, const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type* = 0); template <class _Alloc> + _LIBCPP_INLINE_VISIBILITY priority_queue(const value_compare& __comp, const container_type& __c, const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type* = 0); template <class _Alloc> + _LIBCPP_INLINE_VISIBILITY priority_queue(const priority_queue& __q, const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type* = 0); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Alloc> + _LIBCPP_INLINE_VISIBILITY priority_queue(const value_compare& __comp, container_type&& __c, const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type* = 0); template <class _Alloc> + _LIBCPP_INLINE_VISIBILITY priority_queue(priority_queue&& __q, const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type* = 0); @@ -481,22 +498,26 @@ public: _LIBCPP_INLINE_VISIBILITY const_reference top() const {return c.front();} + _LIBCPP_INLINE_VISIBILITY void push(const value_type& __v); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY void push(value_type&& __v); #ifndef _LIBCPP_HAS_NO_VARIADICS - template <class... _Args> void emplace(_Args&&... __args); + template <class... _Args> _LIBCPP_INLINE_VISIBILITY void emplace(_Args&&... __args); #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY void pop(); + _LIBCPP_INLINE_VISIBILITY void swap(priority_queue& __q) _NOEXCEPT_(__is_nothrow_swappable<container_type>::value && __is_nothrow_swappable<value_compare>::value); }; template <class _Tp, class _Container, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp, const container_type& __c) : c(__c), @@ -508,7 +529,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp, class _Container, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp, container_type&& __c) : c(_VSTD::move(__c)), @@ -521,7 +542,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& _ template <class _Tp, class _Container, class _Compare> template <class _InputIter> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l, const value_compare& __comp) : c(__f, __l), @@ -532,7 +553,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _Input template <class _Tp, class _Container, class _Compare> template <class _InputIter> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l, const value_compare& __comp, const container_type& __c) @@ -547,7 +568,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _Input template <class _Tp, class _Container, class _Compare> template <class _InputIter> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l, const value_compare& __comp, container_type&& __c) @@ -562,7 +583,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _Input template <class _Tp, class _Container, class _Compare> template <class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type*) @@ -572,7 +593,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Alloc& __a, template <class _Tp, class _Container, class _Compare> template <class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp, const _Alloc& __a, typename enable_if<uses_allocator<container_type, @@ -584,7 +605,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& _ template <class _Tp, class _Container, class _Compare> template <class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp, const container_type& __c, const _Alloc& __a, @@ -598,7 +619,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& _ template <class _Tp, class _Container, class _Compare> template <class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const priority_queue& __q, const _Alloc& __a, typename enable_if<uses_allocator<container_type, @@ -613,7 +634,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const priority_queue& template <class _Tp, class _Container, class _Compare> template <class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp, container_type&& __c, const _Alloc& __a, @@ -627,7 +648,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& _ template <class _Tp, class _Container, class _Compare> template <class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(priority_queue&& __q, const _Alloc& __a, typename enable_if<uses_allocator<container_type, @@ -641,7 +662,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(priority_queue&& __q, #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp, class _Container, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline void priority_queue<_Tp, _Container, _Compare>::push(const value_type& __v) { @@ -652,7 +673,7 @@ priority_queue<_Tp, _Container, _Compare>::push(const value_type& __v) #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp, class _Container, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline void priority_queue<_Tp, _Container, _Compare>::push(value_type&& __v) { @@ -664,7 +685,7 @@ priority_queue<_Tp, _Container, _Compare>::push(value_type&& __v) template <class _Tp, class _Container, class _Compare> template <class... _Args> -inline _LIBCPP_INLINE_VISIBILITY +inline void priority_queue<_Tp, _Container, _Compare>::emplace(_Args&&... __args) { @@ -676,7 +697,7 @@ priority_queue<_Tp, _Container, _Compare>::emplace(_Args&&... __args) #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp, class _Container, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline void priority_queue<_Tp, _Container, _Compare>::pop() { @@ -685,7 +706,7 @@ priority_queue<_Tp, _Container, _Compare>::pop() } template <class _Tp, class _Container, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline void priority_queue<_Tp, _Container, _Compare>::swap(priority_queue& __q) _NOEXCEPT_(__is_nothrow_swappable<container_type>::value && @@ -698,7 +719,11 @@ priority_queue<_Tp, _Container, _Compare>::swap(priority_queue& __q) template <class _Tp, class _Container, class _Compare> inline _LIBCPP_INLINE_VISIBILITY -void +typename enable_if< + __is_swappable<_Container>::value + && __is_swappable<_Compare>::value, + void +>::type swap(priority_queue<_Tp, _Container, _Compare>& __x, priority_queue<_Tp, _Container, _Compare>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) diff --git a/include/shared_mutex b/include/shared_mutex index dcb93949e30d3..923fe07ab38b4 100644 --- a/include/shared_mutex +++ b/include/shared_mutex @@ -319,25 +319,25 @@ public: _LIBCPP_INLINE_VISIBILITY explicit shared_lock(mutex_type& __m) - : __m_(&__m), + : __m_(_VSTD::addressof(__m)), __owns_(true) {__m_->lock_shared();} _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT - : __m_(&__m), + : __m_(_VSTD::addressof(__m)), __owns_(false) {} _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, try_to_lock_t) - : __m_(&__m), + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared()) {} _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, adopt_lock_t) - : __m_(&__m), + : __m_(_VSTD::addressof(__m)), __owns_(true) {} @@ -345,7 +345,7 @@ public: _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __abs_time) - : __m_(&__m), + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared_until(__abs_time)) {} @@ -353,7 +353,7 @@ public: _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __rel_time) - : __m_(&__m), + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared_for(__rel_time)) {} diff --git a/include/stack b/include/stack index 2992b091ee51c..48b3b0d16ec2f 100644 --- a/include/stack +++ b/include/stack @@ -58,7 +58,7 @@ public: template <class... Args> void emplace(Args&&... args); void pop(); - void swap(stack& c) noexcept(noexcept(swap(c, q.c))); + void swap(stack& c) noexcept(is_nothrow_swappable_v<Container>) }; template <class T, class Container> @@ -112,7 +112,8 @@ public: typedef typename container_type::reference reference; typedef typename container_type::const_reference const_reference; typedef typename container_type::size_type size_type; - + static_assert((is_same<_Tp, value_type>::value), "" ); + protected: container_type c; @@ -274,7 +275,10 @@ operator<=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) template <class _Tp, class _Container> inline _LIBCPP_INLINE_VISIBILITY -void +typename enable_if< + __is_swappable<_Container>::value, + void +>::type swap(stack<_Tp, _Container>& __x, stack<_Tp, _Container>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { diff --git a/include/stdbool.h b/include/stdbool.h new file mode 100644 index 0000000000000..86a127f0fd620 --- /dev/null +++ b/include/stdbool.h @@ -0,0 +1,39 @@ +// -*- C++ -*- +//===--------------------------- stdbool.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 _LIBCPP_STDBOOL_H +#define _LIBCPP_STDBOOL_H + + +/* + stdbool.h synopsis + +Macros: + + __bool_true_false_are_defined + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#include_next <stdbool.h> + +#ifdef __cplusplus +#undef bool +#undef true +#undef false +#undef __bool_true_false_are_defined +#define __bool_true_false_are_defined 1 +#endif + +#endif // _LIBCPP_STDBOOL_H diff --git a/include/stdexcept b/include/stdexcept index f251806fba62f..4218b1398d85b 100644 --- a/include/stdexcept +++ b/include/stdexcept @@ -53,7 +53,11 @@ public: #ifndef _LIBCPP___REFSTRING _LIBCPP_BEGIN_NAMESPACE_STD class _LIBCPP_HIDDEN __libcpp_refstring { - const char *__imp_ _LIBCPP_UNUSED; +#ifdef __clang__ + const char *__imp_ __attribute__((__unused__)); // only clang emits a warning +#else + const char *__imp_; +#endif }; _LIBCPP_END_NAMESPACE_STD #endif diff --git a/include/streambuf b/include/streambuf index 603c680387963..7544aaf179bd0 100644 --- a/include/streambuf +++ b/include/streambuf @@ -495,12 +495,22 @@ basic_streambuf<_CharT, _Traits>::xsgetn(char_type* __s, streamsize __n) const int_type __eof = traits_type::eof(); int_type __c; streamsize __i = 0; - for (;__i < __n; ++__i, ++__s) + while(__i < __n) { if (__ninp_ < __einp_) - *__s = *__ninp_++; + { + const streamsize __len = _VSTD::min(__einp_ - __ninp_, __n - __i); + traits_type::copy(__s, __ninp_, __len); + __s += __len; + __i += __len; + this->gbump(__len); + } else if ((__c = uflow()) != __eof) + { *__s = traits_type::to_char_type(__c); + ++__s; + ++__i; + } else break; } diff --git a/include/string b/include/string index 91502441e0c0d..786735f970f8e 100644 --- a/include/string +++ b/include/string @@ -98,8 +98,10 @@ public: basic_string(const basic_string& str); basic_string(basic_string&& str) noexcept(is_nothrow_move_constructible<allocator_type>::value); - basic_string(const basic_string& str, size_type pos, size_type n = npos, + basic_string(const basic_string& str, size_type pos, const allocator_type& a = allocator_type()); + basic_string(const basic_string& str, size_type pos, size_type n, + const Allocator& a = Allocator()); basic_string(const value_type* s, const allocator_type& a = allocator_type()); basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); @@ -225,6 +227,7 @@ public: const value_type* c_str() const noexcept; const value_type* data() const noexcept; + value_type* data() noexcept; // C++17 allocator_type get_allocator() const noexcept; @@ -958,7 +961,7 @@ char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) // __str_find template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find(const _CharT *__p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT { @@ -971,7 +974,7 @@ __str_find(const _CharT *__p, _SizeT __sz, } template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find(const _CharT *__p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT { @@ -982,7 +985,7 @@ __str_find(const _CharT *__p, _SizeT __sz, const _CharT* __r = _VSTD::__search(__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq, - random_access_iterator_tag(), random_access_iterator_tag()); + random_access_iterator_tag(), random_access_iterator_tag()).first; if (__r == __p + __sz) return __npos; return static_cast<_SizeT>(__r - __p); @@ -992,7 +995,7 @@ __str_find(const _CharT *__p, _SizeT __sz, // __str_rfind template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_rfind(const _CharT *__p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT { @@ -1011,7 +1014,7 @@ __str_rfind(const _CharT *__p, _SizeT __sz, } template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_rfind(const _CharT *__p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT { @@ -1030,7 +1033,7 @@ __str_rfind(const _CharT *__p, _SizeT __sz, // __str_find_first_of template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find_first_of(const _CharT *__p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT { @@ -1046,7 +1049,7 @@ __str_find_first_of(const _CharT *__p, _SizeT __sz, // __str_find_last_of template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find_last_of(const _CharT *__p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT { @@ -1069,7 +1072,7 @@ __str_find_last_of(const _CharT *__p, _SizeT __sz, // __str_find_first_not_of template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find_first_not_of(const _CharT *__p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT { @@ -1085,7 +1088,7 @@ __str_find_first_not_of(const _CharT *__p, _SizeT __sz, template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find_first_not_of(const _CharT *__p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT { @@ -1102,7 +1105,7 @@ __str_find_first_not_of(const _CharT *__p, _SizeT __sz, // __str_find_last_not_of template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find_last_not_of(const _CharT *__p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT { @@ -1118,7 +1121,7 @@ __str_find_last_not_of(const _CharT *__p, _SizeT __sz, template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find_last_not_of(const _CharT *__p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT { @@ -1396,7 +1399,10 @@ public: basic_string(size_type __n, value_type __c); _LIBCPP_INLINE_VISIBILITY basic_string(size_type __n, value_type __c, const allocator_type& __a); - basic_string(const basic_string& __str, size_type __pos, size_type __n = npos, + basic_string(const basic_string& __str, size_type __pos, size_type __n, + const allocator_type& __a = allocator_type()); + _LIBCPP_INLINE_VISIBILITY + basic_string(const basic_string& __str, size_type __pos, const allocator_type& __a = allocator_type()); template<class _InputIterator> _LIBCPP_INLINE_VISIBILITY @@ -1546,7 +1552,7 @@ public: _LIBCPP_INLINE_VISIBILITY const_reference back() const; _LIBCPP_INLINE_VISIBILITY - basic_string& assign(const basic_string& __str); + basic_string& assign(const basic_string& __str) { return *this = __str; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY basic_string& assign(basic_string&& str) @@ -1659,6 +1665,10 @@ public: const value_type* c_str() const _NOEXCEPT {return data();} _LIBCPP_INLINE_VISIBILITY const value_type* data() const _NOEXCEPT {return _VSTD::__to_raw_pointer(__get_pointer());} +#if _LIBCPP_STD_VER > 14 + _LIBCPP_INLINE_VISIBILITY + value_type* data() _NOEXCEPT {return _VSTD::__to_raw_pointer(__get_pointer());} +#endif _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const _NOEXCEPT {return __alloc();} @@ -2218,6 +2228,21 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st } template <class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, + const allocator_type& __a) + : __r_(__a) +{ + size_type __str_sz = __str.size(); + if (__pos > __str_sz) + this->__throw_out_of_range(); + __init(__str.data() + __pos, __str_sz - __pos); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif +} + +template <class _CharT, class _Traits, class _Allocator> template <class _InputIterator> typename enable_if < @@ -2466,7 +2491,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) if (this != &__str) { __copy_assign_alloc(__str); - assign(__str); + assign(__str.data(), __str.size()); } return *this; } @@ -2558,14 +2583,6 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _For } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -basic_string<_CharT, _Traits, _Allocator>& -basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str) -{ - return assign(__str.data(), __str.size()); -} - -template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) { diff --git a/include/string.h b/include/string.h new file mode 100644 index 0000000000000..a1ce56cbcd6d6 --- /dev/null +++ b/include/string.h @@ -0,0 +1,110 @@ +// -*- C++ -*- +//===--------------------------- string.h ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_STRING_H +#define _LIBCPP_STRING_H + +/* + string.h synopsis + +Macros: + + NULL + +Types: + + size_t + +void* memcpy(void* restrict s1, const void* restrict s2, size_t n); +void* memmove(void* s1, const void* s2, size_t n); +char* strcpy (char* restrict s1, const char* restrict s2); +char* strncpy(char* restrict s1, const char* restrict s2, size_t n); +char* strcat (char* restrict s1, const char* restrict s2); +char* strncat(char* restrict s1, const char* restrict s2, size_t n); +int memcmp(const void* s1, const void* s2, size_t n); +int strcmp (const char* s1, const char* s2); +int strncmp(const char* s1, const char* s2, size_t n); +int strcoll(const char* s1, const char* s2); +size_t strxfrm(char* restrict s1, const char* restrict s2, size_t n); +const void* memchr(const void* s, int c, size_t n); + void* memchr( void* s, int c, size_t n); +const char* strchr(const char* s, int c); + char* strchr( char* s, int c); +size_t strcspn(const char* s1, const char* s2); +const char* strpbrk(const char* s1, const char* s2); + char* strpbrk( char* s1, const char* s2); +const char* strrchr(const char* s, int c); + char* strrchr( char* s, int c); +size_t strspn(const char* s1, const char* s2); +const char* strstr(const char* s1, const char* s2); + char* strstr( char* s1, const char* s2); +char* strtok(char* restrict s1, const char* restrict s2); +void* memset(void* s, int c, size_t n); +char* strerror(int errnum); +size_t strlen(const char* s); + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#include_next <string.h> + +// MSVCRT, GNU libc and its derivates may already have the correct prototype in +// <string.h>. This macro can be defined by users if their C library provides +// the right signature. +#if defined(__CORRECT_ISO_CPP_STRING_H_PROTO) || defined(_LIBCPP_MSVCRT) || \ + defined(__sun__) || defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_) +#define _LIBCPP_STRING_H_HAS_CONST_OVERLOADS +#endif + +#if defined(__cplusplus) && !defined(_LIBCPP_STRING_H_HAS_CONST_OVERLOADS) && defined(_LIBCPP_PREFERRED_OVERLOAD) +extern "C++" { +inline _LIBCPP_INLINE_VISIBILITY +char* __libcpp_strchr(const char* __s, int __c) {return (char*)strchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const char* strchr(const char* __s, int __c) {return __libcpp_strchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + char* strchr( char* __s, int __c) {return __libcpp_strchr(__s, __c);} + +inline _LIBCPP_INLINE_VISIBILITY +char* __libcpp_strpbrk(const char* __s1, const char* __s2) {return (char*)strpbrk(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const char* strpbrk(const char* __s1, const char* __s2) {return __libcpp_strpbrk(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + char* strpbrk( char* __s1, const char* __s2) {return __libcpp_strpbrk(__s1, __s2);} + +inline _LIBCPP_INLINE_VISIBILITY +char* __libcpp_strrchr(const char* __s, int __c) {return (char*)strrchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const char* strrchr(const char* __s, int __c) {return __libcpp_strrchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + char* strrchr( char* __s, int __c) {return __libcpp_strrchr(__s, __c);} + +inline _LIBCPP_INLINE_VISIBILITY +void* __libcpp_memchr(const void* __s, int __c, size_t __n) {return (void*)memchr(__s, __c, __n);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const void* memchr(const void* __s, int __c, size_t __n) {return __libcpp_memchr(__s, __c, __n);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + void* memchr( void* __s, int __c, size_t __n) {return __libcpp_memchr(__s, __c, __n);} + +inline _LIBCPP_INLINE_VISIBILITY +char* __libcpp_strstr(const char* __s1, const char* __s2) {return (char*)strstr(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const char* strstr(const char* __s1, const char* __s2) {return __libcpp_strstr(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + char* strstr( char* __s1, const char* __s2) {return __libcpp_strstr(__s1, __s2);} +} +#endif + +#endif // _LIBCPP_STRING_H diff --git a/include/support/android/locale_bionic.h b/include/support/android/locale_bionic.h index 3a020da67e6bd..1365563ee4815 100644 --- a/include/support/android/locale_bionic.h +++ b/include/support/android/locale_bionic.h @@ -24,8 +24,8 @@ extern "C" { } #endif -// Share implementation with Newlib -#include <support/xlocale/xlocale.h> +#include <support/xlocale/__posix_l_fallback.h> +#include <support/xlocale/__strtonum_fallback.h> #endif // defined(__ANDROID__) #endif // _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H diff --git a/include/support/ibm/locale_mgmt_aix.h b/include/support/ibm/locale_mgmt_aix.h new file mode 100644 index 0000000000000..e3b7a78c45a0f --- /dev/null +++ b/include/support/ibm/locale_mgmt_aix.h @@ -0,0 +1,85 @@ +// -*- C++ -*- +//===------------------- support/ibm/locale_mgmt_aix.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 _LIBCPP_SUPPORT_IBM_LOCALE_MGMT_AIX_H +#define _LIBCPP_SUPPORT_IBM_LOCALE_MGMT_AIX_H + +#if defined(_AIX) +#include "cstdlib" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_AIX71) +// AIX 7.1 and higher has these definitions. Definitions and stubs +// are provied here as a temporary workaround on AIX 6.1. + +#define LC_COLLATE_MASK 1 +#define LC_CTYPE_MASK 2 +#define LC_MESSAGES_MASK 4 +#define LC_MONETARY_MASK 8 +#define LC_NUMERIC_MASK 16 +#define LC_TIME_MASK 32 +#define LC_ALL_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | \ + LC_MESSAGES_MASK | LC_MONETARY_MASK |\ + LC_NUMERIC_MASK | LC_TIME_MASK) + +typedef void* locale_t; + +// The following are stubs. They are not supported on AIX 6.1. +static inline +locale_t newlocale(int category_mask, const char *locale, locale_t base) +{ + _LC_locale_t *newloc, *loc; + if ((loc = (_LC_locale_t *)__xopen_locale(locale)) == NULL) + { + errno = EINVAL; + return (locale_t)0; + } + if ((newloc = (_LC_locale_t *)calloc(1, sizeof(_LC_locale_t))) == NULL) + { + errno = ENOMEM; + return (locale_t)0; + } + if (!base) + base = (_LC_locale_t *)__xopen_locale("C"); + memcpy(newloc, base, sizeof (_LC_locale_t)); + if (category_mask & LC_COLLATE_MASK) + newloc->lc_collate = loc->lc_collate; + if (category_mask & LC_CTYPE_MASK) + newloc->lc_ctype = loc->lc_ctype; + //if (category_mask & LC_MESSAGES_MASK) + // newloc->lc_messages = loc->lc_messages; + if (category_mask & LC_MONETARY_MASK) + newloc->lc_monetary = loc->lc_monetary; + if (category_mask & LC_TIME_MASK) + newloc->lc_time = loc->lc_time; + if (category_mask & LC_NUMERIC_MASK) + newloc->lc_numeric = loc->lc_numeric; + return (locale_t)newloc; +} +static inline +void freelocale(locale_t locobj) +{ + free(locobj); +} +static inline +locale_t uselocale(locale_t newloc) +{ + return (locale_t)0; +} +#endif // !defined(_AIX71) + +#ifdef __cplusplus +} +#endif +#endif // defined(_AIX) +#endif // _LIBCPP_SUPPORT_IBM_LOCALE_MGMT_AIX_H diff --git a/include/support/ibm/xlocale.h b/include/support/ibm/xlocale.h index 8d99a5c7d34d5..f39c0ba95d901 100644 --- a/include/support/ibm/xlocale.h +++ b/include/support/ibm/xlocale.h @@ -10,6 +10,7 @@ #ifndef _LIBCPP_SUPPORT_IBM_XLOCALE_H #define _LIBCPP_SUPPORT_IBM_XLOCALE_H +#include <support/ibm/locale_mgmt_aix.h> #if defined(_AIX) #include "cstdlib" @@ -21,62 +22,6 @@ extern "C" { #if !defined(_AIX71) // AIX 7.1 and higher has these definitions. Definitions and stubs // are provied here as a temporary workaround on AIX 6.1. - -#define LC_COLLATE_MASK 1 -#define LC_CTYPE_MASK 2 -#define LC_MESSAGES_MASK 4 -#define LC_MONETARY_MASK 8 -#define LC_NUMERIC_MASK 16 -#define LC_TIME_MASK 32 -#define LC_ALL_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | \ - LC_MESSAGES_MASK | LC_MONETARY_MASK |\ - LC_NUMERIC_MASK | LC_TIME_MASK) - -typedef void* locale_t; - -// The following are stubs. They are not supported on AIX 6.1. -static inline -locale_t newlocale(int category_mask, const char *locale, locale_t base) -{ - _LC_locale_t *newloc, *loc; - if ((loc = (_LC_locale_t *)__xopen_locale(locale)) == NULL) - { - errno = EINVAL; - return (locale_t)0; - } - if ((newloc = (_LC_locale_t *)calloc(1, sizeof(_LC_locale_t))) == NULL) - { - errno = ENOMEM; - return (locale_t)0; - } - if (!base) - base = (_LC_locale_t *)__xopen_locale("C"); - memcpy(newloc, base, sizeof (_LC_locale_t)); - if (category_mask & LC_COLLATE_MASK) - newloc->lc_collate = loc->lc_collate; - if (category_mask & LC_CTYPE_MASK) - newloc->lc_ctype = loc->lc_ctype; - //if (category_mask & LC_MESSAGES_MASK) - // newloc->lc_messages = loc->lc_messages; - if (category_mask & LC_MONETARY_MASK) - newloc->lc_monetary = loc->lc_monetary; - if (category_mask & LC_TIME_MASK) - newloc->lc_time = loc->lc_time; - if (category_mask & LC_NUMERIC_MASK) - newloc->lc_numeric = loc->lc_numeric; - return (locale_t)newloc; -} -static inline -void freelocale(locale_t locobj) -{ - free(locobj); -} -static inline -locale_t uselocale(locale_t newloc) -{ - return (locale_t)0; -} - static inline int isalnum_l(int c, locale_t locale) { diff --git a/include/support/newlib/xlocale.h b/include/support/newlib/xlocale.h index d067cf85a3bcb..4e4b23be8d6b8 100644 --- a/include/support/newlib/xlocale.h +++ b/include/support/newlib/xlocale.h @@ -16,47 +16,9 @@ #include <clocale> #include <cwctype> #include <ctype.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// Patch over newlib's lack of extended locale support -typedef void *locale_t; -static inline locale_t duplocale(locale_t) { - return NULL; -} - -static inline void freelocale(locale_t) { -} - -static inline locale_t newlocale(int, const char *, locale_t) { - return NULL; -} - -static inline locale_t uselocale(locale_t) { - return NULL; -} - -#define LC_COLLATE_MASK (1 << LC_COLLATE) -#define LC_CTYPE_MASK (1 << LC_CTYPE) -#define LC_MESSAGES_MASK (1 << LC_MESSAGES) -#define LC_MONETARY_MASK (1 << LC_MONETARY) -#define LC_NUMERIC_MASK (1 << LC_NUMERIC) -#define LC_TIME_MASK (1 << LC_TIME) -#define LC_ALL_MASK (LC_COLLATE_MASK|\ - LC_CTYPE_MASK|\ - LC_MONETARY_MASK|\ - LC_NUMERIC_MASK|\ - LC_TIME_MASK|\ - LC_MESSAGES_MASK) - -// Share implementation with Android's Bionic -#include <support/xlocale/xlocale.h> - -#ifdef __cplusplus -} // extern "C" -#endif +#include <support/xlocale/__nop_locale_mgmt.h> +#include <support/xlocale/__posix_l_fallback.h> +#include <support/xlocale/__strtonum_fallback.h> #endif // _NEWLIB_VERSION diff --git a/include/support/solaris/xlocale.h b/include/support/solaris/xlocale.h index 62b0d74a6d23f..e20ef7a6e53b2 100644 --- a/include/support/solaris/xlocale.h +++ b/include/support/solaris/xlocale.h @@ -44,11 +44,6 @@ long strtol_l(const char *__nptr, char **__endptr, return strtol(__nptr, __endptr, __base); } static inline -long double strtold_l(const char *__nptr, char **__endptr, - locale_t __loc) { - return strtold(__nptr, __endptr); -} -static inline unsigned long long strtoull_l(const char *__nptr, char **__endptr, int __base, locale_t __loc) { return strtoull(__nptr, __endptr, __base); @@ -58,6 +53,21 @@ unsigned long strtoul_l(const char *__nptr, char **__endptr, int __base, locale_t __loc) { return strtoul(__nptr, __endptr, __base); } +static inline +float strtof_l(const char *__nptr, char **__endptr, + locale_t __loc) { + return strtof(__nptr, __endptr); +} +static inline +double strtod_l(const char *__nptr, char **__endptr, + locale_t __loc) { + return strtod(__nptr, __endptr); +} +static inline +long double strtold_l(const char *__nptr, char **__endptr, + locale_t __loc) { + return strtold(__nptr, __endptr); +} #ifdef __cplusplus diff --git a/include/support/win32/locale_mgmt_win32.h b/include/support/win32/locale_mgmt_win32.h new file mode 100644 index 0000000000000..b3316d62596f4 --- /dev/null +++ b/include/support/win32/locale_mgmt_win32.h @@ -0,0 +1,33 @@ +// -*- C++ -*- +//===----------------- support/win32/locale_mgmt_win32.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 _LIBCPP_SUPPORT_WIN32_LOCALE_MGMT_WIN32_H +#define _LIBCPP_SUPPORT_WIN32_LOCALE_MGMT_WIN32_H + +#include <xlocinfo.h> // _locale_t +#define locale_t _locale_t +#define LC_COLLATE_MASK _M_COLLATE +#define LC_CTYPE_MASK _M_CTYPE +#define LC_MONETARY_MASK _M_MONETARY +#define LC_NUMERIC_MASK _M_NUMERIC +#define LC_TIME_MASK _M_TIME +#define LC_MESSAGES_MASK _M_MESSAGES +#define LC_ALL_MASK ( LC_COLLATE_MASK \ + | LC_CTYPE_MASK \ + | LC_MESSAGES_MASK \ + | LC_MONETARY_MASK \ + | LC_NUMERIC_MASK \ + | LC_TIME_MASK ) +#define freelocale _free_locale +// FIXME: base currently unused. Needs manual work to construct the new locale +locale_t newlocale( int mask, const char * locale, locale_t base ); +locale_t uselocale( locale_t newloc ); + +#endif // _LIBCPP_SUPPORT_WIN32_LOCALE_MGMT_WIN32_H diff --git a/include/support/win32/locale_win32.h b/include/support/win32/locale_win32.h index f728d234472f9..7f3710ecc1881 100644 --- a/include/support/win32/locale_win32.h +++ b/include/support/win32/locale_win32.h @@ -15,26 +15,10 @@ extern "C" unsigned short __declspec(dllimport) _ctype[]; #include "support/win32/support.h" +#include "support/win32/locale_mgmt_win32.h" #include <stdio.h> #include <memory> -#include <xlocinfo.h> // _locale_t -#define locale_t _locale_t -#define LC_COLLATE_MASK _M_COLLATE -#define LC_CTYPE_MASK _M_CTYPE -#define LC_MONETARY_MASK _M_MONETARY -#define LC_NUMERIC_MASK _M_NUMERIC -#define LC_TIME_MASK _M_TIME -#define LC_MESSAGES_MASK _M_MESSAGES -#define LC_ALL_MASK ( LC_COLLATE_MASK \ - | LC_CTYPE_MASK \ - | LC_MESSAGES_MASK \ - | LC_MONETARY_MASK \ - | LC_NUMERIC_MASK \ - | LC_TIME_MASK ) -#define freelocale _free_locale -// FIXME: base currently unused. Needs manual work to construct the new locale -locale_t newlocale( int mask, const char * locale, locale_t base ); -locale_t uselocale( locale_t newloc ); + lconv *localeconv_l( locale_t loc ); size_t mbrlen_l( const char *__restrict s, size_t n, mbstate_t *__restrict ps, locale_t loc); diff --git a/include/support/xlocale/__nop_locale_mgmt.h b/include/support/xlocale/__nop_locale_mgmt.h new file mode 100644 index 0000000000000..0d3f23a2c9698 --- /dev/null +++ b/include/support/xlocale/__nop_locale_mgmt.h @@ -0,0 +1,52 @@ +// -*- C++ -*- +//===------------ support/xlocale/__nop_locale_mgmt.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 _LIBCPP_SUPPORT_XLOCALE_NOP_LOCALE_MGMT_H +#define _LIBCPP_SUPPORT_XLOCALE_NOP_LOCALE_MGMT_H + +#ifdef __cplusplus +extern "C" { +#endif + +// Patch over lack of extended locale support +typedef void *locale_t; +static inline locale_t duplocale(locale_t) { + return NULL; +} + +static inline void freelocale(locale_t) { +} + +static inline locale_t newlocale(int, const char *, locale_t) { + return NULL; +} + +static inline locale_t uselocale(locale_t) { + return NULL; +} + +#define LC_COLLATE_MASK (1 << LC_COLLATE) +#define LC_CTYPE_MASK (1 << LC_CTYPE) +#define LC_MESSAGES_MASK (1 << LC_MESSAGES) +#define LC_MONETARY_MASK (1 << LC_MONETARY) +#define LC_NUMERIC_MASK (1 << LC_NUMERIC) +#define LC_TIME_MASK (1 << LC_TIME) +#define LC_ALL_MASK (LC_COLLATE_MASK|\ + LC_CTYPE_MASK|\ + LC_MONETARY_MASK|\ + LC_NUMERIC_MASK|\ + LC_TIME_MASK|\ + LC_MESSAGES_MASK) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _LIBCPP_SUPPORT_XLOCALE_NOP_LOCALE_MGMT_H diff --git a/include/support/xlocale/__posix_l_fallback.h b/include/support/xlocale/__posix_l_fallback.h new file mode 100644 index 0000000000000..8bf9567ffc255 --- /dev/null +++ b/include/support/xlocale/__posix_l_fallback.h @@ -0,0 +1,165 @@ +// -*- C++ -*- +//===--------------- support/xlocale/__posix_l_fallback.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. +// +//===----------------------------------------------------------------------===// +// These are reimplementations of some extended locale functions ( *_l ) that +// are normally part of POSIX. This shared implementation provides parts of the +// extended locale support for libc's that normally don't have any (like +// Android's bionic and Newlib). +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SUPPORT_XLOCALE_POSIX_L_FALLBACK_H +#define _LIBCPP_SUPPORT_XLOCALE_POSIX_L_FALLBACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +inline _LIBCPP_ALWAYS_INLINE int isalnum_l(int c, locale_t) { + return ::isalnum(c); +} + +inline _LIBCPP_ALWAYS_INLINE int isalpha_l(int c, locale_t) { + return ::isalpha(c); +} + +inline _LIBCPP_ALWAYS_INLINE int isblank_l(int c, locale_t) { + return ::isblank(c); +} + +inline _LIBCPP_ALWAYS_INLINE int iscntrl_l(int c, locale_t) { + return ::iscntrl(c); +} + +inline _LIBCPP_ALWAYS_INLINE int isdigit_l(int c, locale_t) { + return ::isdigit(c); +} + +inline _LIBCPP_ALWAYS_INLINE int isgraph_l(int c, locale_t) { + return ::isgraph(c); +} + +inline _LIBCPP_ALWAYS_INLINE int islower_l(int c, locale_t) { + return ::islower(c); +} + +inline _LIBCPP_ALWAYS_INLINE int isprint_l(int c, locale_t) { + return ::isprint(c); +} + +inline _LIBCPP_ALWAYS_INLINE int ispunct_l(int c, locale_t) { + return ::ispunct(c); +} + +inline _LIBCPP_ALWAYS_INLINE int isspace_l(int c, locale_t) { + return ::isspace(c); +} + +inline _LIBCPP_ALWAYS_INLINE int isupper_l(int c, locale_t) { + return ::isupper(c); +} + +inline _LIBCPP_ALWAYS_INLINE int isxdigit_l(int c, locale_t) { + return ::isxdigit(c); +} + +inline _LIBCPP_ALWAYS_INLINE int iswalnum_l(wint_t c, locale_t) { + return ::iswalnum(c); +} + +inline _LIBCPP_ALWAYS_INLINE int iswalpha_l(wint_t c, locale_t) { + return ::iswalpha(c); +} + +inline _LIBCPP_ALWAYS_INLINE int iswblank_l(wint_t c, locale_t) { + return ::iswblank(c); +} + +inline _LIBCPP_ALWAYS_INLINE int iswcntrl_l(wint_t c, locale_t) { + return ::iswcntrl(c); +} + +inline _LIBCPP_ALWAYS_INLINE int iswdigit_l(wint_t c, locale_t) { + return ::iswdigit(c); +} + +inline _LIBCPP_ALWAYS_INLINE int iswgraph_l(wint_t c, locale_t) { + return ::iswgraph(c); +} + +inline _LIBCPP_ALWAYS_INLINE int iswlower_l(wint_t c, locale_t) { + return ::iswlower(c); +} + +inline _LIBCPP_ALWAYS_INLINE int iswprint_l(wint_t c, locale_t) { + return ::iswprint(c); +} + +inline _LIBCPP_ALWAYS_INLINE int iswpunct_l(wint_t c, locale_t) { + return ::iswpunct(c); +} + +inline _LIBCPP_ALWAYS_INLINE int iswspace_l(wint_t c, locale_t) { + return ::iswspace(c); +} + +inline _LIBCPP_ALWAYS_INLINE int iswupper_l(wint_t c, locale_t) { + return ::iswupper(c); +} + +inline _LIBCPP_ALWAYS_INLINE int iswxdigit_l(wint_t c, locale_t) { + return ::iswxdigit(c); +} + +inline _LIBCPP_ALWAYS_INLINE int toupper_l(int c, locale_t) { + return ::toupper(c); +} + +inline _LIBCPP_ALWAYS_INLINE int tolower_l(int c, locale_t) { + return ::tolower(c); +} + +inline _LIBCPP_ALWAYS_INLINE int towupper_l(int c, locale_t) { + return ::towupper(c); +} + +inline _LIBCPP_ALWAYS_INLINE int towlower_l(int c, locale_t) { + return ::towlower(c); +} + +inline _LIBCPP_ALWAYS_INLINE int strcoll_l(const char *s1, const char *s2, + locale_t) { + return ::strcoll(s1, s2); +} + +inline _LIBCPP_ALWAYS_INLINE size_t strxfrm_l(char *dest, const char *src, + size_t n, locale_t) { + return ::strxfrm(dest, src, n); +} + +inline _LIBCPP_ALWAYS_INLINE size_t strftime_l(char *s, size_t max, + const char *format, + const struct tm *tm, locale_t) { + return ::strftime(s, max, format, tm); +} + +inline _LIBCPP_ALWAYS_INLINE int wcscoll_l(const wchar_t *ws1, + const wchar_t *ws2, locale_t) { + return ::wcscoll(ws1, ws2); +} + +inline _LIBCPP_ALWAYS_INLINE size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, + size_t n, locale_t) { + return ::wcsxfrm(dest, src, n); +} + +#ifdef __cplusplus +} +#endif + +#endif // _LIBCPP_SUPPORT_XLOCALE_POSIX_L_FALLBACK_H diff --git a/include/support/xlocale/__strtonum_fallback.h b/include/support/xlocale/__strtonum_fallback.h new file mode 100644 index 0000000000000..4ae3918b3d307 --- /dev/null +++ b/include/support/xlocale/__strtonum_fallback.h @@ -0,0 +1,67 @@ +// -*- C++ -*- +//===-------------- support/xlocale/__strtonum_fallback.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. +// +//===----------------------------------------------------------------------===// +// These are reimplementations of some extended locale functions ( *_l ) that +// aren't part of POSIX. They are widely available though (GLIBC, BSD, maybe +// others). The unifying aspect in this case is that all of these functions +// convert strings to some numeric type. +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SUPPORT_XLOCALE_STRTONUM_FALLBACK_H +#define _LIBCPP_SUPPORT_XLOCALE_STRTONUM_FALLBACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +inline _LIBCPP_ALWAYS_INLINE float strtof_l(const char *nptr, + char **endptr, locale_t) { + return ::strtof(nptr, endptr); +} + +inline _LIBCPP_ALWAYS_INLINE double strtod_l(const char *nptr, + char **endptr, locale_t) { + return ::strtod(nptr, endptr); +} + +inline _LIBCPP_ALWAYS_INLINE long double strtold_l(const char *nptr, + char **endptr, locale_t) { + return ::strtold(nptr, endptr); +} + +inline _LIBCPP_ALWAYS_INLINE long long +strtoll_l(const char *nptr, char **endptr, int base, locale_t) { + return ::strtoll(nptr, endptr, base); +} + +inline _LIBCPP_ALWAYS_INLINE unsigned long long +strtoull_l(const char *nptr, char **endptr, int base, locale_t) { + return ::strtoull(nptr, endptr, base); +} + +inline _LIBCPP_ALWAYS_INLINE long long +wcstoll_l(const wchar_t *nptr, wchar_t **endptr, int base, locale_t) { + return ::wcstoll(nptr, endptr, base); +} + +inline _LIBCPP_ALWAYS_INLINE unsigned long long +wcstoull_l(const wchar_t *nptr, wchar_t **endptr, int base, locale_t) { + return ::wcstoull(nptr, endptr, base); +} + +inline _LIBCPP_ALWAYS_INLINE long double wcstold_l(const wchar_t *nptr, + wchar_t **endptr, locale_t) { + return ::wcstold(nptr, endptr); +} + +#ifdef __cplusplus +} +#endif + +#endif // _LIBCPP_SUPPORT_XLOCALE_STRTONUM_FALLBACK_H diff --git a/include/support/xlocale/xlocale.h b/include/support/xlocale/xlocale.h index 99f710e8f44ea..e69de29bb2d1d 100644 --- a/include/support/xlocale/xlocale.h +++ b/include/support/xlocale/xlocale.h @@ -1,194 +0,0 @@ -// -*- C++ -*- -//===------------------- support/xlocale/xlocale.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. -// -//===----------------------------------------------------------------------===// -// This is a shared implementation of a shim to provide extended locale support -// on top of libc's that don't support it (like Android's bionic, and Newlib). -// -// The 'illusion' only works when the specified locale is "C" or "POSIX", but -// that's about as good as we can do without implementing full xlocale support -// in the underlying libc. -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_SUPPORT_XLOCALE_XLOCALE_H -#define _LIBCPP_SUPPORT_XLOCALE_XLOCALE_H - -#ifdef __cplusplus -extern "C" { -#endif - -static inline int isalnum_l(int c, locale_t) { - return isalnum(c); -} - -static inline int isalpha_l(int c, locale_t) { - return isalpha(c); -} - -static inline int isblank_l(int c, locale_t) { - return isblank(c); -} - -static inline int iscntrl_l(int c, locale_t) { - return iscntrl(c); -} - -static inline int isdigit_l(int c, locale_t) { - return isdigit(c); -} - -static inline int isgraph_l(int c, locale_t) { - return isgraph(c); -} - -static inline int islower_l(int c, locale_t) { - return islower(c); -} - -static inline int isprint_l(int c, locale_t) { - return isprint(c); -} - -static inline int ispunct_l(int c, locale_t) { - return ispunct(c); -} - -static inline int isspace_l(int c, locale_t) { - return isspace(c); -} - -static inline int isupper_l(int c, locale_t) { - return isupper(c); -} - -static inline int isxdigit_l(int c, locale_t) { - return isxdigit(c); -} - -static inline int iswalnum_l(wint_t c, locale_t) { - return iswalnum(c); -} - -static inline int iswalpha_l(wint_t c, locale_t) { - return iswalpha(c); -} - -static inline int iswblank_l(wint_t c, locale_t) { - return iswblank(c); -} - -static inline int iswcntrl_l(wint_t c, locale_t) { - return iswcntrl(c); -} - -static inline int iswdigit_l(wint_t c, locale_t) { - return iswdigit(c); -} - -static inline int iswgraph_l(wint_t c, locale_t) { - return iswgraph(c); -} - -static inline int iswlower_l(wint_t c, locale_t) { - return iswlower(c); -} - -static inline int iswprint_l(wint_t c, locale_t) { - return iswprint(c); -} - -static inline int iswpunct_l(wint_t c, locale_t) { - return iswpunct(c); -} - -static inline int iswspace_l(wint_t c, locale_t) { - return iswspace(c); -} - -static inline int iswupper_l(wint_t c, locale_t) { - return iswupper(c); -} - -static inline int iswxdigit_l(wint_t c, locale_t) { - return iswxdigit(c); -} - -static inline int toupper_l(int c, locale_t) { - return toupper(c); -} - -static inline int tolower_l(int c, locale_t) { - return tolower(c); -} - -static inline int towupper_l(int c, locale_t) { - return towupper(c); -} - -static inline int towlower_l(int c, locale_t) { - return towlower(c); -} - -static inline int strcoll_l(const char *s1, const char *s2, locale_t) { - return strcoll(s1, s2); -} - -static inline size_t strxfrm_l(char *dest, const char *src, size_t n, - locale_t) { - return strxfrm(dest, src, n); -} - -static inline size_t strftime_l(char *s, size_t max, const char *format, - const struct tm *tm, locale_t) { - return strftime(s, max, format, tm); -} - -static inline int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t) { - return wcscoll(ws1, ws2); -} - -static inline size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, size_t n, - locale_t) { - return wcsxfrm(dest, src, n); -} - -static inline long double strtold_l(const char *nptr, char **endptr, locale_t) { - return strtold(nptr, endptr); -} - -static inline long long strtoll_l(const char *nptr, char **endptr, int base, - locale_t) { - return strtoll(nptr, endptr, base); -} - -static inline unsigned long long strtoull_l(const char *nptr, char **endptr, - int base, locale_t) { - return strtoull(nptr, endptr, base); -} - -static inline long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr, - int base, locale_t) { - return wcstoll(nptr, endptr, base); -} - -static inline unsigned long long wcstoull_l(const wchar_t *nptr, - wchar_t **endptr, int base, - locale_t) { - return wcstoull(nptr, endptr, base); -} - -static inline long double wcstold_l(const wchar_t *nptr, wchar_t **endptr, - locale_t) { - return wcstold(nptr, endptr); -} - -#ifdef __cplusplus -} -#endif - -#endif // _LIBCPP_SUPPORT_XLOCALE_XLOCALE_H diff --git a/include/thread b/include/thread index 6857e9edb68b6..022021c5addee 100644 --- a/include/thread +++ b/include/thread @@ -98,8 +98,7 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time); #ifndef _LIBCPP_HAS_NO_VARIADICS #include <tuple> #endif -#include <pthread.h> -#include <sched.h> +#include <__threading_support> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -137,7 +136,7 @@ public: template <class _Tp> class __thread_specific_ptr { - pthread_key_t __key_; + __libcpp_tl_key __key_; // Only __thread_local_data() may construct a __thread_specific_ptr // and only with _Tp == __thread_struct. @@ -155,7 +154,7 @@ public: ~__thread_specific_ptr(); _LIBCPP_INLINE_VISIBILITY - pointer get() const {return static_cast<_Tp*>(pthread_getspecific(__key_));} + pointer get() const {return static_cast<_Tp*>(__libcpp_tl_get(__key_));} _LIBCPP_INLINE_VISIBILITY pointer operator*() const {return *get();} _LIBCPP_INLINE_VISIBILITY @@ -174,12 +173,12 @@ __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p) template <class _Tp> __thread_specific_ptr<_Tp>::__thread_specific_ptr() { - int __ec = pthread_key_create(&__key_, &__thread_specific_ptr::__at_thread_exit); -#ifndef _LIBCPP_NO_EXCEPTIONS + int __ec = __libcpp_tl_create( + &__key_, + &__thread_specific_ptr::__at_thread_exit); if (__ec) - throw system_error(error_code(__ec, system_category()), + __throw_system_error(__ec, "__thread_specific_ptr construction failed"); -#endif } template <class _Tp> @@ -196,7 +195,7 @@ typename __thread_specific_ptr<_Tp>::pointer __thread_specific_ptr<_Tp>::release() { pointer __p = get(); - pthread_setspecific(__key_, 0); + __libcpp_tl_set(__key_, nullptr); return __p; } @@ -205,7 +204,7 @@ void __thread_specific_ptr<_Tp>::reset(pointer __p) { pointer __p_old = get(); - pthread_setspecific(__key_, __p); + __libcpp_tl_set(__key_, __p); delete __p_old; } @@ -219,14 +218,14 @@ _LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; } // this_thread -template<> struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>; +template<> struct hash<__thread_id>; class _LIBCPP_TYPE_VIS_ONLY __thread_id { // FIXME: pthread_t is a pointer on Darwin but a long on Linux. // NULL is the no-thread value on Darwin. Someone needs to check // on other platforms. We assume 0 works everywhere for now. - pthread_t __id_; + __libcpp_thread_id __id_; public: _LIBCPP_INLINE_VISIBILITY @@ -234,13 +233,13 @@ public: friend _LIBCPP_INLINE_VISIBILITY bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT - {return __x.__id_ == __y.__id_;} + {return __libcpp_thread_id_equal(__x.__id_, __y.__id_);} friend _LIBCPP_INLINE_VISIBILITY bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT {return !(__x == __y);} friend _LIBCPP_INLINE_VISIBILITY bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT - {return __x.__id_ < __y.__id_;} + {return __libcpp_thread_id_less(__x.__id_, __y.__id_);} friend _LIBCPP_INLINE_VISIBILITY bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT {return !(__y < __x);} @@ -260,7 +259,7 @@ public: private: _LIBCPP_INLINE_VISIBILITY - __thread_id(pthread_t __id) : __id_(__id) {} + __thread_id(__libcpp_thread_id __id) : __id_(__id) {} friend __thread_id this_thread::get_id() _NOEXCEPT; friend class _LIBCPP_TYPE_VIS thread; @@ -274,7 +273,7 @@ struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id> _LIBCPP_INLINE_VISIBILITY size_t operator()(__thread_id __v) const { - return hash<pthread_t>()(__v.__id_); + return hash<__libcpp_thread_id>()(__v.__id_); } }; @@ -285,20 +284,20 @@ inline _LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT { - return pthread_self(); + return __libcpp_thread_get_current_id(); } } // this_thread class _LIBCPP_TYPE_VIS thread { - pthread_t __t_; + __libcpp_thread_t __t_; thread(const thread&); thread& operator=(const thread&); public: typedef __thread_id id; - typedef pthread_t native_handle_type; + typedef __libcpp_thread_t native_handle_type; _LIBCPP_INLINE_VISIBILITY thread() _NOEXCEPT : __t_(0) {} @@ -330,7 +329,7 @@ public: void join(); void detach(); _LIBCPP_INLINE_VISIBILITY - id get_id() const _NOEXCEPT {return __t_;} + id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);} _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() _NOEXCEPT {return __t_;} @@ -339,21 +338,21 @@ public: #ifndef _LIBCPP_HAS_NO_VARIADICS -template <class _Fp, class ..._Args, size_t ..._Indices> +template <class _TSp, class _Fp, class ..._Args, size_t ..._Indices> inline _LIBCPP_INLINE_VISIBILITY void -__thread_execute(tuple<_Fp, _Args...>& __t, __tuple_indices<_Indices...>) +__thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>) { - __invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...); + __invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...); } template <class _Fp> -void* -__thread_proxy(void* __vp) +void* __thread_proxy(void* __vp) { - __thread_local_data().reset(new __thread_struct); + // _Fp = std::tuple< unique_ptr<__thread_struct>, Functor, Args...> std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); - typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index; + __thread_local_data().reset(_VSTD::get<0>(*__p).release()); + typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index; __thread_execute(*__p, _Index()); return nullptr; } @@ -363,10 +362,14 @@ template <class _Fp, class ..._Args, > thread::thread(_Fp&& __f, _Args&&... __args) { - typedef tuple<typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp; - _VSTD::unique_ptr<_Gp> __p(new _Gp(__decay_copy(_VSTD::forward<_Fp>(__f)), - __decay_copy(_VSTD::forward<_Args>(__args))...)); - int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get()); + typedef unique_ptr<__thread_struct> _TSPtr; + _TSPtr __tsp(new __thread_struct); + typedef tuple<_TSPtr, typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp; + _VSTD::unique_ptr<_Gp> __p( + new _Gp(std::move(__tsp), + __decay_copy(_VSTD::forward<_Fp>(__f)), + __decay_copy(_VSTD::forward<_Args>(__args))...)); + int __ec = __libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get()); if (__ec == 0) __p.release(); else @@ -376,22 +379,34 @@ thread::thread(_Fp&& __f, _Args&&... __args) #else // _LIBCPP_HAS_NO_VARIADICS template <class _Fp> -void* -__thread_proxy(void* __vp) +struct __thread_invoke_pair { + // This type is used to pass memory for thread local storage and a functor + // to a newly created thread because std::pair doesn't work with + // std::unique_ptr in C++03. + __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {} + unique_ptr<__thread_struct> __tsp_; + _Fp __fn_; +}; + +template <class _Fp> +void* __thread_proxy_cxx03(void* __vp) { - __thread_local_data().reset(new __thread_struct); std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); - (*__p)(); + __thread_local_data().reset(__p->__tsp_.release()); + (__p->__fn_)(); return nullptr; } template <class _Fp> thread::thread(_Fp __f) { - std::unique_ptr<_Fp> __p(new _Fp(__f)); - int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Fp>, __p.get()); + + typedef __thread_invoke_pair<_Fp> _InvokePair; + typedef std::unique_ptr<_InvokePair> _PairPtr; + _PairPtr __pp(new _InvokePair(__f)); + int __ec = __libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get()); if (__ec == 0) - __p.release(); + __pp.release(); else __throw_system_error(__ec, "thread constructor failed"); } @@ -464,7 +479,7 @@ sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t) } inline _LIBCPP_INLINE_VISIBILITY -void yield() _NOEXCEPT {sched_yield();} +void yield() _NOEXCEPT {__libcpp_thread_yield();} } // this_thread diff --git a/include/tuple b/include/tuple index cb1e27d93cf26..6805d8c7635b7 100644 --- a/include/tuple +++ b/include/tuple @@ -76,10 +76,18 @@ template <class... T> tuple<V...> make_tuple(T&&...); // constexpr in C++14 template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14 template <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14 template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14 - + +// [tuple.apply], calling a function with a tuple of arguments: +template <class F, class Tuple> + constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17 +template <class T, class Tuple> + constexpr T make_from_tuple(Tuple&& t); // C++17 + // 20.4.1.4, tuple helper classes: template <class T> class tuple_size; // undefined template <class... T> class tuple_size<tuple<T...>>; +template <class T> + constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17 template <size_t I, class T> class tuple_element; // undefined template <size_t I, class... T> class tuple_element<I, tuple<T...>>; template <size_t I, class T> @@ -379,10 +387,8 @@ template <class ..._Tp> _LIBCPP_INLINE_VISIBILITY void __swallow(_Tp&&...) _NOEXCEPT {} -template <bool ..._Pred> -struct __all - : is_same<__all<_Pred...>, __all<(_Pred, true)...>> -{ }; +template <class ..._Tp> +struct __lazy_all : __all<_Tp::value...> {}; template <class _Tp> struct __all_default_constructible; @@ -446,7 +452,7 @@ struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...> template <class _Alloc, class _Tuple, class = typename enable_if < - __tuple_convertible<_Tuple, tuple<_Tp...> >::value + __tuple_constructible<_Tuple, tuple<_Tp...> >::value >::type > _LIBCPP_INLINE_VISIBILITY @@ -499,6 +505,28 @@ struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...> } }; +template <bool _IsTuple, class _SizeTrait, size_t _Expected> +struct __tuple_like_with_size_imp : false_type {}; + +template <class _SizeTrait, size_t _Expected> +struct __tuple_like_with_size_imp<true, _SizeTrait, _Expected> + : integral_constant<bool, _SizeTrait::value == _Expected> {}; + +template <class _Tuple, size_t _ExpectedSize, + class _RawTuple = typename __uncvref<_Tuple>::type> +using __tuple_like_with_size = __tuple_like_with_size_imp< + __tuple_like<_RawTuple>::value, + tuple_size<_RawTuple>, _ExpectedSize + >; + + +struct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail { + template <class ...> + static constexpr bool __enable_explicit() { return false; } + template <class ...> + static constexpr bool __enable_implicit() { return false; } +}; + template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple { @@ -506,6 +534,118 @@ class _LIBCPP_TYPE_VIS_ONLY tuple base base_; + template <class ..._Args> + struct _PackExpandsToThisTuple : false_type {}; + + template <class _Arg> + struct _PackExpandsToThisTuple<_Arg> + : is_same<typename __uncvref<_Arg>::type, tuple> {}; + + template <bool _MaybeEnable, class _Dummy = void> + struct _CheckArgsConstructor : __check_tuple_constructor_fail {}; + + template <class _Dummy> + struct _CheckArgsConstructor<true, _Dummy> + { + template <class ..._Args> + static constexpr bool __enable_explicit() { + return + __tuple_constructible< + tuple<_Args...>, + typename __make_tuple_types<tuple, + sizeof...(_Args) < sizeof...(_Tp) ? + sizeof...(_Args) : + sizeof...(_Tp)>::type + >::value && + !__tuple_convertible< + tuple<_Args...>, + typename __make_tuple_types<tuple, + sizeof...(_Args) < sizeof...(_Tp) ? + sizeof...(_Args) : + sizeof...(_Tp)>::type + >::value && + __all_default_constructible< + typename __make_tuple_types<tuple, sizeof...(_Tp), + sizeof...(_Args) < sizeof...(_Tp) ? + sizeof...(_Args) : + sizeof...(_Tp)>::type + >::value; + } + + template <class ..._Args> + static constexpr bool __enable_implicit() { + return + __tuple_convertible< + tuple<_Args...>, + typename __make_tuple_types<tuple, + sizeof...(_Args) < sizeof...(_Tp) ? + sizeof...(_Args) : + sizeof...(_Tp)>::type + >::value && + __all_default_constructible< + typename __make_tuple_types<tuple, sizeof...(_Tp), + sizeof...(_Args) < sizeof...(_Tp) ? + sizeof...(_Args) : + sizeof...(_Tp)>::type + >::value; + } + }; + + template <bool _MaybeEnable, + bool = sizeof...(_Tp) == 1, + class _Dummy = void> + struct _CheckTupleLikeConstructor : __check_tuple_constructor_fail {}; + + template <class _Dummy> + struct _CheckTupleLikeConstructor<true, false, _Dummy> + { + template <class _Tuple> + static constexpr bool __enable_implicit() { + return __tuple_convertible<_Tuple, tuple>::value; + } + + template <class _Tuple> + static constexpr bool __enable_explicit() { + return __tuple_constructible<_Tuple, tuple>::value + && !__tuple_convertible<_Tuple, tuple>::value; + } + }; + + template <class _Dummy> + struct _CheckTupleLikeConstructor<true, true, _Dummy> + { + // This trait is used to disable the tuple-like constructor when + // the UTypes... constructor should be selected instead. + // See LWG issue #2549. + template <class _Tuple> + using _PreferTupleLikeConstructor = __lazy_or< + // Don't attempt the two checks below if the tuple we are given + // has the same type as this tuple. + is_same<typename __uncvref<_Tuple>::type, tuple>, + __lazy_and< + __lazy_not<is_constructible<_Tp..., _Tuple>>, + __lazy_not<is_convertible<_Tuple, _Tp...>> + > + >; + + template <class _Tuple> + static constexpr bool __enable_implicit() { + return __lazy_and< + __tuple_convertible<_Tuple, tuple>, + _PreferTupleLikeConstructor<_Tuple> + >::value; + } + + template <class _Tuple> + static constexpr bool __enable_explicit() { + return __lazy_and< + __tuple_constructible<_Tuple, tuple>, + _PreferTupleLikeConstructor<_Tuple>, + __lazy_not<__tuple_convertible<_Tuple, tuple>> + >::value; + } + }; + template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT; template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 @@ -523,8 +663,30 @@ public: _LIBCPP_CONSTEXPR tuple() _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} + template <class _AllocArgT, class _Alloc, bool _Dummy = true, class = typename enable_if< + __lazy_and< + is_same<allocator_arg_t, _AllocArgT>, + __lazy_all<__dependent_type<is_default_constructible<_Tp>, _Dummy>...> + >::value + >::type> + _LIBCPP_INLINE_VISIBILITY + tuple(_AllocArgT, _Alloc const& __a) + : base_(allocator_arg_t(), __a, + __tuple_indices<>(), __tuple_types<>(), + typename __make_tuple_indices<sizeof...(_Tp), 0>::type(), + __tuple_types<_Tp...>()) {} + + template <bool _Dummy = true, + typename enable_if + < + _CheckArgsConstructor< + _Dummy + >::template __enable_implicit<_Tp...>(), + bool + >::type = false + > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) + tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(), typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), typename __make_tuple_indices<0>::type(), @@ -532,8 +694,54 @@ public: __t... ) {} - template <class _Alloc> + template <bool _Dummy = true, + typename enable_if + < + _CheckArgsConstructor< + _Dummy + >::template __enable_explicit<_Tp...>(), + bool + >::type = false + > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) + : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(), + typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), + typename __make_tuple_indices<0>::type(), + typename __make_tuple_types<tuple, 0>::type(), + __t... + ) {} + + template <class _Alloc, bool _Dummy = true, + typename enable_if + < + _CheckArgsConstructor< + _Dummy + >::template __enable_implicit<_Tp...>(), + bool + >::type = false + > + _LIBCPP_INLINE_VISIBILITY + tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) + : base_(allocator_arg_t(), __a, + typename __make_tuple_indices<sizeof...(_Tp)>::type(), + typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), + typename __make_tuple_indices<0>::type(), + typename __make_tuple_types<tuple, 0>::type(), + __t... + ) {} + + template <class _Alloc, bool _Dummy = true, + typename enable_if + < + _CheckArgsConstructor< + _Dummy + >::template __enable_explicit<_Tp...>(), + bool + >::type = false + > _LIBCPP_INLINE_VISIBILITY + explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) : base_(allocator_arg_t(), __a, typename __make_tuple_indices<sizeof...(_Tp)>::type(), @@ -546,21 +754,10 @@ public: template <class ..._Up, typename enable_if < - sizeof...(_Up) <= sizeof...(_Tp) && - __tuple_convertible - < - tuple<_Up...>, - typename __make_tuple_types<tuple, - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value && - __all_default_constructible< - typename __make_tuple_types<tuple, sizeof...(_Tp), - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value, + _CheckArgsConstructor< + sizeof...(_Up) <= sizeof...(_Tp) + && !_PackExpandsToThisTuple<_Up...>::value + >::template __enable_implicit<_Up...>(), bool >::type = false > @@ -584,31 +781,12 @@ public: template <class ..._Up, typename enable_if < - sizeof...(_Up) <= sizeof...(_Tp) && - __tuple_constructible - < - tuple<_Up...>, - typename __make_tuple_types<tuple, - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value && - !__tuple_convertible - < - tuple<_Up...>, - typename __make_tuple_types<tuple, - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value && - __all_default_constructible< - typename __make_tuple_types<tuple, sizeof...(_Tp), - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value, + _CheckArgsConstructor< + sizeof...(_Up) <= sizeof...(_Tp) + && !_PackExpandsToThisTuple<_Up...>::value + >::template __enable_explicit<_Up...>(), bool - >::type =false + >::type = false > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit @@ -629,26 +807,36 @@ public: _VSTD::forward<_Up>(__u)...) {} template <class _Alloc, class ..._Up, - class = typename enable_if + typename enable_if < - sizeof...(_Up) <= sizeof...(_Tp) && - __tuple_convertible - < - tuple<_Up...>, - typename __make_tuple_types<tuple, - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value && - __all_default_constructible< - typename __make_tuple_types<tuple, sizeof...(_Tp), - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value - >::type + _CheckArgsConstructor< + sizeof...(_Up) == sizeof...(_Tp) && + !_PackExpandsToThisTuple<_Up...>::value + >::template __enable_implicit<_Up...>(), + bool + >::type = false + > + _LIBCPP_INLINE_VISIBILITY + tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) + : base_(allocator_arg_t(), __a, + typename __make_tuple_indices<sizeof...(_Up)>::type(), + typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), + typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), + typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), + _VSTD::forward<_Up>(__u)...) {} + + template <class _Alloc, class ..._Up, + typename enable_if + < + _CheckArgsConstructor< + sizeof...(_Up) == sizeof...(_Tp) && + !_PackExpandsToThisTuple<_Up...>::value + >::template __enable_explicit<_Up...>(), + bool + >::type = false > _LIBCPP_INLINE_VISIBILITY + explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) : base_(allocator_arg_t(), __a, typename __make_tuple_indices<sizeof...(_Up)>::type(), @@ -660,7 +848,10 @@ public: template <class _Tuple, typename enable_if < - __tuple_convertible<_Tuple, tuple>::value, + _CheckTupleLikeConstructor< + __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value + && !_PackExpandsToThisTuple<_Tuple>::value + >::template __enable_implicit<_Tuple>(), bool >::type = false > @@ -671,8 +862,10 @@ public: template <class _Tuple, typename enable_if < - __tuple_constructible<_Tuple, tuple>::value && - !__tuple_convertible<_Tuple, tuple>::value, + _CheckTupleLikeConstructor< + __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value + && !_PackExpandsToThisTuple<_Tuple>::value + >::template __enable_explicit<_Tuple>(), bool >::type = false > @@ -682,12 +875,29 @@ public: : base_(_VSTD::forward<_Tuple>(__t)) {} template <class _Alloc, class _Tuple, - class = typename enable_if + typename enable_if < - __tuple_convertible<_Tuple, tuple>::value - >::type + _CheckTupleLikeConstructor< + __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value + >::template __enable_implicit<_Tuple>(), + bool + >::type = false + > + _LIBCPP_INLINE_VISIBILITY + tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) + : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {} + + template <class _Alloc, class _Tuple, + typename enable_if + < + _CheckTupleLikeConstructor< + __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value + >::template __enable_explicit<_Tuple>(), + bool + >::type = false > _LIBCPP_INLINE_VISIBILITY + explicit tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {} @@ -784,39 +994,44 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT } #if _LIBCPP_STD_VER > 11 -// get by type -template <typename _T1, size_t _Idx, typename... _Args> -struct __find_exactly_one_t_helper; - -// -- find exactly one -template <typename _T1, size_t _Idx, typename... _Args> -struct __find_exactly_one_t_checker { - static constexpr size_t value = _Idx; -// Check the rest of the list to make sure there's only one - static_assert ( __find_exactly_one_t_helper<_T1, 0, _Args...>::value == -1, "type can only occur once in type list" ); - }; +namespace __find_detail { -template <typename _T1, size_t _Idx> -struct __find_exactly_one_t_helper <_T1, _Idx> { - static constexpr size_t value = -1; - }; +static constexpr size_t __not_found = -1; +static constexpr size_t __ambiguous = __not_found - 1; -template <typename _T1, size_t _Idx, typename _Head, typename... _Args> -struct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> { - static constexpr size_t value = - std::conditional< - std::is_same<_T1, _Head>::value, - __find_exactly_one_t_checker<_T1, _Idx, _Args...>, - __find_exactly_one_t_helper <_T1, _Idx+1, _Args...> - >::type::value; - }; +inline _LIBCPP_INLINE_VISIBILITY +constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) { + return !__matches ? __res : + (__res == __not_found ? __curr_i : __ambiguous); +} + +template <size_t _Nx> +inline _LIBCPP_INLINE_VISIBILITY +constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) { + return __i == _Nx ? __not_found : + __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]); +} + +template <class _T1, class ..._Args> +struct __find_exactly_one_checked { + static constexpr bool __matches[] = {is_same<_T1, _Args>::value...}; + static constexpr size_t value = __find_detail::__find_idx(0, __matches); + static_assert (value != __not_found, "type not found in type list" ); + static_assert(value != __ambiguous,"type occurs more than once in type list"); +}; + +template <class _T1> +struct __find_exactly_one_checked<_T1> { + static_assert(!is_same<_T1, _T1>::value, "type not in empty type list"); +}; + +} // namespace __find_detail; template <typename _T1, typename... _Args> -struct __find_exactly_one_t { - static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value; - static_assert ( value != -1, "type not found in type list" ); - }; +struct __find_exactly_one_t + : public __find_detail::__find_exactly_one_checked<_T1, _Args...> { +}; template <class _T1, class... _Args> inline _LIBCPP_INLINE_VISIBILITY @@ -1154,6 +1369,50 @@ pair<_T1, _T2>::pair(piecewise_construct_t, #endif // _LIBCPP_HAS_NO_VARIADICS +#if _LIBCPP_STD_VER > 14 +template <class _Tp> +constexpr size_t tuple_size_v = tuple_size<_Tp>::value; + +#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; } + +template <class _Fn, class _Tuple, size_t ..._Id> +inline _LIBCPP_INLINE_VISIBILITY +constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t, + __tuple_indices<_Id...>) +_LIBCPP_NOEXCEPT_RETURN( + _VSTD::__invoke_constexpr( + _VSTD::forward<_Fn>(__f), + _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...) +) + +template <class _Fn, class _Tuple> +inline _LIBCPP_INLINE_VISIBILITY +constexpr decltype(auto) apply(_Fn && __f, _Tuple && __t) +_LIBCPP_NOEXCEPT_RETURN( + _VSTD::__apply_tuple_impl( + _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t), + typename __make_tuple_indices<tuple_size_v<decay_t<_Tuple>>>::type{}) +) + +template <class _Tp, class _Tuple, size_t... _Idx> +inline _LIBCPP_INLINE_VISIBILITY +constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>) +_LIBCPP_NOEXCEPT_RETURN( + _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...) +) + +template <class _Tp, class _Tuple> +inline _LIBCPP_INLINE_VISIBILITY +constexpr _Tp make_from_tuple(_Tuple&& __t) +_LIBCPP_NOEXCEPT_RETURN( + _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t), + typename __make_tuple_indices<tuple_size_v<decay_t<_Tuple>>>::type{}) +) + +#undef _LIBCPP_NOEXCEPT_RETURN + +#endif // _LIBCPP_STD_VER > 14 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_TUPLE diff --git a/include/type_traits b/include/type_traits index b7adfebceeb96..821a73c764dd5 100644 --- a/include/type_traits +++ b/include/type_traits @@ -105,6 +105,8 @@ namespace std template <class T, class U> struct is_assignable; template <class T> struct is_copy_assignable; template <class T> struct is_move_assignable; + template <class T, class U> struct is_swappable_with; // C++17 + template <class T> struct is_swappable; // C++17 template <class T> struct is_destructible; template <class T, class... Args> struct is_trivially_constructible; @@ -123,6 +125,8 @@ namespace std template <class T, class U> struct is_nothrow_assignable; template <class T> struct is_nothrow_copy_assignable; template <class T> struct is_nothrow_move_assignable; + template <class T, class U> struct is_nothrow_swappable_with; // C++17 + template <class T> struct is_nothrow_swappable; // C++17 template <class T> struct is_nothrow_destructible; template <class T> struct has_virtual_destructor; @@ -132,6 +136,14 @@ namespace std template <class Base, class Derived> struct is_base_of; template <class From, class To> struct is_convertible; + template <class, class R = void> struct is_callable; // not defined + template <class Fn, class... ArgTypes, class R> + struct is_callable<Fn(ArgTypes...), R>; + + template <class, class R = void> struct is_nothrow_callable; // not defined + template <class Fn, class... ArgTypes, class R> + struct is_nothrow_callable<Fn(ArgTypes...), R>; + // Alignment properties and transformations: template <class T> struct alignment_of; template <size_t Len, size_t Align = most_stringent_alignment_requirement> @@ -292,6 +304,10 @@ namespace std = is_copy_assignable<T>::value; // C++17 template <class T> constexpr bool is_move_assignable_v = is_move_assignable<T>::value; // C++17 + template <class T, class U> constexpr bool is_swappable_with_v + = is_swappable_with<T, U>::value; // C++17 + template <class T> constexpr bool is_swappable_v + = is_swappable<T>::value; // C++17 template <class T> constexpr bool is_destructible_v = is_destructible<T>::value; // C++17 template <class T, class... Args> constexpr bool is_trivially_constructible_v @@ -324,6 +340,10 @@ namespace std = is_nothrow_copy_assignable<T>::value; // C++17 template <class T> constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<T>::value; // C++17 + template <class T, class U> constexpr bool is_nothrow_swappable_with_v + = is_nothrow_swappable_with<T, U>::value; // C++17 + template <class T> constexpr bool is_nothrow_swappable_v + = is_nothrow_swappable<T>::value; // C++17 template <class T> constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<T>::value; // C++17 template <class T> constexpr bool has_virtual_destructor_v @@ -344,6 +364,10 @@ namespace std = is_base_of<Base, Derived>::value; // C++17 template <class From, class To> constexpr bool is_convertible_v = is_convertible<From, To>::value; // C++17 + template <class T, class R = void> constexpr bool is_callable_v + = is_callable<T, R>::value; // C++17 + template <class T, class R = void> constexpr bool is_nothrow_callable_v + = is_nothrow_callable<T, R>::value; // C++17 // [meta.logical], logical operator traits: template<class... B> struct conjunction; // C++17 @@ -368,6 +392,10 @@ namespace std _LIBCPP_BEGIN_NAMESPACE_STD +template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair; +template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY reference_wrapper; +template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash; + template <class> struct __void_t { typedef void type; }; @@ -397,15 +425,29 @@ template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp #endif // addressof +#if __has_builtin(__builtin_addressof) template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_NO_CFI _LIBCPP_INLINE_VISIBILITY +_Tp* +addressof(_Tp& __x) _NOEXCEPT +{ + return __builtin_addressof(__x); +} + +#else + +template <class _Tp> +inline _LIBCPP_NO_CFI _LIBCPP_INLINE_VISIBILITY _Tp* addressof(_Tp& __x) _NOEXCEPT { return (_Tp*)&reinterpret_cast<const volatile char&>(__x); } +#endif // __has_builtin(__builtin_addressof) + #if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF) // Objective-C++ Automatic Reference Counting uses qualified pointers // that require special addressof() signatures. When @@ -957,6 +999,19 @@ template <class _Tp> _LIBCPP_CONSTEXPR bool is_compound_v = is_compound<_Tp>::value; #endif + +// __is_referenceable [defns.referenceable] + +struct __is_referenceable_impl { + template <class _Tp> static _Tp& __test(int); + template <class _Tp> static __two __test(...); +}; + +template <class _Tp> +struct __is_referenceable : integral_constant<bool, + !is_same<decltype(__is_referenceable_impl::__test<_Tp>(0)), __two>::value> {}; + + // add_const template <class _Tp, bool = is_reference<_Tp>::value || @@ -1014,12 +1069,11 @@ template <class _Tp> using remove_reference_t = typename remove_reference<_Tp>:: // add_lvalue_reference -template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference {typedef _Tp& type;}; -template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<_Tp&> {typedef _Tp& type;}; // for older compiler -template <> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<void> {typedef void type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<const void> {typedef const void type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<volatile void> {typedef volatile void type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<const volatile void> {typedef const volatile void type;}; +template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_lvalue_reference_impl { typedef _Tp type; }; +template <class _Tp > struct __add_lvalue_reference_impl<_Tp, true> { typedef _Tp& type; }; + +template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference +{typedef typename __add_lvalue_reference_impl<_Tp>::type type;}; #if _LIBCPP_STD_VER > 11 template <class _Tp> using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type; @@ -1027,11 +1081,11 @@ template <class _Tp> using add_lvalue_reference_t = typename add_lvalue_referenc #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference {typedef _Tp&& type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<void> {typedef void type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<const void> {typedef const void type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<volatile void> {typedef volatile void type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<const volatile void> {typedef const volatile void type;}; +template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_rvalue_reference_impl { typedef _Tp type; }; +template <class _Tp > struct __add_rvalue_reference_impl<_Tp, true> { typedef _Tp&& type; }; + +template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference +{typedef typename __add_rvalue_reference_impl<_Tp>::type type;}; #if _LIBCPP_STD_VER > 11 template <class _Tp> using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type; @@ -1041,8 +1095,11 @@ template <class _Tp> using add_rvalue_reference_t = typename add_rvalue_referenc #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +template <class _Tp> _Tp&& __declval(int); +template <class _Tp> _Tp __declval(long); + template <class _Tp> -typename add_rvalue_reference<_Tp>::type +decltype(_VSTD::__declval<_Tp>(0)) declval() _NOEXCEPT; #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -1053,6 +1110,24 @@ declval(); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +// __uncvref + +template <class _Tp> +struct __uncvref { + typedef typename remove_cv<typename remove_reference<_Tp>::type>::type type; +}; + +template <class _Tp> +struct __unconstref { + typedef typename remove_const<typename remove_reference<_Tp>::type>::type type; +}; + +// __is_same_uncvref + +template <class _Tp, class _Up> +struct __is_same_uncvref : is_same<typename __uncvref<_Tp>::type, + typename __uncvref<_Up>::type> {}; + struct __any { __any(...); @@ -1072,8 +1147,16 @@ template <class _Tp> using remove_pointer_t = typename remove_pointer<_Tp>::type // add_pointer -template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_pointer +template <class _Tp, + bool = __is_referenceable<_Tp>::value || + is_same<typename remove_cv<_Tp>::type, void>::value> +struct __add_pointer_impl {typedef typename remove_reference<_Tp>::type* type;}; +template <class _Tp> struct __add_pointer_impl<_Tp, false> + {typedef _Tp type;}; + +template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_pointer + {typedef typename __add_pointer_impl<_Tp>::type type;}; #if _LIBCPP_STD_VER > 11 template <class _Tp> using add_pointer_t = typename add_pointer<_Tp>::type; @@ -1301,16 +1384,9 @@ 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 + decltype(_VSTD::__is_convertible_imp::__test_convert<_To>(_VSTD::declval<_From>()))> : public true_type {}; -template <class _Tp> __two __test(...); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -template <class _Tp> _Tp&& __source(); -#else -template <class _Tp> typename remove_reference<_Tp>::type& __source(); -#endif - template <class _Tp, bool _IsArray = is_array<_Tp>::value, bool _IsFunction = is_function<_Tp>::value, bool _IsVoid = is_void<_Tp>::value> @@ -1350,41 +1426,6 @@ struct __is_convertible > {}; -template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 0> : false_type {}; - -template <class _T1> struct __is_convertible<_T1, const _T1&, 1, 0> : true_type {}; -template <class _T1> struct __is_convertible<const _T1, const _T1&, 1, 0> : true_type {}; -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -template <class _T1> struct __is_convertible<_T1, _T1&&, 1, 0> : true_type {}; -template <class _T1> struct __is_convertible<_T1, const _T1&&, 1, 0> : true_type {}; -template <class _T1> struct __is_convertible<_T1, volatile _T1&&, 1, 0> : true_type {}; -template <class _T1> struct __is_convertible<_T1, const volatile _T1&&, 1, 0> : true_type {}; -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - -template <class _T1, class _T2> struct __is_convertible<_T1, _T2*, 1, 0> - : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*>::value> {}; - -template <class _T1, class _T2> struct __is_convertible<_T1, _T2* const, 1, 0> - : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*const>::value> {}; - -template <class _T1, class _T2> struct __is_convertible<_T1, _T2* volatile, 1, 0> - : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*volatile>::value> {}; - -template <class _T1, class _T2> struct __is_convertible<_T1, _T2* const volatile, 1, 0> - : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*const volatile>::value> {}; - -template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 0> : public false_type {}; -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -template <class _T1> struct __is_convertible<_T1, _T1&&, 2, 0> : public true_type {}; -#endif -template <class _T1> struct __is_convertible<_T1, _T1&, 2, 0> : public true_type {}; -template <class _T1> struct __is_convertible<_T1, _T1*, 2, 0> : public true_type {}; -template <class _T1> struct __is_convertible<_T1, _T1*const, 2, 0> : public true_type {}; -template <class _T1> struct __is_convertible<_T1, _T1*volatile, 2, 0> : public true_type {}; -template <class _T1> struct __is_convertible<_T1, _T1*const volatile, 2, 0> : public true_type {}; - -template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 0> : public false_type {}; - template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type {}; template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type {}; template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type {}; @@ -2136,7 +2177,7 @@ move(_Tp&& __t) _NOEXCEPT template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp&& -forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT +forward(typename remove_reference<_Tp>::type& __t) _NOEXCEPT { return static_cast<_Tp&&>(__t); } @@ -2144,9 +2185,9 @@ forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp&& -forward(typename std::remove_reference<_Tp>::type&& __t) _NOEXCEPT +forward(typename remove_reference<_Tp>::type&& __t) _NOEXCEPT { - static_assert(!std::is_lvalue_reference<_Tp>::value, + static_assert(!is_lvalue_reference<_Tp>::value, "Can not forward an rvalue as an lvalue."); return static_cast<_Tp&&>(__t); } @@ -2172,7 +2213,7 @@ move(const _Tp& __t) template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _Tp& -forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT +forward(typename remove_reference<_Tp>::type& __t) _NOEXCEPT { return __t; } @@ -2691,6 +2732,15 @@ struct __member_pointer_traits // typedef ... _FnType; }; + +template <class _DecayedFp> +struct __member_pointer_class_type {}; + +template <class _Ret, class _ClassType> +struct __member_pointer_class_type<_Ret _ClassType::*> { + typedef _ClassType type; +}; + // result_of template <class _Callable> class result_of; @@ -3918,7 +3968,12 @@ template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivial_v = is_trivial<_Tp>::value; #endif -#ifndef _LIBCPP_HAS_NO_VARIADICS +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> {}; + +#ifndef _LIBCPP_CXX03_LANG // Check for complete types @@ -4006,8 +4061,6 @@ struct __check_complete<_Rp (_Class::*)(_Param...) const volatile> { }; -#if __has_feature(cxx_reference_qualified_functions) - template <class _Rp, class _Class, class ..._Param> struct __check_complete<_Rp (_Class::*)(_Param...) &> : private __check_complete<_Class> @@ -4056,125 +4109,257 @@ struct __check_complete<_Rp (_Class::*)(_Param...) const volatile&&> { }; -#endif - template <class _Rp, class _Class> struct __check_complete<_Rp _Class::*> : private __check_complete<_Class> { }; + +template <class _Fp, class _A0, + class _DecayFp = typename decay<_Fp>::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet1 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && is_base_of<_ClassT, _DecayA0>::value + >::type; + +template <class _Fp, class _A0, + class _DecayFp = typename decay<_Fp>::type, + class _DecayA0 = typename decay<_A0>::type> +using __enable_if_bullet2 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && __is_reference_wrapper<_DecayA0>::value + >::type; + +template <class _Fp, class _A0, + class _DecayFp = typename decay<_Fp>::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet3 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && !is_base_of<_ClassT, _DecayA0>::value + && !__is_reference_wrapper<_DecayA0>::value + >::type; + +template <class _Fp, class _A0, + class _DecayFp = typename decay<_Fp>::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet4 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && is_base_of<_ClassT, _DecayA0>::value + >::type; + +template <class _Fp, class _A0, + class _DecayFp = typename decay<_Fp>::type, + class _DecayA0 = typename decay<_A0>::type> +using __enable_if_bullet5 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && __is_reference_wrapper<_DecayA0>::value + >::type; + +template <class _Fp, class _A0, + class _DecayFp = typename decay<_Fp>::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet6 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && !is_base_of<_ClassT, _DecayA0>::value + && !__is_reference_wrapper<_DecayA0>::value + >::type; + // __invoke forward declarations // fall back - none of the bullets +#define _LIBCPP_INVOKE_RETURN(...) \ + noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) \ + { return __VA_ARGS__; } + +template <class ..._Args> +auto __invoke(__any, _Args&& ...__args) -> __nat; + template <class ..._Args> +auto __invoke_constexpr(__any, _Args&& ...__args) -> __nat; + +// bullets 1, 2 and 3 + +template <class _Fp, class _A0, class ..._Args, + class = __enable_if_bullet1<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY auto -__invoke(__any, _Args&& ...__args) - -> __nat; +__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) +_LIBCPP_INVOKE_RETURN((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)) -// bullets 1 and 2 +template <class _Fp, class _A0, class ..._Args, + class = __enable_if_bullet1<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args) +_LIBCPP_INVOKE_RETURN((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)) template <class _Fp, class _A0, class ..._Args, - class = typename enable_if - < - is_member_function_pointer<typename remove_reference<_Fp>::type>::value && - is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType>::type, - typename remove_reference<_A0>::type>::value - >::type - > -_LIBCPP_INLINE_VISIBILITY + class = __enable_if_bullet2<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)); +_LIBCPP_INVOKE_RETURN((__a0.get().*__f)(_VSTD::forward<_Args>(__args)...)) template <class _Fp, class _A0, class ..._Args, - class = typename enable_if - < - is_member_function_pointer<typename remove_reference<_Fp>::type>::value && - !is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType>::type, - typename remove_reference<_A0>::type>::value - >::type - > -_LIBCPP_INLINE_VISIBILITY + class = __enable_if_bullet2<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args) +_LIBCPP_INVOKE_RETURN((__a0.get().*__f)(_VSTD::forward<_Args>(__args)...)) + +template <class _Fp, class _A0, class ..._Args, + class = __enable_if_bullet3<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)); +_LIBCPP_INVOKE_RETURN(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)) + +template <class _Fp, class _A0, class ..._Args, + class = __enable_if_bullet3<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args) +_LIBCPP_INVOKE_RETURN(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)) -// bullets 3 and 4 +// bullets 4, 5 and 6 template <class _Fp, class _A0, - class = typename enable_if - < - is_member_object_pointer<typename remove_reference<_Fp>::type>::value && - is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType, - typename remove_reference<_A0>::type>::value - >::type - > -_LIBCPP_INLINE_VISIBILITY + class = __enable_if_bullet4<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0) - -> decltype(_VSTD::forward<_A0>(__a0).*__f); +_LIBCPP_INVOKE_RETURN(_VSTD::forward<_A0>(__a0).*__f) + +template <class _Fp, class _A0, + class = __enable_if_bullet4<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _A0&& __a0) +_LIBCPP_INVOKE_RETURN(_VSTD::forward<_A0>(__a0).*__f) template <class _Fp, class _A0, - class = typename enable_if - < - is_member_object_pointer<typename remove_reference<_Fp>::type>::value && - !is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType, - typename remove_reference<_A0>::type>::value - >::type - > -_LIBCPP_INLINE_VISIBILITY + class = __enable_if_bullet5<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0) - -> decltype((*_VSTD::forward<_A0>(__a0)).*__f); +_LIBCPP_INVOKE_RETURN(__a0.get().*__f) -// bullet 5 +template <class _Fp, class _A0, + class = __enable_if_bullet5<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _A0&& __a0) +_LIBCPP_INVOKE_RETURN(__a0.get().*__f) + +template <class _Fp, class _A0, + class = __enable_if_bullet6<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +auto +__invoke(_Fp&& __f, _A0&& __a0) +_LIBCPP_INVOKE_RETURN((*_VSTD::forward<_A0>(__a0)).*__f) + +template <class _Fp, class _A0, + class = __enable_if_bullet6<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _A0&& __a0) +_LIBCPP_INVOKE_RETURN((*_VSTD::forward<_A0>(__a0)).*__f) + +// bullet 7 template <class _Fp, class ..._Args> -_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _Args&& ...__args) - -> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)); +_LIBCPP_INVOKE_RETURN(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)) + +template <class _Fp, class ..._Args> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _Args&& ...__args) +_LIBCPP_INVOKE_RETURN(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)) + +#undef _LIBCPP_INVOKE_RETURN // __invokable -template <class _Fp, class ..._Args> -struct __invokable_imp +template <class _Ret, class _Fp, class ..._Args> +struct __invokable_r : private __check_complete<_Fp> { - typedef decltype( - __invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...) - ) type; - static const bool value = !is_same<type, __nat>::value; + using _Result = decltype( + _VSTD::__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...)); + + static const bool value = + conditional< + !is_same<_Result, __nat>::value, + typename conditional< + is_void<_Ret>::value, + true_type, + is_convertible<_Result, _Ret> + >::type, + false_type + >::type::value; }; template <class _Fp, class ..._Args> -struct __invokable - : public integral_constant<bool, - __invokable_imp<_Fp, _Args...>::value> -{ -}; +using __invokable = __invokable_r<void, _Fp, _Args...>; -// __invoke_of +template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class ..._Args> +struct __nothrow_invokable_r_imp { + static const bool value = false; +}; -template <bool _Invokable, class _Fp, class ..._Args> -struct __invoke_of_imp // false +template <class _Ret, class _Fp, class ..._Args> +struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...> { + typedef __nothrow_invokable_r_imp _ThisT; + + template <class _Tp> + static void __test_noexcept(_Tp) noexcept; + + static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>( + _VSTD::__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...))); }; -template <class _Fp, class ..._Args> -struct __invoke_of_imp<true, _Fp, _Args...> +template <class _Ret, class _Fp, class ..._Args> +struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...> { - typedef typename __invokable_imp<_Fp, _Args...>::type type; + static const bool value = noexcept( + _VSTD::__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...)); }; +template <class _Ret, class _Fp, class ..._Args> +using __nothrow_invokable_r = + __nothrow_invokable_r_imp< + __invokable_r<_Ret, _Fp, _Args...>::value, + is_void<_Ret>::value, + _Ret, _Fp, _Args... + >; + template <class _Fp, class ..._Args> struct __invoke_of - : public __invoke_of_imp<__invokable<_Fp, _Args...>::value, _Fp, _Args...> + : public enable_if< + __invokable<_Fp, _Args...>::value, + typename __invokable_r<void, _Fp, _Args...>::_Result> { }; +// result_of + template <class _Fp, class ..._Args> class _LIBCPP_TYPE_VIS_ONLY result_of<_Fp(_Args...)> : public __invoke_of<_Fp, _Args...> @@ -4185,7 +4370,39 @@ class _LIBCPP_TYPE_VIS_ONLY result_of<_Fp(_Args...)> template <class _Tp> using result_of_t = typename result_of<_Tp>::type; #endif -#endif // _LIBCPP_HAS_NO_VARIADICS +#if _LIBCPP_STD_VER > 14 + +// is_callable + +template <class _Fn, class _Ret = void> +struct _LIBCPP_TYPE_VIS_ONLY is_callable; + +template <class _Fn, class ..._Args, class _Ret> +struct _LIBCPP_TYPE_VIS_ONLY is_callable<_Fn(_Args...), _Ret> + : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {}; + +template <class _Fn, class _Ret = void> +constexpr bool is_callable_v = is_callable<_Fn, _Ret>::value; + +// is_nothrow_callable + +template <class _Fn, class _Ret = void> +struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_callable; + +template <class _Fn, class ..._Args, class _Ret> +struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_callable<_Fn(_Args...), _Ret> + : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> +{}; + +template <class _Fn, class _Ret = void> +constexpr bool is_nothrow_callable_v = is_nothrow_callable<_Fn, _Ret>::value; + +#endif // _LIBCPP_STD_VER > 14 + +#endif // !defined(_LIBCPP_CXX03_LANG) + +template <class _Tp> struct __is_swappable; +template <class _Tp> struct __is_nothrow_swappable; template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY @@ -4206,6 +4423,13 @@ swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value && __y = _VSTD::move(__t); } +template<class _Tp, size_t _Np> +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if< + __is_swappable<_Tp>::value +>::type +swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value); + template <class _ForwardIterator1, class _ForwardIterator2> inline _LIBCPP_INLINE_VISIBILITY void @@ -4221,55 +4445,108 @@ iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) namespace __detail { +// ALL generic swap overloads MUST already have a declaration available at this point. -using _VSTD::swap; -__nat swap(__any, __any); - -template <class _Tp> -struct __swappable +template <class _Tp, class _Up = _Tp, + bool _NotVoid = !is_void<_Tp>::value && !is_void<_Up>::value> +struct __swappable_with { - typedef decltype(swap(_VSTD::declval<_Tp&>(), _VSTD::declval<_Tp&>())) type; - static const bool value = !is_same<type, __nat>::value; + template <class _LHS, class _RHS> + static decltype(swap(_VSTD::declval<_LHS>(), _VSTD::declval<_RHS>())) + __test_swap(int); + template <class, class> + static __nat __test_swap(long); + + // Extra parens are needed for the C++03 definition of decltype. + typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1; + typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2; + + static const bool value = !is_same<__swap1, __nat>::value + && !is_same<__swap2, __nat>::value; }; +template <class _Tp, class _Up> +struct __swappable_with<_Tp, _Up, false> : false_type {}; + +template <class _Tp, class _Up = _Tp, bool _Swappable = __swappable_with<_Tp, _Up>::value> +struct __nothrow_swappable_with { + static const bool value = +#ifndef _LIBCPP_HAS_NO_NOEXCEPT + noexcept(swap(_VSTD::declval<_Tp>(), _VSTD::declval<_Up>())) + && noexcept(swap(_VSTD::declval<_Up>(), _VSTD::declval<_Tp>())); +#else + false; +#endif +}; + +template <class _Tp, class _Up> +struct __nothrow_swappable_with<_Tp, _Up, false> : false_type {}; + } // __detail template <class _Tp> struct __is_swappable - : public integral_constant<bool, __detail::__swappable<_Tp>::value> + : public integral_constant<bool, __detail::__swappable_with<_Tp&>::value> { }; -#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L) - -template <bool, class _Tp> -struct __is_nothrow_swappable_imp - : public integral_constant<bool, noexcept(swap(_VSTD::declval<_Tp&>(), - _VSTD::declval<_Tp&>()))> +template <class _Tp> +struct __is_nothrow_swappable + : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp&>::value> { }; -template <class _Tp> -struct __is_nothrow_swappable_imp<false, _Tp> - : public false_type +#if _LIBCPP_STD_VER > 14 + +template <class _Tp, class _Up> +struct _LIBCPP_TYPE_VIS_ONLY is_swappable_with + : public integral_constant<bool, __detail::__swappable_with<_Tp, _Up>::value> { }; template <class _Tp> -struct __is_nothrow_swappable - : public __is_nothrow_swappable_imp<__is_swappable<_Tp>::value, _Tp> +struct _LIBCPP_TYPE_VIS_ONLY is_swappable + : public conditional< + __is_referenceable<_Tp>::value, + is_swappable_with< + typename add_lvalue_reference<_Tp>::type, + typename add_lvalue_reference<_Tp>::type>, + false_type + >::type { }; -#else // __has_feature(cxx_noexcept) +template <class _Tp, class _Up> +struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_swappable_with + : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp, _Up>::value> +{ +}; template <class _Tp> -struct __is_nothrow_swappable - : public false_type +struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_swappable + : public conditional< + __is_referenceable<_Tp>::value, + is_nothrow_swappable_with< + typename add_lvalue_reference<_Tp>::type, + typename add_lvalue_reference<_Tp>::type>, + false_type + >::type { }; -#endif // __has_feature(cxx_noexcept) +template <class _Tp, class _Up> +constexpr bool is_swappable_with_v = is_swappable_with<_Tp, _Up>::value; + +template <class _Tp> +constexpr bool is_swappable_v = is_swappable<_Tp>::value; + +template <class _Tp, class _Up> +constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<_Tp, _Up>::value; + +template <class _Tp> +constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Tp>::value; + +#endif // _LIBCPP_STD_VER > 14 #ifdef _LIBCPP_UNDERLYING_TYPE @@ -4296,7 +4573,7 @@ struct underlying_type #endif // _LIBCPP_UNDERLYING_TYPE -template <class _Tp, bool = std::is_enum<_Tp>::value> +template <class _Tp, bool = is_enum<_Tp>::value> struct __sfinae_underlying_type { typedef typename underlying_type<_Tp>::type type; @@ -4389,6 +4666,39 @@ template<class _Tp> constexpr bool negation_v = negation<_Tp>::value; # endif // _LIBCPP_HAS_NO_VARIADICS #endif // _LIBCPP_STD_VER > 14 +// These traits are used in __tree and __hash_table +#ifndef _LIBCPP_CXX03_LANG +struct __extract_key_fail_tag {}; +struct __extract_key_self_tag {}; +struct __extract_key_first_tag {}; + +template <class _ValTy, class _Key, + class _RawValTy = typename __unconstref<_ValTy>::type> +struct __can_extract_key + : conditional<is_same<_RawValTy, _Key>::value, __extract_key_self_tag, + __extract_key_fail_tag>::type {}; + +template <class _Pair, class _Key, class _First, class _Second> +struct __can_extract_key<_Pair, _Key, pair<_First, _Second>> + : conditional<is_same<typename remove_const<_First>::type, _Key>::value, + __extract_key_first_tag, __extract_key_fail_tag>::type {}; + +// __can_extract_map_key uses true_type/false_type instead of the tags. +// It returns true if _Key != _ContainerValueTy (the container is a map not a set) +// and _ValTy == _Key. +template <class _ValTy, class _Key, class _ContainerValueTy, + class _RawValTy = typename __unconstref<_ValTy>::type> +struct __can_extract_map_key + : integral_constant<bool, is_same<_RawValTy, _Key>::value> {}; + +// This specialization returns __extract_key_fail_tag for non-map containers +// because _Key == _ContainerValueTy +template <class _ValTy, class _Key, class _RawValTy> +struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy> + : false_type {}; + +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_TYPE_TRAITS diff --git a/include/unordered_map b/include/unordered_map index 85a54a7b6ddba..bf64ad66f39a6 100644 --- a/include/unordered_map +++ b/include/unordered_map @@ -369,6 +369,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc> #include <__hash_table> #include <functional> #include <stdexcept> +#include <tuple> #include <__debug> @@ -413,7 +414,6 @@ template <class _Key, class _Cp, class _Hash> class __unordered_map_hasher<_Key, _Cp, _Hash, false> { _Hash __hash_; - public: _LIBCPP_INLINE_VISIBILITY __unordered_map_hasher() @@ -487,7 +487,6 @@ template <class _Key, class _Cp, class _Pred> class __unordered_map_equal<_Key, _Cp, _Pred, false> { _Pred __pred_; - public: _LIBCPP_INLINE_VISIBILITY __unordered_map_equal() @@ -531,12 +530,11 @@ class __hash_map_node_destructor { typedef _Alloc allocator_type; typedef allocator_traits<allocator_type> __alloc_traits; - typedef typename __alloc_traits::value_type::value_type value_type; + public: - typedef typename __alloc_traits::pointer pointer; + + typedef typename __alloc_traits::pointer pointer; private: - typedef typename value_type::value_type::first_type first_type; - typedef typename value_type::value_type::second_type second_type; allocator_type& __na_; @@ -586,8 +584,7 @@ public: } }; -#if __cplusplus >= 201103L - +#ifndef _LIBCPP_CXX03_LANG template <class _Key, class _Tp> union __hash_value_type { @@ -599,19 +596,6 @@ union __hash_value_type value_type __cc; __nc_value_type __nc; - template <class ..._Args> - _LIBCPP_INLINE_VISIBILITY - __hash_value_type(_Args&& ...__args) - : __cc(std::forward<_Args>(__args)...) {} - - _LIBCPP_INLINE_VISIBILITY - __hash_value_type(const __hash_value_type& __v) - : __cc(__v.__cc) {} - - _LIBCPP_INLINE_VISIBILITY - __hash_value_type(__hash_value_type&& __v) - : __nc(_VSTD::move(__v.__nc)) {} - _LIBCPP_INLINE_VISIBILITY __hash_value_type& operator=(const __hash_value_type& __v) {__nc = __v.__cc; return *this;} @@ -620,8 +604,23 @@ union __hash_value_type __hash_value_type& operator=(__hash_value_type&& __v) {__nc = _VSTD::move(__v.__nc); return *this;} + template <class _ValueTp, + class = typename enable_if< + __is_same_uncvref<_ValueTp, value_type>::value + >::type + > _LIBCPP_INLINE_VISIBILITY - ~__hash_value_type() {__cc.~value_type();} + __hash_value_type& operator=(_ValueTp&& __v) { + __nc = _VSTD::forward<_ValueTp>(__v); return *this; + } + +private: + __hash_value_type(const __hash_value_type& __v) = delete; + __hash_value_type(__hash_value_type&& __v) = delete; + template <class ..._Args> + explicit __hash_value_type(_Args&& ...__args) = delete; + + ~__hash_value_type() = delete; }; #else @@ -635,18 +634,8 @@ struct __hash_value_type value_type __cc; - _LIBCPP_INLINE_VISIBILITY - __hash_value_type() {} - - template <class _A0> - _LIBCPP_INLINE_VISIBILITY - __hash_value_type(const _A0& __a0) - : __cc(__a0) {} - - template <class _A0, class _A1> - _LIBCPP_INLINE_VISIBILITY - __hash_value_type(const _A0& __a0, const _A1& __a1) - : __cc(__a0, __a1) {} +private: + ~__hash_value_type(); }; #endif @@ -656,15 +645,14 @@ class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator { _HashIterator __i_; - typedef const typename _HashIterator::value_type::value_type::first_type key_type; - typedef typename _HashIterator::value_type::value_type::second_type mapped_type; + typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes; + public: typedef forward_iterator_tag iterator_category; - typedef pair<key_type, mapped_type> value_type; - typedef typename _HashIterator::difference_type difference_type; + typedef typename _NodeTypes::__map_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; typedef value_type& reference; - typedef typename __rebind_pointer<typename _HashIterator::pointer, value_type>::type - pointer; + typedef typename _NodeTypes::__map_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_map_iterator() _NOEXCEPT {} @@ -706,15 +694,14 @@ class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator { _HashIterator __i_; - typedef const typename _HashIterator::value_type::value_type::first_type key_type; - typedef typename _HashIterator::value_type::value_type::second_type mapped_type; + typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes; + public: typedef forward_iterator_tag iterator_category; - typedef pair<key_type, mapped_type> value_type; - typedef typename _HashIterator::difference_type difference_type; + typedef typename _NodeTypes::__map_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; typedef const value_type& reference; - typedef typename __rebind_pointer<typename _HashIterator::pointer, const value_type>::type - pointer; + typedef typename _NodeTypes::__const_map_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator() _NOEXCEPT {} @@ -785,6 +772,7 @@ private: __table __table_; + typedef typename __table::_NodeTypes _NodeTypes; typedef typename __table::__node_pointer __node_pointer; typedef typename __table::__node_const_pointer __node_const_pointer; typedef typename __table::__node_traits __node_traits; @@ -793,11 +781,14 @@ private: typedef __hash_map_node_destructor<__node_allocator> _Dp; typedef unique_ptr<__node, _Dp> __node_holder; typedef allocator_traits<allocator_type> __alloc_traits; + + static_assert((is_same<typename __table::__container_value_type, value_type>::value), ""); + static_assert((is_same<typename __table::__node_value_type, __value_type>::value), ""); public: typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; - typedef typename __alloc_traits::size_type size_type; - typedef typename __alloc_traits::difference_type difference_type; + typedef typename __table::size_type size_type; + typedef typename __table::difference_type difference_type; typedef __hash_map_iterator<typename __table::iterator> iterator; typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator; @@ -828,10 +819,12 @@ public: size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); + _LIBCPP_INLINE_VISIBILITY explicit unordered_map(const allocator_type& __a); unordered_map(const unordered_map& __u); unordered_map(const unordered_map& __u, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_map(unordered_map&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); unordered_map(unordered_map&& __u, const allocator_type& __a); @@ -872,7 +865,7 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_map& operator=(const unordered_map& __u) { -#if __cplusplus >= 201103L +#ifndef _LIBCPP_CXX03_LANG __table_ = __u.__table_; #else if (this != &__u) { @@ -887,10 +880,12 @@ public: return *this; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_map& operator=(unordered_map&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); #endif #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY unordered_map& operator=(initializer_list<value_type> __il); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS @@ -918,189 +913,162 @@ public: _LIBCPP_INLINE_VISIBILITY const_iterator cend() const _NOEXCEPT {return __table_.end();} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> insert(const value_type& __x) + {return __table_.__insert_unique(__x);} - template <class... _Args> - pair<iterator, bool> emplace(_Args&&... __args); + iterator insert(const_iterator __p, const value_type& __x) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" + " referring to this unordered_map"); +#endif + return insert(__x).first; + } - template <class... _Args> + template <class _InputIterator> _LIBCPP_INLINE_VISIBILITY + void insert(_InputIterator __first, _InputIterator __last); + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY + void insert(initializer_list<value_type> __il) + {insert(__il.begin(), __il.end());} +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> insert(value_type&& __x) + {return __table_.__insert_unique(_VSTD::move(__x));} + + iterator insert(const_iterator __p, value_type&& __x) { #if _LIBCPP_DEBUG_LEVEL >= 2 - iterator emplace_hint(const_iterator __p, _Args&&... __args) - { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered_map"); - return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; - } -#else - iterator emplace_hint(const_iterator, _Args&&... __args) - {return emplace(_VSTD::forward<_Args>(__args)...).first;} + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" + " referring to this unordered_map"); #endif -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> insert(const value_type& __x) - {return __table_.__insert_unique(__x);} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + return __table_.__insert_unique(_VSTD::move(__x)).first; + } + template <class _Pp, class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> insert(_Pp&& __x) {return __table_.__insert_unique(_VSTD::forward<_Pp>(__x));} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY -#if _LIBCPP_DEBUG_LEVEL >= 2 - iterator insert(const_iterator __p, const value_type& __x) - { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" - " referring to this unordered_map"); - return insert(__x).first; - } -#else - iterator insert(const_iterator, const value_type& __x) - {return insert(__x).first;} -#endif -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + template <class _Pp, class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> _LIBCPP_INLINE_VISIBILITY -#if _LIBCPP_DEBUG_LEVEL >= 2 iterator insert(const_iterator __p, _Pp&& __x) { +#if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered_map::insert(const_iterator, value_type&&) called with an iterator not" " referring to this unordered_map"); +#endif return insert(_VSTD::forward<_Pp>(__x)).first; } -#else - iterator insert(const_iterator, _Pp&& __x) - {return insert(_VSTD::forward<_Pp>(__x)).first;} -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - template <class _InputIterator> - void insert(_InputIterator __first, _InputIterator __last); -#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + template <class... _Args> _LIBCPP_INLINE_VISIBILITY - void insert(initializer_list<value_type> __il) - {insert(__il.begin(), __il.end());} -#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + pair<iterator, bool> emplace(_Args&&... __args) { + return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...); + } + + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + iterator emplace_hint(const_iterator __p, _Args&&... __args) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered_map"); +#endif + return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; + } + +#endif // _LIBCPP_CXX03_LANG #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); + return __table_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(__k), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } 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); + return __table_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(_VSTD::move(__k)), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } 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)...)); +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" + " referring to this unordered_map"); +#endif + return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first; } 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)...)); +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" + " referring to this unordered_map"); +#endif + return try_emplace(_VSTD::move(__k), _VSTD::forward<_Args>(__args)...).first; } 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); + pair<iterator, bool> __res = __table_.__emplace_unique_key_args(__k, + __k, _VSTD::forward<_Vp>(__v)); + if (!__res.second) { + __res.first->second = _VSTD::forward<_Vp>(__v); } - return _VSTD::make_pair(emplace_hint(__p, __k, _VSTD::forward<_Vp>(__v)), true); + return __res; } - + 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); + pair<iterator, bool> __res = __table_.__emplace_unique_key_args(__k, + _VSTD::move(__k), _VSTD::forward<_Vp>(__v)); + if (!__res.second) { + __res.first->second = _VSTD::forward<_Vp>(__v); } - return _VSTD::make_pair(emplace_hint(__p, _VSTD::forward<key_type>(__k), _VSTD::forward<_Vp>(__v)), true); + return __res; } 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)); + return insert_or_assign(__k, _VSTD::forward<_Vp>(__v)).first; } 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)); + return insert_or_assign(_VSTD::move(__k), _VSTD::forward<_Vp>(__v)).first; } #endif -#endif -#endif _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);} @@ -1140,7 +1108,7 @@ public: {return __table_.__equal_range_unique(__k);} mapped_type& operator[](const key_type& __k); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG mapped_type& operator[](key_type&& __k); #endif @@ -1196,18 +1164,10 @@ public: #endif // _LIBCPP_DEBUG_LEVEL >= 2 private: -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - __node_holder __construct_node(); - template <class _A0> - __node_holder - __construct_node(_A0&& __a0); - __node_holder __construct_node_with_key(key_type&& __k); -#ifndef _LIBCPP_HAS_NO_VARIADICS - template <class _A0, class _A1, class ..._Args> - __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args); -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +#ifdef _LIBCPP_CXX03_LANG __node_holder __construct_node_with_key(const key_type& __k); +#endif }; template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> @@ -1234,7 +1194,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( } template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const allocator_type& __a) : __table_(__a) @@ -1310,7 +1270,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( unordered_map&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) @@ -1333,10 +1293,10 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( if (__a != __u.get_allocator()) { iterator __i = __u.begin(); - while (__u.size() != 0) - __table_.__insert_unique( - _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_) - ); + while (__u.size() != 0) { + __table_.__emplace_unique(_VSTD::move( + __u.__table_.remove((__i++).__i_)->__value_.__nc)); + } } #if _LIBCPP_DEBUG_LEVEL >= 2 else @@ -1389,7 +1349,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_map&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) @@ -1403,7 +1363,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_map&& __u) #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=( initializer_list<value_type> __il) @@ -1414,81 +1374,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=( #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node() -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_)); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _A0> -typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0) -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), - _VSTD::forward<_A0>(__a0)); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(key_type&& __k) -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), _VSTD::move(__k)); - __h.get_deleter().__first_constructed = true; - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); - __h.get_deleter().__second_constructed = true; - return __h; -} - -#ifndef _LIBCPP_HAS_NO_VARIADICS - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _A0, class _A1, class ..._Args> -typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0, - _A1&& __a1, - _Args&&... __args) -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), - _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1), - _VSTD::forward<_Args>(__args)...); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class... _Args> -pair<typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator, bool> -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_Args&&... __args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get()); - if (__r.second) - __h.release(); - return __r; -} - -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - +#ifdef _LIBCPP_CXX03_LANG template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(const key_type& __k) @@ -1501,10 +1387,11 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(const __h.get_deleter().__second_constructed = true; return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 } +#endif template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) @@ -1513,6 +1400,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, __table_.__insert_unique(*__first); } +#ifdef _LIBCPP_CXX03_LANG template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> _Tp& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) @@ -1525,23 +1413,27 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) __h.release(); return __r.first->second; } +#else -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> +_Tp& +unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) +{ + return __table_.__emplace_unique_key_args(__k, + std::piecewise_construct, std::forward_as_tuple(__k), + std::forward_as_tuple()).first->__cc.second; +} template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> _Tp& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](key_type&& __k) { - iterator __i = find(__k); - if (__i != end()) - return __i->second; - __node_holder __h = __construct_node_with_key(_VSTD::move(__k)); - pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get()); - __h.release(); - return __r.first->second; + return __table_.__emplace_unique_key_args(__k, + std::piecewise_construct, std::forward_as_tuple(std::move(__k)), + std::forward_as_tuple()).first->__cc.second; } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // !_LIBCPP_CXX03_MODE template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> _Tp& @@ -1635,17 +1527,21 @@ private: __table __table_; + typedef typename __table::_NodeTypes _NodeTypes; typedef typename __table::__node_traits __node_traits; typedef typename __table::__node_allocator __node_allocator; typedef typename __table::__node __node; typedef __hash_map_node_destructor<__node_allocator> _Dp; typedef unique_ptr<__node, _Dp> __node_holder; typedef allocator_traits<allocator_type> __alloc_traits; + static_assert((is_same<typename __node_traits::size_type, + typename __alloc_traits::size_type>::value), + "Allocator uses different size_type for different types"); public: typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; - typedef typename __alloc_traits::size_type size_type; - typedef typename __alloc_traits::difference_type difference_type; + typedef typename __table::size_type size_type; + typedef typename __table::difference_type difference_type; typedef __hash_map_iterator<typename __table::iterator> iterator; typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator; @@ -1676,10 +1572,12 @@ public: size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); + _LIBCPP_INLINE_VISIBILITY explicit unordered_multimap(const allocator_type& __a); unordered_multimap(const unordered_multimap& __u); unordered_multimap(const unordered_multimap& __u, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_multimap(unordered_multimap&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); unordered_multimap(unordered_multimap&& __u, const allocator_type& __a); @@ -1721,7 +1619,7 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_multimap& operator=(const unordered_multimap& __u) { -#if __cplusplus >= 201103L +#ifndef _LIBCPP_CXX03_LANG __table_ = __u.__table_; #else if (this != &__u) { @@ -1736,10 +1634,12 @@ public: return *this; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_multimap& operator=(unordered_multimap&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); #endif #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY unordered_multimap& operator=(initializer_list<value_type> __il); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS @@ -1767,43 +1667,55 @@ public: _LIBCPP_INLINE_VISIBILITY const_iterator cend() const _NOEXCEPT {return __table_.end();} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS - - template <class... _Args> - iterator emplace(_Args&&... __args); - - template <class... _Args> - iterator emplace_hint(const_iterator __p, _Args&&... __args); -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - template <class _Pp, - class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> - _LIBCPP_INLINE_VISIBILITY - iterator insert(_Pp&& __x) - {return __table_.__insert_multi(_VSTD::forward<_Pp>(__x));} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, const value_type& __x) {return __table_.__insert_multi(__p.__i_, __x);} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - template <class _Pp, - class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, _Pp&& __x) - {return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + template <class _InputIterator> - void insert(_InputIterator __first, _InputIterator __last); + _LIBCPP_INLINE_VISIBILITY + void insert(_InputIterator __first, _InputIterator __last); + #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY void insert(initializer_list<value_type> __il) {insert(__il.begin(), __il.end());} #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + iterator insert(value_type&& __x) {return __table_.__insert_multi(_VSTD::move(__x));} + + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __p, value_type&& __x) + {return __table_.__insert_multi(__p.__i_, _VSTD::move(__x));} + + template <class _Pp, + class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> + _LIBCPP_INLINE_VISIBILITY + iterator insert(_Pp&& __x) + {return __table_.__insert_multi(_VSTD::forward<_Pp>(__x));} + + template <class _Pp, + class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __p, _Pp&& __x) + {return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));} + + template <class... _Args> + iterator emplace(_Args&&... __args) { + return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...); + } + + template <class... _Args> + iterator emplace_hint(const_iterator __p, _Args&&... __args) { + return __table_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...); + } +#endif // _LIBCPP_CXX03_LANG + + _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);} _LIBCPP_INLINE_VISIBILITY @@ -1890,17 +1802,7 @@ public: #endif // _LIBCPP_DEBUG_LEVEL >= 2 -private: -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - __node_holder __construct_node(); - template <class _A0> - __node_holder - __construct_node(_A0&& __a0); -#ifndef _LIBCPP_HAS_NO_VARIADICS - template <class _A0, class _A1, class ..._Args> - __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args); -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + }; template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> @@ -1966,7 +1868,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( } template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const allocator_type& __a) : __table_(__a) @@ -2003,7 +1905,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( unordered_multimap&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) @@ -2029,7 +1931,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( while (__u.size() != 0) { __table_.__insert_multi( - _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_) + _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_.__nc) ); } } @@ -2084,7 +1986,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_multimap&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) @@ -2098,7 +2000,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_multima #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=( initializer_list<value_type> __il) @@ -2109,81 +2011,11 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=( #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node() -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_)); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _A0> -typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0) -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), - _VSTD::forward<_A0>(__a0)); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -#ifndef _LIBCPP_HAS_NO_VARIADICS - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _A0, class _A1, class ..._Args> -typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node( - _A0&& __a0, _A1&& __a1, _Args&&... __args) -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), - _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1), - _VSTD::forward<_Args>(__args)...); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class... _Args> -typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_Args&&... __args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - iterator __r = __table_.__node_insert_multi(__h.get()); - __h.release(); - return __r; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class... _Args> -typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace_hint( - const_iterator __p, _Args&&... __args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - iterator __r = __table_.__node_insert_multi(__p.__i_, __h.get()); - __h.release(); - return __r; -} -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) diff --git a/include/unordered_set b/include/unordered_set index f6ccdc3734f23..fb38b648a86a6 100644 --- a/include/unordered_set +++ b/include/unordered_set @@ -404,10 +404,12 @@ public: size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__first, __last, __n, __hf, key_equal(), __a) {} #endif + _LIBCPP_INLINE_VISIBILITY explicit unordered_set(const allocator_type& __a); unordered_set(const unordered_set& __u); unordered_set(const unordered_set& __u, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_set(unordered_set&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); unordered_set(unordered_set&& __u, const allocator_type& __a); @@ -439,10 +441,12 @@ public: return *this; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_set& operator=(unordered_set&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); #endif #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY unordered_set& operator=(initializer_list<value_type> __il); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS @@ -527,6 +531,7 @@ public: #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _InputIterator> + _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY @@ -678,7 +683,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( } template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const allocator_type& __a) : __table_(__a) @@ -715,7 +720,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( unordered_set&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) @@ -792,7 +797,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_set<_Value, _Hash, _Pred, _Alloc>& unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(unordered_set&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) @@ -806,7 +811,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(unordered_set&& __u) #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_set<_Value, _Hash, _Pred, _Alloc>& unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=( initializer_list<value_type> __il) @@ -819,7 +824,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=( template <class _Value, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void unordered_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) @@ -940,10 +945,12 @@ public: size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {} #endif + _LIBCPP_INLINE_VISIBILITY explicit unordered_multiset(const allocator_type& __a); unordered_multiset(const unordered_multiset& __u); unordered_multiset(const unordered_multiset& __u, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_multiset(unordered_multiset&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); unordered_multiset(unordered_multiset&& __u, const allocator_type& __a); @@ -973,6 +980,7 @@ public: return *this; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_multiset& operator=(unordered_multiset&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); #endif @@ -1029,6 +1037,7 @@ public: {return __table_.__insert_multi(__p, _VSTD::move(__x));} #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _InputIterator> + _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY @@ -1181,7 +1190,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( } template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const allocator_type& __a) : __table_(__a) @@ -1218,7 +1227,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( unordered_multiset&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) @@ -1295,7 +1304,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multiset<_Value, _Hash, _Pred, _Alloc>& unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=( unordered_multiset&& __u) @@ -1323,7 +1332,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=( template <class _Value, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void unordered_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) diff --git a/include/utility b/include/utility index c9f5785b3d4e0..7b978ad309699 100644 --- a/include/utility +++ b/include/utility @@ -82,8 +82,8 @@ struct pair is_nothrow_move_assignable<T2>::value); template <class U, class V> pair& operator=(pair<U, V>&& p); - void swap(pair& p) noexcept(noexcept(swap(first, p.first)) && - noexcept(swap(second, p.second))); + void swap(pair& p) noexcept(is_nothrow_swappable_v<T1> && + is_nothrow_swappable_v<T2>); }; template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14 @@ -169,7 +169,7 @@ template<size_t N> template<class... T> using index_sequence_for = make_index_sequence<sizeof...(T)>; -template<class T, class U=T> +template<class T, class U=T> T exchange(T& obj, U&& new_value); } // std @@ -178,6 +178,7 @@ template<class T, class U=T> #include <__config> #include <__tuple> #include <type_traits> +#include <initializer_list> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -224,10 +225,6 @@ operator>=(const _Tp& __x, const _Tp& __y) // swap_ranges -// forward -template<class _Tp, size_t _Np> -inline _LIBCPP_INLINE_VISIBILITY -void swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value); template <class _ForwardIterator1, class _ForwardIterator2> inline _LIBCPP_INLINE_VISIBILITY @@ -239,9 +236,12 @@ swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardItera return __first2; } +// forward declared in <type_traits> template<class _Tp, size_t _Np> inline _LIBCPP_INLINE_VISIBILITY -void +typename enable_if< + __is_swappable<_Tp>::value +>::type swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) { _VSTD::swap_ranges(__a, __a + _Np, __b); @@ -285,9 +285,6 @@ struct _LIBCPP_TYPE_VIS_ONLY pair _T1 first; _T2 second; - // pair(const pair&) = default; - // pair(pair&&) = default; - #ifndef _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS template <bool _Dummy = true, class = typename enable_if< __dependent_type<is_default_constructible<_T1>, _Dummy>::value && @@ -310,10 +307,7 @@ struct _LIBCPP_TYPE_VIS_ONLY pair ) : first(__p.first), second(__p.second) {} -#if !defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && _LIBCPP_TRIVIAL_PAIR_COPY_CTOR - _LIBCPP_INLINE_VISIBILITY - pair(const pair& __p) = default; -#elif !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) || !_LIBCPP_TRIVIAL_PAIR_COPY_CTOR +#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) _LIBCPP_INLINE_VISIBILITY pair(const pair& __p) _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value && @@ -322,6 +316,21 @@ struct _LIBCPP_TYPE_VIS_ONLY pair second(__p.second) { } + +# ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + pair(pair&& __p) _NOEXCEPT_(is_nothrow_move_constructible<first_type>::value && + is_nothrow_move_constructible<second_type>::value) + : first(_VSTD::forward<first_type>(__p.first)), + second(_VSTD::forward<second_type>(__p.second)) + { + } +# endif +#elif !defined(_LIBCPP_CXX03_LANG) + pair(pair const&) = default; + pair(pair&&) = default; +#else + // Use the implicitly declared copy constructor in C++03 #endif _LIBCPP_INLINE_VISIBILITY @@ -353,19 +362,6 @@ struct _LIBCPP_TYPE_VIS_ONLY pair : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} -#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS - _LIBCPP_INLINE_VISIBILITY - pair(pair&& __p) = default; -#else - _LIBCPP_INLINE_VISIBILITY - pair(pair&& __p) _NOEXCEPT_(is_nothrow_move_constructible<first_type>::value && - is_nothrow_move_constructible<second_type>::value) - : first(_VSTD::forward<first_type>(__p.first)), - second(_VSTD::forward<second_type>(__p.second)) - { - } -#endif - _LIBCPP_INLINE_VISIBILITY pair& operator=(pair&& __p) _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value && @@ -501,7 +497,6 @@ swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY reference_wrapper; template <class _Tp> struct __make_pair_return_impl @@ -742,63 +737,15 @@ template<size_t... _Ip> #if __has_builtin(__make_integer_seq) && !defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) template <class _Tp, _Tp _Ep> -struct __make_integer_sequence -{ - typedef __make_integer_seq<integer_sequence, _Tp, _Ep> type; -}; +using __make_integer_sequence = __make_integer_seq<integer_sequence, _Tp, _Ep>; #else -namespace __detail { - -template<typename _Tp, size_t ..._Extra> struct __repeat; -template<typename _Tp, _Tp ..._Np, size_t ..._Extra> struct __repeat<integer_sequence<_Tp, _Np...>, _Extra...> { - typedef integer_sequence<_Tp, - _Np..., - sizeof...(_Np) + _Np..., - 2 * sizeof...(_Np) + _Np..., - 3 * sizeof...(_Np) + _Np..., - 4 * sizeof...(_Np) + _Np..., - 5 * sizeof...(_Np) + _Np..., - 6 * sizeof...(_Np) + _Np..., - 7 * sizeof...(_Np) + _Np..., - _Extra...> type; -}; - -template<size_t _Np> struct __parity; -template<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {}; - -template<> struct __make<0> { typedef integer_sequence<size_t> type; }; -template<> struct __make<1> { typedef integer_sequence<size_t, 0> type; }; -template<> struct __make<2> { typedef integer_sequence<size_t, 0, 1> type; }; -template<> struct __make<3> { typedef integer_sequence<size_t, 0, 1, 2> type; }; -template<> struct __make<4> { typedef integer_sequence<size_t, 0, 1, 2, 3> type; }; -template<> struct __make<5> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4> type; }; -template<> struct __make<6> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; }; -template<> struct __make<7> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; }; - -template<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; }; -template<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; }; -template<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<5> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<6> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; - -template<typename _Tp, typename _Up> struct __convert { - template<typename> struct __result; - template<_Tp ..._Np> struct __result<integer_sequence<_Tp, _Np...> > { typedef integer_sequence<_Up, _Np...> type; }; -}; -template<typename _Tp> struct __convert<_Tp, _Tp> { template<typename _Up> struct __result { typedef _Up type; }; }; - -} - template<typename _Tp, _Tp _Np> using __make_integer_sequence_unchecked = - typename __detail::__convert<size_t, _Tp>::template __result<typename __detail::__make<_Np>::type>::type; + typename __detail::__make<_Np>::type::template __convert<integer_sequence, _Tp>; template <class _Tp, _Tp _Ep> -struct __make_integer_sequence +struct __make_integer_sequence_checked { static_assert(is_integral<_Tp>::value, "std::make_integer_sequence can only be instantiated with an integral type" ); @@ -808,17 +755,20 @@ struct __make_integer_sequence typedef __make_integer_sequence_unchecked<_Tp, 0 <= _Ep ? _Ep : 0> type; }; +template <class _Tp, _Tp _Ep> +using __make_integer_sequence = typename __make_integer_sequence_checked<_Tp, _Ep>::type; + #endif template<class _Tp, _Tp _Np> - using make_integer_sequence = typename __make_integer_sequence<_Tp, _Np>::type; + using make_integer_sequence = __make_integer_sequence<_Tp, _Np>; template<size_t _Np> using make_index_sequence = make_integer_sequence<size_t, _Np>; template<class... _Tp> using index_sequence_for = make_index_sequence<sizeof...(_Tp)>; - + #endif // _LIBCPP_STD_VER > 11 #if _LIBCPP_STD_VER > 11 @@ -829,7 +779,7 @@ _T1 exchange(_T1& __obj, _T2 && __new_value) _T1 __old_value = _VSTD::move(__obj); __obj = _VSTD::forward<_T2>(__new_value); return __old_value; -} +} #endif // _LIBCPP_STD_VER > 11 _LIBCPP_END_NAMESPACE_STD diff --git a/include/vector b/include/vector index dbc0dd321824b..021bbfb6643e1 100644 --- a/include/vector +++ b/include/vector @@ -262,6 +262,7 @@ void swap(vector<T,Allocator>& x, vector<T,Allocator>& y) */ #include <__config> +#include <iosfwd> // for forward declaration of vector #include <__bit_reference> #include <type_traits> #include <climits> @@ -453,7 +454,7 @@ __vector_base<_Tp, _Allocator>::~__vector_base() } } -template <class _Tp, class _Allocator = allocator<_Tp> > +template <class _Tp, class _Allocator /* = allocator<_Tp> */> class _LIBCPP_TYPE_VIS_ONLY vector : private __vector_base<_Tp, _Allocator> { @@ -1811,9 +1812,9 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) } else { - value_type __tmp(_VSTD::forward<_Args>(__args)...); + __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...); __move_range(__p, this->__end_, __p + 1); - *__p = _VSTD::move(__tmp); + *__p = _VSTD::move(__tmp.get()); } __annotator.__done(); } @@ -2362,6 +2363,7 @@ public: _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value); #endif + static void swap(reference __x, reference __y) _NOEXCEPT { _VSTD::swap(__x, __y); } void resize(size_type __sz, value_type __x = false); void flip() _NOEXCEPT; diff --git a/include/wchar.h b/include/wchar.h index da34f735edf35..c0c6ef754fbeb 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -118,7 +118,7 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len, #include_next <wchar.h> -// Let <cwchar> know if we have const-correct overloads for wcschr and friends. +// Determine whether we have const-correct overloads for wcschr and friends. #if defined(_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_) # define _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS 1 #elif defined(__GLIBC_PREREQ) @@ -127,6 +127,45 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len, # endif #endif +#if defined(__cplusplus) && !defined(_LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS) && defined(_LIBCPP_PREFERRED_OVERLOAD) +extern "C++" { +inline _LIBCPP_INLINE_VISIBILITY +wchar_t* __libcpp_wcschr(const wchar_t* __s, wchar_t __c) {return (wchar_t*)wcschr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const wchar_t* wcschr(const wchar_t* __s, wchar_t __c) {return __libcpp_wcschr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + wchar_t* wcschr( wchar_t* __s, wchar_t __c) {return __libcpp_wcschr(__s, __c);} + +inline _LIBCPP_INLINE_VISIBILITY +wchar_t* __libcpp_wcspbrk(const wchar_t* __s1, const wchar_t* __s2) {return (wchar_t*)wcspbrk(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const wchar_t* wcspbrk(const wchar_t* __s1, const wchar_t* __s2) {return __libcpp_wcspbrk(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + wchar_t* wcspbrk( wchar_t* __s1, const wchar_t* __s2) {return __libcpp_wcspbrk(__s1, __s2);} + +inline _LIBCPP_INLINE_VISIBILITY +wchar_t* __libcpp_wcsrchr(const wchar_t* __s, wchar_t __c) {return (wchar_t*)wcsrchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const wchar_t* wcsrchr(const wchar_t* __s, wchar_t __c) {return __libcpp_wcsrchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + wchar_t* wcsrchr( wchar_t* __s, wchar_t __c) {return __libcpp_wcsrchr(__s, __c);} + +inline _LIBCPP_INLINE_VISIBILITY +wchar_t* __libcpp_wcsstr(const wchar_t* __s1, const wchar_t* __s2) {return (wchar_t*)wcsstr(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const wchar_t* wcsstr(const wchar_t* __s1, const wchar_t* __s2) {return __libcpp_wcsstr(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + wchar_t* wcsstr( wchar_t* __s1, const wchar_t* __s2) {return __libcpp_wcsstr(__s1, __s2);} + +inline _LIBCPP_INLINE_VISIBILITY +wchar_t* __libcpp_wmemchr(const wchar_t* __s, wchar_t __c, size_t __n) {return (wchar_t*)wmemchr(__s, __c, __n);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const wchar_t* wmemchr(const wchar_t* __s, wchar_t __c, size_t __n) {return __libcpp_wmemchr(__s, __c, __n);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + wchar_t* wmemchr( wchar_t* __s, wchar_t __c, size_t __n) {return __libcpp_wmemchr(__s, __c, __n);} +} +#endif + #if defined(__cplusplus) && (defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)) extern "C++" { #include <support/win32/support.h> // pull in *swprintf defines diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index d6a35f8eba2e4..afc388e7613f0 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -79,6 +79,7 @@ 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) +add_library_flags_if(LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB atomic) # Setup flags. add_flags_if_supported(-fPIC) @@ -87,7 +88,21 @@ add_link_flags_if_supported(-nodefaultlibs) if ( APPLE AND (LIBCXX_CXX_ABI_LIBNAME STREQUAL "libcxxabi" OR LIBCXX_CXX_ABI_LIBNAME STREQUAL "none")) if (NOT DEFINED LIBCXX_LIBCPPABI_VERSION) - set(LIBCXX_LIBCPPABI_VERSION "2") + set(LIBCXX_LIBCPPABI_VERSION "2") # Default value + execute_process( + COMMAND xcrun --show-sdk-version + OUTPUT_VARIABLE sdk_ver + RESULT_VARIABLE res + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (res EQUAL 0) + message(STATUS "Found SDK version ${sdk_ver}") + string(REPLACE "10." "" sdk_ver "${sdk_ver}") + if (sdk_ver LESS 9) + set(LIBCXX_LIBCPPABI_VERSION "") + else() + set(LIBCXX_LIBCPPABI_VERSION "2") + endif() + endif() endif() if ( CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.6" ) @@ -137,6 +152,26 @@ set_target_properties(cxx SOVERSION "${LIBCXX_ABI_VERSION}" ) +if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY) + file(GLOB LIBCXX_EXPERIMENTAL_SOURCES ../src/experimental/*.cpp) + if (LIBCXX_ENABLE_FILESYSTEM) + file(GLOB LIBCXX_FILESYSTEM_SOURCES ../src/experimental/filesystem/*.cpp) + endif() + add_library(cxx_experimental STATIC ${LIBCXX_EXPERIMENTAL_SOURCES} ${LIBCXX_FILESYSTEM_SOURCES}) + target_link_libraries(cxx_experimental cxx) + + set(experimental_flags "${LIBCXX_COMPILE_FLAGS}") + check_flag_supported(-std=c++14) + if (NOT MSVC AND LIBCXX_SUPPORTS_STD_EQ_CXX14_FLAG) + string(REPLACE "-std=c++11" "-std=c++14" experimental_flags "${LIBCXX_COMPILE_FLAGS}") + endif() + set_target_properties(cxx_experimental + PROPERTIES + COMPILE_FLAGS "${experimental_flags}" + OUTPUT_NAME "c++experimental" + ) +endif() + # Generate a linker script inplace of a libc++.so symlink. Rerun this command # after cxx builds. if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT) @@ -159,7 +194,10 @@ if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT) endif() if (LIBCXX_INSTALL_LIBRARY) - install(TARGETS cxx + if (LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY) + set(experimental_lib cxx_experimental) + endif() + install(TARGETS cxx ${experimental_lib} LIBRARY DESTINATION lib${LIBCXX_LIBDIR_SUFFIX} COMPONENT libcxx ARCHIVE DESTINATION lib${LIBCXX_LIBDIR_SUFFIX} COMPONENT libcxx ) @@ -177,10 +215,18 @@ endif() if (NOT CMAKE_CONFIGURATION_TYPES AND (LIBCXX_INSTALL_LIBRARY OR LIBCXX_INSTALL_HEADERS)) if(LIBCXX_INSTALL_LIBRARY) - set(deps DEPENDS cxx) + set(lib_install_target cxx) + endif() + if (LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY) + set(experimental_lib_install_target cxx_experimental) + endif() + if(LIBCXX_INSTALL_HEADERS) + set(header_install_target install-libcxx-headers) endif() add_custom_target(install-libcxx - ${deps} + DEPENDS ${lib_install_target} + ${experimental_lib_install_target} + ${header_install_target} COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=libcxx -P "${LIBCXX_BINARY_DIR}/cmake_install.cmake") diff --git a/lib/buildit b/lib/buildit index 7e3bc2ed2a964..6451a9bfad6c0 100755 --- a/lib/buildit +++ b/lib/buildit @@ -41,7 +41,7 @@ then fi EXTRA_FLAGS="-nostdinc++ -std=${CXX_LANG} -fstrict-aliasing -Wall -Wextra -Wshadow -Wconversion \ - -Wpadded -Wstrict-aliasing=2 -Wstrict-overflow=4 " + -Wstrict-aliasing=2 -Wstrict-overflow=4 " case $TRIPLE in *-apple-*) diff --git a/src/algorithm.cpp b/src/algorithm.cpp index e548856ff6e14..e9752b0653e03 100644 --- a/src/algorithm.cpp +++ b/src/algorithm.cpp @@ -48,14 +48,14 @@ template bool __insertion_sort_incomplete<__less<long double>&, long double*>(lo template unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&); #ifndef _LIBCPP_HAS_NO_THREADS -static pthread_mutex_t __rs_mut = PTHREAD_MUTEX_INITIALIZER; +static __libcpp_mutex_t __rs_mut = _LIBCPP_MUTEX_INITIALIZER; #endif unsigned __rs_default::__c_ = 0; __rs_default::__rs_default() { #ifndef _LIBCPP_HAS_NO_THREADS - pthread_mutex_lock(&__rs_mut); + __libcpp_mutex_lock(&__rs_mut); #endif __c_ = 1; } @@ -69,7 +69,7 @@ __rs_default::~__rs_default() { #ifndef _LIBCPP_HAS_NO_THREADS if (--__c_ == 0) - pthread_mutex_unlock(&__rs_mut); + __libcpp_mutex_unlock(&__rs_mut); #else --__c_; #endif diff --git a/src/bind.cpp b/src/bind.cpp index cab0b7c03a912..b318fc16979ec 100644 --- a/src/bind.cpp +++ b/src/bind.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#define _LIBCPP_BUILDING_BIND #include "functional" _LIBCPP_BEGIN_NAMESPACE_STD @@ -14,16 +15,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace placeholders { -__ph<1> _1; -__ph<2> _2; -__ph<3> _3; -__ph<4> _4; -__ph<5> _5; -__ph<6> _6; -__ph<7> _7; -__ph<8> _8; -__ph<9> _9; -__ph<10> _10; +const __ph<1> _1{}; +const __ph<2> _2{}; +const __ph<3> _3{}; +const __ph<4> _4{}; +const __ph<5> _5{}; +const __ph<6> _6{}; +const __ph<7> _7{}; +const __ph<8> _8{}; +const __ph<9> _9{}; +const __ph<10> _10{}; } // placeholders diff --git a/src/condition_variable.cpp b/src/condition_variable.cpp index 5fd5fc891c160..bfb4bf3925f7e 100644 --- a/src/condition_variable.cpp +++ b/src/condition_variable.cpp @@ -20,19 +20,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD condition_variable::~condition_variable() { - pthread_cond_destroy(&__cv_); + __libcpp_condvar_destroy(&__cv_); } void condition_variable::notify_one() _NOEXCEPT { - pthread_cond_signal(&__cv_); + __libcpp_condvar_signal(&__cv_); } void condition_variable::notify_all() _NOEXCEPT { - pthread_cond_broadcast(&__cv_); + __libcpp_condvar_broadcast(&__cv_); } void @@ -41,7 +41,7 @@ condition_variable::wait(unique_lock<mutex>& lk) _NOEXCEPT if (!lk.owns_lock()) __throw_system_error(EPERM, "condition_variable::wait: mutex not locked"); - int ec = pthread_cond_wait(&__cv_, lk.mutex()->native_handle()); + int ec = __libcpp_condvar_wait(&__cv_, lk.mutex()->native_handle()); if (ec) __throw_system_error(ec, "condition_variable wait failed"); } @@ -71,7 +71,7 @@ condition_variable::__do_timed_wait(unique_lock<mutex>& lk, ts.tv_sec = ts_sec_max; ts.tv_nsec = giga::num - 1; } - int ec = pthread_cond_timedwait(&__cv_, lk.mutex()->native_handle(), &ts); + int ec = __libcpp_condvar_timedwait(&__cv_, lk.mutex()->native_handle(), &ts); if (ec != 0 && ec != ETIMEDOUT) __throw_system_error(ec, "condition_variable timed_wait failed"); } diff --git a/src/experimental/filesystem/directory_iterator.cpp b/src/experimental/filesystem/directory_iterator.cpp new file mode 100644 index 0000000000000..fa217ba7a12ce --- /dev/null +++ b/src/experimental/filesystem/directory_iterator.cpp @@ -0,0 +1,256 @@ +#include "experimental/filesystem" +#include <dirent.h> +#include <errno.h> + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM + +namespace { namespace detail { + +inline error_code capture_errno() { + _LIBCPP_ASSERT(errno, "Expected errno to be non-zero"); + return error_code{errno, std::generic_category()}; +} + +template <class ...Args> +inline bool capture_error_or_throw(std::error_code* user_ec, + const char* msg, Args&&... args) +{ + std::error_code my_ec = capture_errno(); + if (user_ec) { + *user_ec = my_ec; + return true; + } + __libcpp_throw(filesystem_error(msg, std::forward<Args>(args)..., my_ec)); + return false; +} + +template <class ...Args> +inline bool set_or_throw(std::error_code& my_ec, + std::error_code* user_ec, + const char* msg, Args&&... args) +{ + if (user_ec) { + *user_ec = my_ec; + return true; + } + __libcpp_throw(filesystem_error(msg, std::forward<Args>(args)..., my_ec)); + return false; +} + +typedef path::string_type string_type; + + +inline string_type posix_readdir(DIR *dir_stream, error_code& ec) { + struct dirent* dir_entry_ptr = nullptr; + errno = 0; // zero errno in order to detect errors + if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) { + ec = capture_errno(); + return {}; + } else { + ec.clear(); + return dir_entry_ptr->d_name; + } +} + +}} // namespace detail + +using detail::set_or_throw; + +class __dir_stream { +public: + __dir_stream() = delete; + __dir_stream& operator=(const __dir_stream&) = delete; + + __dir_stream(__dir_stream&& other) noexcept + : __stream_(other.__stream_), __root_(std::move(other.__root_)), + __entry_(std::move(other.__entry_)) + { + other.__stream_ = nullptr; + } + + + __dir_stream(const path& root, directory_options opts, error_code& ec) + : __stream_(nullptr), + __root_(root) + { + if ((__stream_ = ::opendir(root.c_str())) == nullptr) { + ec = detail::capture_errno(); + const bool allow_eacess = + bool(opts & directory_options::skip_permission_denied); + if (allow_eacess && ec.value() == EACCES) + ec.clear(); + return; + } + advance(ec); + } + + ~__dir_stream() noexcept + { if (__stream_) close(); } + + bool good() const noexcept { return __stream_ != nullptr; } + + bool advance(error_code &ec) { + while (true) { + auto str = detail::posix_readdir(__stream_, ec); + if (str == "." || str == "..") { + continue; + } else if (ec || str.empty()) { + close(); + return false; + } else { + __entry_.assign(__root_ / str); + return true; + } + } + } +private: + std::error_code close() noexcept { + std::error_code m_ec; + if (::closedir(__stream_) == -1) + m_ec = detail::capture_errno(); + __stream_ = nullptr; + return m_ec; + } + + DIR * __stream_{nullptr}; +public: + path __root_; + directory_entry __entry_; +}; + +// directory_iterator + +directory_iterator::directory_iterator(const path& p, error_code *ec, + directory_options opts) +{ + std::error_code m_ec; + __imp_ = make_shared<__dir_stream>(p, opts, m_ec); + if (ec) *ec = m_ec; + if (!__imp_->good()) { + __imp_.reset(); + if (m_ec) + set_or_throw(m_ec, ec, + "directory_iterator::directory_iterator(...)", p); + } +} + +directory_iterator& directory_iterator::__increment(error_code *ec) +{ + _LIBCPP_ASSERT(__imp_, "Attempting to increment an invalid iterator"); + std::error_code m_ec; + if (!__imp_->advance(m_ec)) { + __imp_.reset(); + if (m_ec) + set_or_throw(m_ec, ec, "directory_iterator::operator++()"); + } else { + if (ec) ec->clear(); + } + return *this; + +} + +directory_entry const& directory_iterator::__deref() const { + _LIBCPP_ASSERT(__imp_, "Attempting to dereference an invalid iterator"); + return __imp_->__entry_; +} + +// recursive_directory_iterator + +struct recursive_directory_iterator::__shared_imp { + stack<__dir_stream> __stack_; + directory_options __options_; +}; + +recursive_directory_iterator::recursive_directory_iterator(const path& p, + directory_options opt, error_code *ec) + : __imp_(nullptr), __rec_(true) +{ + if (ec) ec->clear(); + std::error_code m_ec; + __dir_stream new_s(p, opt, m_ec); + if (m_ec) set_or_throw(m_ec, ec, "recursive_directory_iterator", p); + if (m_ec || !new_s.good()) return; + + __imp_ = _VSTD::make_shared<__shared_imp>(); + __imp_->__options_ = opt; + __imp_->__stack_.push(_VSTD::move(new_s)); +} + +void recursive_directory_iterator::__pop(error_code* ec) +{ + _LIBCPP_ASSERT(__imp_, "Popping the end iterator"); + if (ec) ec->clear(); + __imp_->__stack_.pop(); + if (__imp_->__stack_.size() == 0) + __imp_.reset(); + else + __advance(ec); +} + +directory_options recursive_directory_iterator::options() const { + return __imp_->__options_; +} + +int recursive_directory_iterator::depth() const { + return __imp_->__stack_.size() - 1; +} + +const directory_entry& recursive_directory_iterator::__deref() const { + return __imp_->__stack_.top().__entry_; +} + +recursive_directory_iterator& +recursive_directory_iterator::__increment(error_code *ec) +{ + if (ec) ec->clear(); + if (recursion_pending()) { + if (__try_recursion(ec) || (ec && *ec)) + return *this; + } + __rec_ = true; + __advance(ec); + return *this; +} + +void recursive_directory_iterator::__advance(error_code* ec) { + // REQUIRES: ec must be cleared before calling this function. + const directory_iterator end_it; + auto& stack = __imp_->__stack_; + std::error_code m_ec; + while (stack.size() > 0) { + if (stack.top().advance(m_ec)) + return; + if (m_ec) break; + stack.pop(); + } + __imp_.reset(); + if (m_ec) + set_or_throw(m_ec, ec, "recursive_directory_iterator::operator++()"); +} + +bool recursive_directory_iterator::__try_recursion(error_code *ec) { + + bool rec_sym = + bool(options() & directory_options::follow_directory_symlink); + auto& curr_it = __imp_->__stack_.top(); + + if (is_directory(curr_it.__entry_.status()) && + (!is_symlink(curr_it.__entry_.symlink_status()) || rec_sym)) + { + std::error_code m_ec; + __dir_stream new_it(curr_it.__entry_.path(), __imp_->__options_, m_ec); + if (new_it.good()) { + __imp_->__stack_.push(_VSTD::move(new_it)); + return true; + } + if (m_ec) { + __imp_.reset(); + set_or_throw(m_ec, ec, + "recursive_directory_iterator::operator++()"); + } + } + return false; +} + + +_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM diff --git a/src/experimental/filesystem/operations.cpp b/src/experimental/filesystem/operations.cpp new file mode 100644 index 0000000000000..369996fcbe62d --- /dev/null +++ b/src/experimental/filesystem/operations.cpp @@ -0,0 +1,794 @@ +//===--------------------- filesystem/ops.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/filesystem" +#include "iterator" +#include "fstream" +#include "type_traits" +#include "random" /* for unique_path */ +#include "cstdlib" +#include "climits" + +#include <unistd.h> +#include <sys/stat.h> +#include <sys/statvfs.h> +#include <fcntl.h> /* values for fchmodat */ +#if !defined(UTIME_OMIT) +#include <sys/time.h> // for ::utimes as used in __last_write_time +#endif + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM + +filesystem_error::~filesystem_error() {} + + +// POSIX HELPERS + +namespace detail { namespace { + +using value_type = path::value_type; +using string_type = path::string_type; + + + +inline std::error_code capture_errno() { + _LIBCPP_ASSERT(errno, "Expected errno to be non-zero"); + std::error_code m_ec(errno, std::generic_category()); + return m_ec; +} + +void set_or_throw(std::error_code const& m_ec, std::error_code* ec, + const char* msg, path const& p = {}, path const& p2 = {}) +{ + if (ec) { + *ec = m_ec; + } else { + string msg_s("std::experimental::filesystem::"); + msg_s += msg; + __libcpp_throw(filesystem_error(msg_s, p, p2, m_ec)); + } +} + +void set_or_throw(std::error_code* ec, const char* msg, + path const& p = {}, path const& p2 = {}) +{ + return set_or_throw(capture_errno(), ec, msg, p, p2); +} + +perms posix_get_perms(const struct ::stat & st) noexcept { + return static_cast<perms>(st.st_mode) & perms::mask; +} + +::mode_t posix_convert_perms(perms prms) { + return static_cast< ::mode_t>(prms & perms::mask); +} + +file_status create_file_status(std::error_code& m_ec, path const& p, + struct ::stat& path_stat, + std::error_code* ec) +{ + if (ec) *ec = m_ec; + if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) { + return file_status(file_type::not_found); + } + else if (m_ec) { + set_or_throw(m_ec, ec, "posix_stat", p); + return file_status(file_type::none); + } + // else + + file_status fs_tmp; + auto const mode = path_stat.st_mode; + if (S_ISLNK(mode)) fs_tmp.type(file_type::symlink); + else if (S_ISREG(mode)) fs_tmp.type(file_type::regular); + else if (S_ISDIR(mode)) fs_tmp.type(file_type::directory); + else if (S_ISBLK(mode)) fs_tmp.type(file_type::block); + else if (S_ISCHR(mode)) fs_tmp.type(file_type::character); + else if (S_ISFIFO(mode)) fs_tmp.type(file_type::fifo); + else if (S_ISSOCK(mode)) fs_tmp.type(file_type::socket); + else fs_tmp.type(file_type::unknown); + + fs_tmp.permissions(detail::posix_get_perms(path_stat)); + return fs_tmp; +} + +file_status posix_stat(path const & p, struct ::stat& path_stat, + std::error_code* ec) +{ + std::error_code m_ec; + if (::stat(p.c_str(), &path_stat) == -1) + m_ec = detail::capture_errno(); + return create_file_status(m_ec, p, path_stat, ec); +} + +file_status posix_stat(path const & p, std::error_code* ec) { + struct ::stat path_stat; + return posix_stat(p, path_stat, ec); +} + +file_status posix_lstat(path const & p, struct ::stat & path_stat, + std::error_code* ec) +{ + std::error_code m_ec; + if (::lstat(p.c_str(), &path_stat) == -1) + m_ec = detail::capture_errno(); + return create_file_status(m_ec, p, path_stat, ec); +} + +file_status posix_lstat(path const & p, std::error_code* ec) { + struct ::stat path_stat; + return posix_lstat(p, path_stat, ec); +} + +bool stat_equivalent(struct ::stat& st1, struct ::stat& st2) { + return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino); +} + +// DETAIL::MISC + + +bool copy_file_impl(const path& from, const path& to, perms from_perms, + std::error_code *ec) +{ + std::ifstream in(from.c_str(), std::ios::binary); + std::ofstream out(to.c_str(), std::ios::binary); + + if (in.good() && out.good()) { + using InIt = std::istreambuf_iterator<char>; + using OutIt = std::ostreambuf_iterator<char>; + InIt bin(in); + InIt ein; + OutIt bout(out); + std::copy(bin, ein, bout); + } + if (out.fail() || in.fail()) { + set_or_throw(make_error_code(errc::operation_not_permitted), + ec, "copy_file", from, to); + return false; + } + __permissions(to, from_perms, ec); + // TODO what if permissions fails? + return true; +} + +}} // end namespace detail + +using detail::set_or_throw; + +path __canonical(path const & orig_p, const path& base, std::error_code *ec) +{ + path p = absolute(orig_p, base); + char buff[PATH_MAX + 1]; + char *ret; + if ((ret = ::realpath(p.c_str(), buff)) == nullptr) { + set_or_throw(ec, "canonical", orig_p, base); + return {}; + } + if (ec) ec->clear(); + return {ret}; +} + +void __copy(const path& from, const path& to, copy_options options, + std::error_code *ec) +{ + const bool sym_status = bool(options & + (copy_options::create_symlinks | copy_options::skip_symlinks)); + + const bool sym_status2 = bool(options & + copy_options::copy_symlinks); + + std::error_code m_ec; + struct ::stat f_st = {}; + const file_status f = sym_status || sym_status2 + ? detail::posix_lstat(from, f_st, &m_ec) + : detail::posix_stat(from, f_st, &m_ec); + if (m_ec) + return set_or_throw(m_ec, ec, "copy", from, to); + + struct ::stat t_st = {}; + const file_status t = sym_status ? detail::posix_lstat(to, t_st, &m_ec) + : detail::posix_stat(to, t_st, &m_ec); + + if (not status_known(t)) + return set_or_throw(m_ec, ec, "copy", from, to); + + if (!exists(f) || is_other(f) || is_other(t) + || (is_directory(f) && is_regular_file(t)) + || detail::stat_equivalent(f_st, t_st)) + { + return set_or_throw(make_error_code(errc::function_not_supported), + ec, "copy", from, to); + } + + if (ec) ec->clear(); + + if (is_symlink(f)) { + if (bool(copy_options::skip_symlinks & options)) { + // do nothing + } else if (not exists(t)) { + __copy_symlink(from, to, ec); + } else { + set_or_throw(make_error_code(errc::file_exists), + ec, "copy", from, to); + } + return; + } + else if (is_regular_file(f)) { + if (bool(copy_options::directories_only & options)) { + // do nothing + } + else if (bool(copy_options::create_symlinks & options)) { + __create_symlink(from, to, ec); + } + else if (bool(copy_options::create_hard_links & options)) { + __create_hard_link(from, to, ec); + } + else if (is_directory(t)) { + __copy_file(from, to / from.filename(), options, ec); + } else { + __copy_file(from, to, options, ec); + } + return; + } + else if (is_directory(f)) { + if (not bool(copy_options::recursive & options) && + bool(copy_options::__in_recursive_copy & options)) + { + return; + } + + if (!exists(t)) { + // create directory to with attributes from 'from'. + __create_directory(to, from, ec); + if (ec && *ec) { return; } + } + directory_iterator it = ec ? directory_iterator(from, *ec) + : directory_iterator(from); + if (ec && *ec) { return; } + std::error_code m_ec; + for (; it != directory_iterator(); it.increment(m_ec)) { + if (m_ec) return set_or_throw(m_ec, ec, "copy", from, to); + __copy(it->path(), to / it->path().filename(), + options | copy_options::__in_recursive_copy, ec); + if (ec && *ec) { return; } + } + } +} + + +bool __copy_file(const path& from, const path& to, copy_options options, + std::error_code *ec) +{ + if (ec) ec->clear(); + + std::error_code m_ec; + auto from_st = detail::posix_stat(from, &m_ec); + if (not is_regular_file(from_st)) { + if (not m_ec) + m_ec = make_error_code(errc::not_supported); + set_or_throw(m_ec, ec, "copy_file", from, to); + return false; + } + + auto to_st = detail::posix_stat(to, &m_ec); + if (!status_known(to_st)) { + set_or_throw(m_ec, ec, "copy_file", from, to); + return false; + } + + const bool to_exists = exists(to_st); + if (to_exists && bool(copy_options::skip_existing & options)) { + return false; + } + else if (to_exists && bool(copy_options::update_existing & options)) { + auto from_time = __last_write_time(from, ec); + if (ec && *ec) { return false; } + auto to_time = __last_write_time(to, ec); + if (ec && *ec) { return false; } + if (from_time <= to_time) { + return false; + } + return detail::copy_file_impl(from, to, from_st.permissions(), ec); + } + else if (!to_exists || bool(copy_options::overwrite_existing & options)) { + return detail::copy_file_impl(from, to, from_st.permissions(), ec); + } + else { + set_or_throw(make_error_code(errc::file_exists), ec, "copy", from, to); + return false; + } +} + +void __copy_symlink(const path& existing_symlink, const path& new_symlink, + std::error_code *ec) +{ + const path real_path(__read_symlink(existing_symlink, ec)); + if (ec && *ec) { return; } + // NOTE: proposal says you should detect if you should call + // create_symlink or create_directory_symlink. I don't think this + // is needed with POSIX + __create_symlink(real_path, new_symlink, ec); +} + + +bool __create_directories(const path& p, std::error_code *ec) +{ + std::error_code m_ec; + auto const st = detail::posix_stat(p, &m_ec); + if (!status_known(st)) { + set_or_throw(m_ec, ec, "create_directories", p); + return false; + } + else if (is_directory(st)) { + if (ec) ec->clear(); + return false; + } + else if (exists(st)) { + set_or_throw(make_error_code(errc::file_exists), + ec, "create_directories", p); + return false; + } + + const path parent = p.parent_path(); + if (!parent.empty()) { + const file_status parent_st = status(parent, m_ec); + if (not status_known(parent_st)) { + set_or_throw(m_ec, ec, "create_directories", p); + return false; + } + if (not exists(parent_st)) { + __create_directories(parent, ec); + if (ec && *ec) { return false; } + } + } + return __create_directory(p, ec); +} + +bool __create_directory(const path& p, std::error_code *ec) +{ + if (ec) ec->clear(); + if (::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0) + return true; + if (errno != EEXIST || !is_directory(p)) + set_or_throw(ec, "create_directory", p); + return false; +} + +bool __create_directory(path const & p, path const & attributes, + std::error_code *ec) +{ + struct ::stat attr_stat; + std::error_code mec; + auto st = detail::posix_stat(attributes, attr_stat, &mec); + if (!status_known(st)) { + set_or_throw(mec, ec, "create_directory", p, attributes); + return false; + } + if (ec) ec->clear(); + if (::mkdir(p.c_str(), attr_stat.st_mode) == 0) + return true; + if (errno != EEXIST || !is_directory(p)) + set_or_throw(ec, "create_directory", p, attributes); + return false; +} + +void __create_directory_symlink(path const & from, path const & to, + std::error_code *ec){ + if (::symlink(from.c_str(), to.c_str()) != 0) + set_or_throw(ec, "create_directory_symlink", from, to); + else if (ec) + ec->clear(); +} + +void __create_hard_link(const path& from, const path& to, std::error_code *ec){ + if (::link(from.c_str(), to.c_str()) == -1) + set_or_throw(ec, "create_hard_link", from, to); + else if (ec) + ec->clear(); +} + +void __create_symlink(path const & from, path const & to, std::error_code *ec) { + + if (::symlink(from.c_str(), to.c_str()) == -1) + set_or_throw(ec, "create_symlink", from, to); + else if (ec) + ec->clear(); +} + +path __current_path(std::error_code *ec) { + auto size = ::pathconf(".", _PC_PATH_MAX); + _LIBCPP_ASSERT(size >= 0, "pathconf returned a 0 as max size"); + + auto buff = std::unique_ptr<char[]>(new char[size + 1]); + char* ret; + if ((ret = ::getcwd(buff.get(), static_cast<size_t>(size))) == nullptr) { + set_or_throw(ec, "current_path"); + return {}; + } + if (ec) ec->clear(); + return {buff.get()}; +} + +void __current_path(const path& p, std::error_code *ec) { + if (::chdir(p.c_str()) == -1) + set_or_throw(ec, "current_path", p); + else if (ec) + ec->clear(); +} + +bool __equivalent(const path& p1, const path& p2, std::error_code *ec) +{ + std::error_code ec1, ec2; + struct ::stat st1 = {}; + struct ::stat st2 = {}; + auto s1 = detail::posix_stat(p1.native(), st1, &ec1); + auto s2 = detail::posix_stat(p2.native(), st2, &ec2); + + if ((!exists(s1) && !exists(s2)) || (is_other(s1) && is_other(s2))) { + set_or_throw(make_error_code(errc::not_supported), ec, + "equivalent", p1, p2); + return false; + } + if (ec) ec->clear(); + return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino); +} + + +std::uintmax_t __file_size(const path& p, std::error_code *ec) +{ + std::error_code m_ec; + struct ::stat st; + file_status fst = detail::posix_stat(p, st, &m_ec); + if (!exists(fst) || !is_regular_file(fst)) { + if (!m_ec) + m_ec = make_error_code(errc::not_supported); + set_or_throw(m_ec, ec, "file_size", p); + return static_cast<uintmax_t>(-1); + } + // is_regular_file(p) == true + if (ec) ec->clear(); + return static_cast<std::uintmax_t>(st.st_size); +} + +std::uintmax_t __hard_link_count(const path& p, std::error_code *ec) +{ + std::error_code m_ec; + struct ::stat st; + detail::posix_stat(p, st, &m_ec); + if (m_ec) { + set_or_throw(m_ec, ec, "hard_link_count", p); + return static_cast<std::uintmax_t>(-1); + } + if (ec) ec->clear(); + return static_cast<std::uintmax_t>(st.st_nlink); +} + + +bool __fs_is_empty(const path& p, std::error_code *ec) +{ + if (ec) ec->clear(); + std::error_code m_ec; + struct ::stat pst; + auto st = detail::posix_stat(p, pst, &m_ec); + if (is_directory(st)) + return directory_iterator(p) == directory_iterator{}; + else if (is_regular_file(st)) + return static_cast<std::uintmax_t>(pst.st_size) == 0; + // else + set_or_throw(m_ec, ec, "is_empty", p); + return false; +} + + +namespace detail { namespace { + +template <class CType, class ChronoType> +bool checked_set(CType* out, ChronoType time) { + using Lim = numeric_limits<CType>; + if (time > Lim::max() || time < Lim::min()) + return false; + *out = static_cast<CType>(time); + return true; +} + +constexpr long long min_seconds = file_time_type::duration::min().count() + / file_time_type::period::den; + +template <class SubSecDurT, class SubSecT> +bool set_times_checked(time_t* sec_out, SubSecT* subsec_out, file_time_type tp) { + using namespace chrono; + auto dur = tp.time_since_epoch(); + auto sec_dur = duration_cast<seconds>(dur); + auto subsec_dur = duration_cast<SubSecDurT>(dur - sec_dur); + // The tv_nsec and tv_usec fields must not be negative so adjust accordingly + if (subsec_dur.count() < 0) { + if (sec_dur.count() > min_seconds) { + + sec_dur -= seconds(1); + subsec_dur += seconds(1); + } else { + subsec_dur = SubSecDurT::zero(); + } + } + return checked_set(sec_out, sec_dur.count()) + && checked_set(subsec_out, subsec_dur.count()); +} + +}} // end namespace detail + + +file_time_type __last_write_time(const path& p, std::error_code *ec) +{ + std::error_code m_ec; + struct ::stat st; + detail::posix_stat(p, st, &m_ec); + if (m_ec) { + set_or_throw(m_ec, ec, "last_write_time", p); + return file_time_type::min(); + } + if (ec) ec->clear(); + return file_time_type::clock::from_time_t(st.st_mtime); +} + +void __last_write_time(const path& p, file_time_type new_time, + std::error_code *ec) +{ + using namespace std::chrono; + std::error_code m_ec; + + // We can use the presence of UTIME_OMIT to detect platforms that do not + // provide utimensat. +#if !defined(UTIME_OMIT) + // This implementation has a race condition between determining the + // last access time and attempting to set it to the same value using + // ::utimes + struct ::stat st; + file_status fst = detail::posix_stat(p, st, &m_ec); + if (m_ec && !status_known(fst)) { + set_or_throw(m_ec, ec, "last_write_time", p); + return; + } + struct ::timeval tbuf[2]; + tbuf[0].tv_sec = st.st_atime; + tbuf[0].tv_usec = 0; + const bool overflowed = !detail::set_times_checked<microseconds>( + &tbuf[1].tv_sec, &tbuf[1].tv_usec, new_time); + + if (overflowed) { + set_or_throw(make_error_code(errc::invalid_argument), ec, + "last_write_time", p); + return; + } + if (::utimes(p.c_str(), tbuf) == -1) { + m_ec = detail::capture_errno(); + } +#else + struct ::timespec tbuf[2]; + tbuf[0].tv_sec = 0; + tbuf[0].tv_nsec = UTIME_OMIT; + + const bool overflowed = !detail::set_times_checked<nanoseconds>( + &tbuf[1].tv_sec, &tbuf[1].tv_nsec, new_time); + if (overflowed) { + set_or_throw(make_error_code(errc::invalid_argument), + ec, "last_write_time", p); + return; + } + if (::utimensat(AT_FDCWD, p.c_str(), tbuf, 0) == -1) { + m_ec = detail::capture_errno(); + } +#endif + if (m_ec) + set_or_throw(m_ec, ec, "last_write_time", p); + else if (ec) + ec->clear(); +} + + +void __permissions(const path& p, perms prms, std::error_code *ec) +{ + + const bool resolve_symlinks = !bool(perms::symlink_nofollow & prms); + const bool add_perms = bool(perms::add_perms & prms); + const bool remove_perms = bool(perms::remove_perms & prms); + _LIBCPP_ASSERT(!(add_perms && remove_perms), + "Both add_perms and remove_perms are set"); + + bool set_sym_perms = false; + prms &= perms::mask; + if (!resolve_symlinks || (add_perms || remove_perms)) { + std::error_code m_ec; + file_status st = resolve_symlinks ? detail::posix_stat(p, &m_ec) + : detail::posix_lstat(p, &m_ec); + set_sym_perms = is_symlink(st); + if (m_ec) return set_or_throw(m_ec, ec, "permissions", p); + _LIBCPP_ASSERT(st.permissions() != perms::unknown, + "Permissions unexpectedly unknown"); + if (add_perms) + prms |= st.permissions(); + else if (remove_perms) + prms = st.permissions() & ~prms; + } + const auto real_perms = detail::posix_convert_perms(prms); + +# if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD) + const int flags = set_sym_perms ? AT_SYMLINK_NOFOLLOW : 0; + if (::fchmodat(AT_FDCWD, p.c_str(), real_perms, flags) == -1) { + return set_or_throw(ec, "permissions", p); + } +# else + if (set_sym_perms) + return set_or_throw(make_error_code(errc::operation_not_supported), + ec, "permissions", p); + if (::chmod(p.c_str(), real_perms) == -1) { + return set_or_throw(ec, "permissions", p); + } +# endif + if (ec) ec->clear(); +} + + +path __read_symlink(const path& p, std::error_code *ec) { + char buff[PATH_MAX + 1]; + std::error_code m_ec; + ::ssize_t ret; + if ((ret = ::readlink(p.c_str(), buff, PATH_MAX)) == -1) { + set_or_throw(ec, "read_symlink", p); + return {}; + } + _LIBCPP_ASSERT(ret <= PATH_MAX, "TODO"); + _LIBCPP_ASSERT(ret > 0, "TODO"); + if (ec) ec->clear(); + buff[ret] = 0; + return {buff}; +} + + +bool __remove(const path& p, std::error_code *ec) { + if (ec) ec->clear(); + if (::remove(p.c_str()) == -1) { + set_or_throw(ec, "remove", p); + return false; + } + return true; +} + +namespace { + +std::uintmax_t remove_all_impl(path const & p, std::error_code& ec) +{ + const auto npos = static_cast<std::uintmax_t>(-1); + const file_status st = __symlink_status(p, &ec); + if (ec) return npos; + std::uintmax_t count = 1; + if (is_directory(st)) { + for (directory_iterator it(p, ec); !ec && it != directory_iterator(); + it.increment(ec)) { + auto other_count = remove_all_impl(it->path(), ec); + if (ec) return npos; + count += other_count; + } + if (ec) return npos; + } + if (!__remove(p, &ec)) return npos; + return count; +} + +} // end namespace + +std::uintmax_t __remove_all(const path& p, std::error_code *ec) { + std::error_code mec; + auto count = remove_all_impl(p, mec); + if (mec) { + set_or_throw(mec, ec, "remove_all", p); + return static_cast<std::uintmax_t>(-1); + } + if (ec) ec->clear(); + return count; +} + +void __rename(const path& from, const path& to, std::error_code *ec) { + if (::rename(from.c_str(), to.c_str()) == -1) + set_or_throw(ec, "rename", from, to); + else if (ec) + ec->clear(); +} + +void __resize_file(const path& p, std::uintmax_t size, std::error_code *ec) { + if (::truncate(p.c_str(), static_cast<long>(size)) == -1) + set_or_throw(ec, "resize_file", p); + else if (ec) + ec->clear(); +} + +space_info __space(const path& p, std::error_code *ec) { + space_info si; + struct statvfs m_svfs = {}; + if (::statvfs(p.c_str(), &m_svfs) == -1) { + set_or_throw(ec, "space", p); + si.capacity = si.free = si.available = + static_cast<std::uintmax_t>(-1); + return si; + } + if (ec) ec->clear(); + // Multiply with overflow checking. + auto do_mult = [&](std::uintmax_t& out, std::uintmax_t other) { + out = other * m_svfs.f_frsize; + if (out / other != m_svfs.f_frsize || other == 0) + out = static_cast<std::uintmax_t>(-1); + }; + do_mult(si.capacity, m_svfs.f_blocks); + do_mult(si.free, m_svfs.f_bfree); + do_mult(si.available, m_svfs.f_bavail); + return si; +} + +file_status __status(const path& p, std::error_code *ec) { + return detail::posix_stat(p, ec); +} + +file_status __symlink_status(const path& p, std::error_code *ec) { + return detail::posix_lstat(p, ec); +} + +path __system_complete(const path& p, std::error_code *ec) { + if (ec) ec->clear(); + return absolute(p, current_path()); +} + +path __temp_directory_path(std::error_code *ec) { + const char* env_paths[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"}; + const char* ret = nullptr; + for (auto & ep : env_paths) { + if ((ret = std::getenv(ep))) + break; + } + path p(ret ? ret : "/tmp"); + std::error_code m_ec; + if (is_directory(p, m_ec)) { + if (ec) ec->clear(); + return p; + } + if (!m_ec || m_ec == make_error_code(errc::no_such_file_or_directory)) + m_ec = make_error_code(errc::not_a_directory); + set_or_throw(m_ec, ec, "temp_directory_path"); + return {}; +} + +// An absolute path is composed according to the table in [fs.op.absolute]. +path absolute(const path& p, const path& base) { + auto root_name = p.root_name(); + auto root_dir = p.root_directory(); + + if (!root_name.empty() && !root_dir.empty()) + return p; + + auto abs_base = base.is_absolute() ? base : absolute(base); + + /* !has_root_name && !has_root_dir */ + if (root_name.empty() && root_dir.empty()) + { + return abs_base / p; + } + else if (!root_name.empty()) /* has_root_name && !has_root_dir */ + { + return root_name / abs_base.root_directory() + / + abs_base.relative_path() / p.relative_path(); + } + else /* !has_root_name && has_root_dir */ + { + if (abs_base.has_root_name()) + return abs_base.root_name() / p; + // else p is absolute, return outside of block + } + return p; +} + +_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM diff --git a/src/experimental/filesystem/path.cpp b/src/experimental/filesystem/path.cpp new file mode 100644 index 0000000000000..38c449832f6ec --- /dev/null +++ b/src/experimental/filesystem/path.cpp @@ -0,0 +1,391 @@ +//===--------------------- filesystem/path.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/filesystem" +#include "experimental/string_view" +#include "utility" + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM + +_LIBCPP_CONSTEXPR path::value_type path::preferred_separator; + +namespace { namespace parser +{ + +using string_type = string_view; +using value_type = path::value_type; + +using string_view_pair = pair<string_view, string_view>; + +// status reporting +constexpr size_t npos = static_cast<size_t>(-1); + +inline bool good(size_t pos) { return pos != npos; } + +// lexical elements +constexpr value_type preferred_separator = path::preferred_separator; +constexpr value_type const * preferred_separator_str = "/"; +constexpr value_type const * dot = "."; + +// forward // +bool is_separator(string_type const &, size_t); +bool is_root_name(const string_type&, size_t); +bool is_root_directory(string_type const &, size_t); +bool is_trailing_separator(string_type const &, size_t); + +size_t start_of(string_type const &, size_t); +size_t end_of(string_type const &, size_t); + +size_t root_name_start(const string_type& s); +size_t root_name_end(const string_type&); + +size_t root_directory_start(string_type const &); +size_t root_directory_end(string_type const &); + +string_view_pair separate_filename(string_type const &); +string_view extract_raw(string_type const &, size_t); +string_view extract_preferred(string_type const &, size_t); + +inline bool is_separator(const string_type& s, size_t pos) { + return (pos < s.size() && s[pos] == preferred_separator); +} + +inline bool is_root_name(const string_type& s, size_t pos) { + return good(pos) && pos == 0 ? root_name_start(s) == pos : false; +} + +inline bool is_root_directory(const string_type& s, size_t pos) { + return good(pos) ? root_directory_start(s) == pos : false; +} + +inline bool is_trailing_separator(const string_type& s, size_t pos) { + return (pos < s.size() && is_separator(s, pos) && + end_of(s, pos) == s.size()-1 && + !is_root_directory(s, pos) && !is_root_name(s, pos)); +} + +size_t start_of(const string_type& s, size_t pos) { + if (pos >= s.size()) return npos; + bool in_sep = (s[pos] == preferred_separator); + while (pos - 1 < s.size() && + (s[pos-1] == preferred_separator) == in_sep) + { --pos; } + if (pos == 2 && !in_sep && s[0] == preferred_separator && + s[1] == preferred_separator) + { return 0; } + return pos; +} + +size_t end_of(const string_type& s, size_t pos) { + if (pos >= s.size()) return npos; + // special case for root name + if (pos == 0 && is_root_name(s, pos)) return root_name_end(s); + bool in_sep = (s[pos] == preferred_separator); + while (pos + 1 < s.size() && (s[pos+1] == preferred_separator) == in_sep) + { ++pos; } + return pos; +} + +inline size_t root_name_start(const string_type& s) { + return good(root_name_end(s)) ? 0 : npos; +} + +size_t root_name_end(const string_type& s) { + if (s.size() < 2 || s[0] != preferred_separator + || s[1] != preferred_separator) { + return npos; + } + if (s.size() == 2) { + return 1; + } + size_t index = 2; // current position + if (s[index] == preferred_separator) { + return npos; + } + while (index + 1 < s.size() && s[index+1] != preferred_separator) { + ++index; + } + return index; +} + +size_t root_directory_start(const string_type& s) { + size_t e = root_name_end(s); + if (!good(e)) + return is_separator(s, 0) ? 0 : npos; + return is_separator(s, e + 1) ? e + 1 : npos; +} + +size_t root_directory_end(const string_type& s) { + size_t st = root_directory_start(s); + if (!good(st)) return npos; + size_t index = st; + while (index + 1 < s.size() && s[index + 1] == preferred_separator) + { ++index; } + return index; +} + +string_view_pair separate_filename(string_type const & s) { + if (s == "." || s == ".." || s.empty()) return string_view_pair{s, ""}; + auto pos = s.find_last_of('.'); + if (pos == string_type::npos) return string_view_pair{s, string_view{}}; + return string_view_pair{s.substr(0, pos), s.substr(pos)}; +} + +inline string_view extract_raw(const string_type& s, size_t pos) { + size_t end_i = end_of(s, pos); + if (!good(end_i)) return string_view{}; + return string_view(s).substr(pos, end_i - pos + 1); +} + +string_view extract_preferred(const string_type& s, size_t pos) { + string_view raw = extract_raw(s, pos); + if (raw.empty()) + return raw; + if (is_trailing_separator(s, pos)) + return string_view{dot}; + if (is_separator(s, pos) && !is_root_name(s, pos)) + return string_view(preferred_separator_str); + return raw; +} + +}} // namespace parser + + +//////////////////////////////////////////////////////////////////////////////// +// path_view_iterator +//////////////////////////////////////////////////////////////////////////////// +namespace { + +struct path_view_iterator { + const string_view __s_; + size_t __pos_; + + explicit path_view_iterator(string_view const& __s) : __s_(__s), __pos_(__s_.empty() ? parser::npos : 0) {} + explicit path_view_iterator(string_view const& __s, size_t __p) : __s_(__s), __pos_(__p) {} + + string_view operator*() const { + return parser::extract_preferred(__s_, __pos_); + } + + path_view_iterator& operator++() { + increment(); + return *this; + } + + path_view_iterator& operator--() { + decrement(); + return *this; + } + + void increment() { + if (__pos_ == parser::npos) return; + while (! set_position(parser::end_of(__s_, __pos_)+1)) + ; + return; + } + + void decrement() { + if (__pos_ == 0) { + set_position(0); + } + else if (__pos_ == parser::npos) { + auto const str_size = __s_.size(); + set_position(parser::start_of( + __s_, str_size != 0 ? str_size - 1 : str_size)); + } else { + while (!set_position(parser::start_of(__s_, __pos_-1))) + ; + } + } + + bool set_position(size_t pos) { + if (pos >= __s_.size()) { + __pos_ = parser::npos; + } else { + __pos_ = pos; + } + return valid_iterator_position(); + } + + bool valid_iterator_position() const { + if (__pos_ == parser::npos) return true; // end position is valid + return (!parser::is_separator (__s_, __pos_) || + parser::is_root_directory (__s_, __pos_) || + parser::is_trailing_separator(__s_, __pos_) || + parser::is_root_name (__s_, __pos_)); + } + + bool is_end() const { return __pos_ == parser::npos; } + + inline bool operator==(path_view_iterator const& __p) { + return __pos_ == __p.__pos_; + } +}; + +path_view_iterator pbegin(path const& p) { + return path_view_iterator(p.native()); +} + +path_view_iterator pend(path const& p) { + path_view_iterator __p(p.native()); + __p.__pos_ = parser::npos; + return __p; +} + +} // end namespace +/////////////////////////////////////////////////////////////////////////////// +// path definitions +/////////////////////////////////////////////////////////////////////////////// + +path & path::replace_extension(path const & replacement) +{ + path p = extension(); + if (not p.empty()) { + __pn_.erase(__pn_.size() - p.native().size()); + } + if (!replacement.empty()) { + if (replacement.native()[0] != '.') { + __pn_ += "."; + } + __pn_.append(replacement.__pn_); + } + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// +// path.decompose + +string_view path::__root_name() const +{ + return parser::is_root_name(__pn_, 0) + ? parser::extract_preferred(__pn_, 0) + : string_view{}; +} + +string_view path::__root_directory() const +{ + auto start_i = parser::root_directory_start(__pn_); + if(!parser::good(start_i)) { + return {}; + } + return parser::extract_preferred(__pn_, start_i); +} + +string_view path::__relative_path() const +{ + if (empty()) { + return {__pn_}; + } + auto end_i = parser::root_directory_end(__pn_); + if (not parser::good(end_i)) { + end_i = parser::root_name_end(__pn_); + } + if (not parser::good(end_i)) { + return {__pn_}; + } + return string_view(__pn_).substr(end_i+1); +} + +string_view path::__parent_path() const +{ + if (empty() || pbegin(*this) == --pend(*this)) { + return {}; + } + auto end_it = --(--pend(*this)); + auto end_i = parser::end_of(__pn_, end_it.__pos_); + return string_view(__pn_).substr(0, end_i+1); +} + +string_view path::__filename() const +{ + return empty() ? string_view{} : *--pend(*this); +} + +string_view path::__stem() const +{ + return parser::separate_filename(__filename()).first; +} + +string_view path::__extension() const +{ + return parser::separate_filename(__filename()).second; +} + +//////////////////////////////////////////////////////////////////////////// +// path.comparisons +int path::__compare(const value_type* __s) const { + path_view_iterator thisIter(this->native()); + path_view_iterator sIter(__s); + while (!thisIter.is_end() && !sIter.is_end()) { + int res = (*thisIter).compare(*sIter); + if (res != 0) return res; + ++thisIter; ++sIter; + } + if (thisIter.is_end() && sIter.is_end()) + return 0; + if (thisIter.is_end()) + return -1; + return 1; +} + +//////////////////////////////////////////////////////////////////////////// +// path.nonmembers +size_t hash_value(const path& __p) _NOEXCEPT { + path_view_iterator thisIter(__p.native()); + struct HashPairT { + size_t first; + size_t second; + }; + HashPairT hp = {0, 0}; + std::hash<string_view> hasher; + std::__scalar_hash<decltype(hp)> pair_hasher; + while (!thisIter.is_end()) { + hp.second = hasher(*thisIter); + hp.first = pair_hasher(hp); + ++thisIter; + } + return hp.first; +} + +//////////////////////////////////////////////////////////////////////////// +// path.itr +path::iterator path::begin() const +{ + path_view_iterator pit = pbegin(*this); + iterator it; + it.__path_ptr_ = this; + it.__pos_ = pit.__pos_; + it.__elem_.__assign_view(*pit); + return it; +} + +path::iterator path::end() const +{ + iterator it{}; + it.__path_ptr_ = this; + it.__pos_ = parser::npos; + return it; +} + +path::iterator& path::iterator::__increment() { + path_view_iterator it(__path_ptr_->native(), __pos_); + it.increment(); + __pos_ = it.__pos_; + __elem_.__assign_view(*it); + return *this; +} + +path::iterator& path::iterator::__decrement() { + path_view_iterator it(__path_ptr_->native(), __pos_); + it.decrement(); + __pos_ = it.__pos_; + __elem_.__assign_view(*it); + return *this; +} + +_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM diff --git a/src/experimental/memory_resource.cpp b/src/experimental/memory_resource.cpp new file mode 100644 index 0000000000000..c01eb0823baee --- /dev/null +++ b/src/experimental/memory_resource.cpp @@ -0,0 +1,144 @@ +//===------------------------ memory_resource.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/memory_resource" + +#ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER +#include "atomic" +#elif !defined(_LIBCPP_HAS_NO_THREADS) +#include "mutex" +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +// memory_resource + +//memory_resource::~memory_resource() {} + +// new_delete_resource() + +class _LIBCPP_TYPE_VIS_ONLY __new_delete_memory_resource_imp + : public memory_resource +{ +public: + ~__new_delete_memory_resource_imp() = default; + +protected: + virtual void* do_allocate(size_t __size, size_t __align) + { return __allocate(__size); } + + virtual void do_deallocate(void * __p, size_t, size_t) + { __deallocate(__p); } + + virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT + { return &__other == this; } +}; + +// null_memory_resource() + +class _LIBCPP_TYPE_VIS_ONLY __null_memory_resource_imp + : public memory_resource +{ +public: + ~__null_memory_resource_imp() = default; + +protected: + virtual void* do_allocate(size_t, size_t) { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw std::bad_alloc(); +#else + abort(); +#endif + } + virtual void do_deallocate(void *, size_t, size_t) {} + virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT + { return &__other == this; } +}; + +namespace { + +union ResourceInitHelper { + struct { + __new_delete_memory_resource_imp new_delete_res; + __null_memory_resource_imp null_res; + } resources; + char dummy; + _LIBCPP_CONSTEXPR_AFTER_CXX11 ResourceInitHelper() : resources() {} + ~ResourceInitHelper() {} +}; +// When compiled in C++14 this initialization should be a constant expression. +// Only in C++11 is "init_priority" needed to ensure initialization order. +ResourceInitHelper res_init __attribute__((init_priority (101))); + +} // end namespace + + +memory_resource * new_delete_resource() _NOEXCEPT { + return &res_init.resources.new_delete_res; +} + +memory_resource * null_memory_resource() _NOEXCEPT { + return &res_init.resources.null_res; +} + +// default_memory_resource() + +static memory_resource * +__default_memory_resource(bool set = false, memory_resource * new_res = nullptr) _NOEXCEPT +{ +#ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER + static atomic<memory_resource*> __res = + ATOMIC_VAR_INIT(&res_init.resources.new_delete_res); + if (set) { + new_res = new_res ? new_res : new_delete_resource(); + // TODO: Can a weaker ordering be used? + return _VSTD::atomic_exchange_explicit( + &__res, new_res, memory_order::memory_order_acq_rel); + } + else { + return _VSTD::atomic_load_explicit( + &__res, memory_order::memory_order_acquire); + } +#elif !defined(_LIBCPP_HAS_NO_THREADS) + static memory_resource * res = &res_init.resources.new_delete_res; + static mutex res_lock; + if (set) { + new_res = new_res ? new_res : new_delete_resource(); + lock_guard<mutex> guard(res_lock); + memory_resource * old_res = res; + res = new_res; + return old_res; + } else { + lock_guard<mutex> guard(res_lock); + return res; + } +#else + static memory_resource* res = &res_init.resources.new_delete_res; + if (set) { + new_res = new_res ? new_res : new_delete_resource(); + memory_resource * old_res = res; + res = new_res; + return old_res; + } else { + return res; + } +#endif +} + +memory_resource * get_default_resource() _NOEXCEPT +{ + return __default_memory_resource(); +} + +memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT +{ + return __default_memory_resource(true, __new_res); +} + +_LIBCPP_END_NAMESPACE_LFTS_PMR
\ No newline at end of file diff --git a/src/locale.cpp b/src/locale.cpp index 6b04e78817641..da2fd11678d60 100644 --- a/src/locale.cpp +++ b/src/locale.cpp @@ -123,11 +123,6 @@ const locale::category locale::time; const locale::category locale::messages; const locale::category locale::all; -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - class _LIBCPP_HIDDEN locale::__imp : public facet { @@ -163,10 +158,6 @@ private: template <class F> void install_from(const __imp& other); }; -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - locale::__imp::__imp(size_t refs) : facet(refs), facets_(N), @@ -1409,33 +1400,21 @@ ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const wchar_t ctype_byname<wchar_t>::do_widen(char c) const { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return btowc_l(c, __l); -#else - return __btowc_l(c, __l); -#endif + return __libcpp_btowc_l(c, __l); } const char* ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const { for (; low != high; ++low, ++dest) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - *dest = btowc_l(*low, __l); -#else - *dest = __btowc_l(*low, __l); -#endif + *dest = __libcpp_btowc_l(*low, __l); return low; } char ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int r = wctob_l(c, __l); -#else - int r = __wctob_l(c, __l); -#endif + int r = __libcpp_wctob_l(c, __l); return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault; } @@ -1444,11 +1423,7 @@ ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, ch { for (; low != high; ++low, ++dest) { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int r = wctob_l(*low, __l); -#else - int r = __wctob_l(*low, __l); -#endif + int r = __libcpp_wctob_l(*low, __l); *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault; } return low; @@ -1558,22 +1533,14 @@ codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st, { // save state in case it is needed to recover to_nxt on error mbstate_t save_state = st; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t n = wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm), - static_cast<size_t>(to_end-to), &st, __l); -#else - size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l); -#endif + size_t n = __libcpp_wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm), + static_cast<size_t>(to_end-to), &st, __l); if (n == size_t(-1)) { // need to recover to_nxt for (to_nxt = to; frm != frm_nxt; ++frm) { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - n = wcrtomb_l(to_nxt, *frm, &save_state, __l); -#else - n = __wcrtomb_l(to_nxt, *frm, &save_state, __l); -#endif + n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l); if (n == size_t(-1)) break; to_nxt += n; @@ -1590,11 +1557,7 @@ codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st, { // Try to write the terminating null extern_type tmp[MB_LEN_MAX]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - n = wcrtomb_l(tmp, intern_type(), &st, __l); -#else - n = __wcrtomb_l(tmp, intern_type(), &st, __l); -#endif + n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l); if (n == size_t(-1)) // on error return error; if (n > static_cast<size_t>(to_end-to_nxt)) // is there room? @@ -1627,23 +1590,15 @@ codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st, { // save state in case it is needed to recover to_nxt on error mbstate_t save_state = st; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t n = mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm), - static_cast<size_t>(to_end-to), &st, __l); -#else - size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l); -#endif + size_t n = __libcpp_mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm), + static_cast<size_t>(to_end-to), &st, __l); if (n == size_t(-1)) { // need to recover to_nxt for (to_nxt = to; frm != frm_nxt; ++to_nxt) { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - n = mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm), - &save_state, __l); -#else - n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l); -#endif + n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm), + &save_state, __l); switch (n) { case 0: @@ -1671,11 +1626,7 @@ codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st, if (fend != frm_end) // set up next null terminated sequence { // Try to write the terminating null -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); -#else - n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); -#endif + n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); if (n != 0) // on error return error; ++to_nxt; @@ -1695,11 +1646,7 @@ codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st, { to_nxt = to; extern_type tmp[MB_LEN_MAX]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t n = wcrtomb_l(tmp, intern_type(), &st, __l); -#else - size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l); -#endif + size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l); if (n == size_t(-1) || n == 0) // on error return error; --n; @@ -1713,21 +1660,11 @@ codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st, 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) -#else - if (__mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0) -#endif + if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0) 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 -#else - if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings -#endif + if (__l == 0 || __libcpp_mb_cur_max_l(__l) == 1) // there are no known constant length encodings return 1; // which take more than 1 char to form a wchar_t return 0; } @@ -1745,11 +1682,7 @@ codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st, int nbytes = 0; for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t) { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t n = mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l); -#else - size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l); -#endif + size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l); switch (n) { case 0: @@ -1771,11 +1704,7 @@ codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st, int codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return __l == 0 ? 1 : static_cast<int>( MB_CUR_MAX_L(__l)); -#else - return __l == 0 ? 1 : static_cast<int>(__mb_cur_max_l(__l)); -#endif + return __l == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l)); } // Valid UTF ranges @@ -2894,10 +2823,10 @@ ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& f to_nxt = to; if (mode & generate_header) { - if (to_end-to_nxt < 2) + if (to_end - to_nxt < 2) return codecvt_base::partial; - *to_nxt++ = static_cast<uint8_t>(0xFF); - *to_nxt++ = static_cast<uint8_t>(0xFE); + *to_nxt++ = static_cast<uint8_t>(0xFF); + *to_nxt++ = static_cast<uint8_t>(0xFE); } for (; frm_nxt < frm_end; ++frm_nxt) { @@ -4333,11 +4262,7 @@ numpunct_byname<char>::__init(const char* nm) throw runtime_error("numpunct_byname<char>::numpunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - lconv* lc = localeconv_l(loc.get()); -#else - lconv* lc = __localeconv_l(loc.get()); -#endif + lconv* lc = __libcpp_localeconv_l(loc.get()); if (*lc->decimal_point) __decimal_point_ = *lc->decimal_point; if (*lc->thousands_sep) @@ -4376,11 +4301,7 @@ numpunct_byname<wchar_t>::__init(const char* nm) throw runtime_error("numpunct_byname<char>::numpunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - lconv* lc = localeconv_l(loc.get()); -#else - lconv* lc = __localeconv_l(loc.get()); -#endif + lconv* lc = __libcpp_localeconv_l(loc.get()); if (*lc->decimal_point) __decimal_point_ = *lc->decimal_point; if (*lc->thousands_sep) @@ -4981,11 +4902,7 @@ __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct) wchar_t* wbb = wbuf; mbstate_t mb = {0}; const char* bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); -#else - size_t j = __mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); -#endif + size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wchar_t* wbe = wbb + j; @@ -5165,11 +5082,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) strftime_l(buf, countof(buf), "%A", &t, __loc_); mb = mbstate_t(); const char* bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#else - size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#endif + size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -5177,11 +5090,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) strftime_l(buf, countof(buf), "%a", &t, __loc_); mb = mbstate_t(); bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#endif + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -5194,11 +5103,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) strftime_l(buf, countof(buf), "%B", &t, __loc_); mb = mbstate_t(); const char* bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#else - size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#endif + size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -5206,11 +5111,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) strftime_l(buf, countof(buf), "%b", &t, __loc_); mb = mbstate_t(); bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#endif + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -5221,11 +5122,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) strftime_l(buf, countof(buf), "%p", &t, __loc_); mb = mbstate_t(); const char* bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#else - size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#endif + size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -5234,11 +5131,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) strftime_l(buf, countof(buf), "%p", &t, __loc_); mb = mbstate_t(); bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#endif + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -5513,11 +5406,7 @@ __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, __do_put(__nar, __ne, __tm, __fmt, __mod); mbstate_t mb = {0}; const char* __nb = __nar; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); -#else - size_t j = __mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); -#endif + size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); __we = __wb + j; @@ -5908,11 +5797,7 @@ moneypunct_byname<char, false>::init(const char* nm) throw runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - lconv* lc = localeconv_l(loc.get()); -#else - lconv* lc = __localeconv_l(loc.get()); -#endif + lconv* lc = __libcpp_localeconv_l(loc.get()); if (*lc->mon_decimal_point) __decimal_point_ = *lc->mon_decimal_point; else @@ -5956,11 +5841,7 @@ moneypunct_byname<char, true>::init(const char* nm) throw runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - lconv* lc = localeconv_l(loc.get()); -#else - lconv* lc = __localeconv_l(loc.get()); -#endif + lconv* lc = __libcpp_localeconv_l(loc.get()); if (*lc->mon_decimal_point) __decimal_point_ = *lc->mon_decimal_point; else @@ -6021,11 +5902,7 @@ moneypunct_byname<wchar_t, false>::init(const char* nm) throw runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - lconv* lc = localeconv_l(loc.get()); -#else - lconv* lc = __localeconv_l(loc.get()); -#endif + lconv* lc = __libcpp_localeconv_l(loc.get()); if (*lc->mon_decimal_point) __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point); else @@ -6038,11 +5915,7 @@ moneypunct_byname<wchar_t, false>::init(const char* nm) wchar_t wbuf[100]; mbstate_t mb = {0}; const char* bb = lc->currency_symbol; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#else - size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#endif + size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wchar_t* wbe = wbuf + j; @@ -6057,11 +5930,7 @@ moneypunct_byname<wchar_t, false>::init(const char* nm) { mb = mbstate_t(); bb = lc->positive_sign; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#endif + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -6073,11 +5942,7 @@ moneypunct_byname<wchar_t, false>::init(const char* nm) { mb = mbstate_t(); bb = lc->negative_sign; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#endif + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -6104,11 +5969,7 @@ moneypunct_byname<wchar_t, true>::init(const char* nm) throw runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - lconv* lc = localeconv_l(loc.get()); -#else - lconv* lc = __localeconv_l(loc.get()); -#endif + lconv* lc = __libcpp_localeconv_l(loc.get()); if (*lc->mon_decimal_point) __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point); else @@ -6121,11 +5982,7 @@ moneypunct_byname<wchar_t, true>::init(const char* nm) wchar_t wbuf[100]; mbstate_t mb = {0}; const char* bb = lc->int_curr_symbol; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#else - size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#endif + size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wchar_t* wbe = wbuf + j; @@ -6144,11 +6001,7 @@ moneypunct_byname<wchar_t, true>::init(const char* nm) { mb = mbstate_t(); bb = lc->positive_sign; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#endif + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -6164,11 +6017,7 @@ moneypunct_byname<wchar_t, true>::init(const char* nm) { mb = mbstate_t(); bb = lc->negative_sign; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#endif + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; diff --git a/src/memory.cpp b/src/memory.cpp index 5b81f26e3dc00..15e947fc0ff8c 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -124,15 +124,15 @@ __shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT #endif // _LIBCPP_NO_RTTI -#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) +#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) static const std::size_t __sp_mut_count = 16; -static pthread_mutex_t mut_back_imp[__sp_mut_count] = +static __libcpp_mutex_t mut_back_imp[__sp_mut_count] = { - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER + _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, + _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, + _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, + _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER }; static mutex* mut_back = reinterpret_cast<std::mutex*>(mut_back_imp); @@ -177,7 +177,7 @@ __get_sp_mut(const void* p) return muts[hash<const void*>()(p) & (__sp_mut_count-1)]; } -#endif // defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) +#endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) void declare_reachable(void*) diff --git a/src/mutex.cpp b/src/mutex.cpp index 127e67a2627e6..9f808ca5076c5 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -23,13 +23,13 @@ const adopt_lock_t adopt_lock = {}; mutex::~mutex() { - pthread_mutex_destroy(&__m_); + __libcpp_mutex_destroy(&__m_); } void mutex::lock() { - int ec = pthread_mutex_lock(&__m_); + int ec = __libcpp_mutex_lock(&__m_); if (ec) __throw_system_error(ec, "mutex lock failed"); } @@ -37,13 +37,13 @@ mutex::lock() bool mutex::try_lock() _NOEXCEPT { - return pthread_mutex_trylock(&__m_) == 0; + return __libcpp_mutex_trylock(&__m_) == 0; } void mutex::unlock() _NOEXCEPT { - int ec = pthread_mutex_unlock(&__m_); + int ec = __libcpp_mutex_unlock(&__m_); (void)ec; assert(ec == 0); } @@ -52,36 +52,14 @@ mutex::unlock() _NOEXCEPT recursive_mutex::recursive_mutex() { - pthread_mutexattr_t attr; - int ec = pthread_mutexattr_init(&attr); + int ec = __libcpp_recursive_mutex_init(&__m_); if (ec) - goto fail; - ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - if (ec) - { - pthread_mutexattr_destroy(&attr); - goto fail; - } - ec = pthread_mutex_init(&__m_, &attr); - if (ec) - { - pthread_mutexattr_destroy(&attr); - goto fail; - } - ec = pthread_mutexattr_destroy(&attr); - if (ec) - { - pthread_mutex_destroy(&__m_); - goto fail; - } - return; -fail: - __throw_system_error(ec, "recursive_mutex constructor failed"); + __throw_system_error(ec, "recursive_mutex constructor failed"); } recursive_mutex::~recursive_mutex() { - int e = pthread_mutex_destroy(&__m_); + int e = __libcpp_mutex_destroy(&__m_); (void)e; assert(e == 0); } @@ -89,7 +67,7 @@ recursive_mutex::~recursive_mutex() void recursive_mutex::lock() { - int ec = pthread_mutex_lock(&__m_); + int ec = __libcpp_mutex_lock(&__m_); if (ec) __throw_system_error(ec, "recursive_mutex lock failed"); } @@ -97,7 +75,7 @@ recursive_mutex::lock() void recursive_mutex::unlock() _NOEXCEPT { - int e = pthread_mutex_unlock(&__m_); + int e = __libcpp_mutex_unlock(&__m_); (void)e; assert(e == 0); } @@ -105,7 +83,7 @@ recursive_mutex::unlock() _NOEXCEPT bool recursive_mutex::try_lock() _NOEXCEPT { - return pthread_mutex_trylock(&__m_) == 0; + return __libcpp_mutex_trylock(&__m_) == 0; } // timed_mutex @@ -165,9 +143,9 @@ recursive_timed_mutex::~recursive_timed_mutex() void recursive_timed_mutex::lock() { - pthread_t id = pthread_self(); + __libcpp_thread_id id = __libcpp_thread_get_current_id(); unique_lock<mutex> lk(__m_); - if (pthread_equal(id, __id_)) + if (__libcpp_thread_id_equal(id, __id_)) { if (__count_ == numeric_limits<size_t>::max()) __throw_system_error(EAGAIN, "recursive_timed_mutex lock limit reached"); @@ -183,9 +161,9 @@ recursive_timed_mutex::lock() bool recursive_timed_mutex::try_lock() _NOEXCEPT { - pthread_t id = pthread_self(); + __libcpp_thread_id id = __libcpp_thread_get_current_id(); unique_lock<mutex> lk(__m_, try_to_lock); - if (lk.owns_lock() && (__count_ == 0 || pthread_equal(id, __id_))) + if (lk.owns_lock() && (__count_ == 0 || __libcpp_thread_id_equal(id, __id_))) { if (__count_ == numeric_limits<size_t>::max()) return false; @@ -217,8 +195,8 @@ recursive_timed_mutex::unlock() _NOEXCEPT // keep in sync with: 7741191. #ifndef _LIBCPP_HAS_NO_THREADS -static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; +static __libcpp_mutex_t mut = _LIBCPP_MUTEX_INITIALIZER; +static __libcpp_condvar_t cv = _LIBCPP_CONDVAR_INITIALIZER; #endif /// NOTE: Changes to flag are done via relaxed atomic stores @@ -247,9 +225,9 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) #endif // _LIBCPP_NO_EXCEPTIONS } #else // !_LIBCPP_HAS_NO_THREADS - pthread_mutex_lock(&mut); + __libcpp_mutex_lock(&mut); while (flag == 1) - pthread_cond_wait(&cv, &mut); + __libcpp_condvar_wait(&cv, &mut); if (flag == 0) { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -257,26 +235,26 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) { #endif // _LIBCPP_NO_EXCEPTIONS __libcpp_relaxed_store(&flag, 1ul); - pthread_mutex_unlock(&mut); + __libcpp_mutex_unlock(&mut); func(arg); - pthread_mutex_lock(&mut); + __libcpp_mutex_lock(&mut); __libcpp_relaxed_store(&flag, ~0ul); - pthread_mutex_unlock(&mut); - pthread_cond_broadcast(&cv); + __libcpp_mutex_unlock(&mut); + __libcpp_condvar_broadcast(&cv); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - pthread_mutex_lock(&mut); + __libcpp_mutex_lock(&mut); __libcpp_relaxed_store(&flag, 0ul); - pthread_mutex_unlock(&mut); - pthread_cond_broadcast(&cv); + __libcpp_mutex_unlock(&mut); + __libcpp_condvar_broadcast(&cv); throw; } #endif // _LIBCPP_NO_EXCEPTIONS } else - pthread_mutex_unlock(&mut); + __libcpp_mutex_unlock(&mut); #endif // !_LIBCPP_HAS_NO_THREADS } diff --git a/src/regex.cpp b/src/regex.cpp index 17dd6eaa60a7e..a7363599d5a5c 100644 --- a/src/regex.cpp +++ b/src/regex.cpp @@ -69,21 +69,12 @@ regex_error::~regex_error() throw() {} namespace { -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - struct collationnames { const char* elem_; char char_; }; -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - const collationnames collatenames[] = { {"A", 0x41}, @@ -199,21 +190,12 @@ const collationnames collatenames[] = {"zero", 0x30} }; -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - struct classnames { const char* elem_; regex_traits<char>::char_class_type mask_; }; -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - const classnames ClassNames[] = { {"alnum", ctype_base::alnum}, diff --git a/src/strstream.cpp b/src/strstream.cpp index ea728138db66c..0e2d7ff21bb97 100644 --- a/src/strstream.cpp +++ b/src/strstream.cpp @@ -11,6 +11,7 @@ #include "algorithm" #include "climits" #include "cstring" +#include "__debug" _LIBCPP_BEGIN_NAMESPACE_STD @@ -167,11 +168,13 @@ strstreambuf::overflow(int_type __c) buf = new char[new_size]; if (buf == nullptr) return int_type(EOF); - memcpy(buf, eback(), static_cast<size_t>(old_size)); + if (old_size != 0) { + _LIBCPP_ASSERT(eback(), "overflow copying from NULL"); + memcpy(buf, eback(), static_cast<size_t>(old_size)); + } ptrdiff_t ninp = gptr() - eback(); ptrdiff_t einp = egptr() - eback(); ptrdiff_t nout = pptr() - pbase(); - ptrdiff_t eout = epptr() - pbase(); if (__strmode_ & __allocated) { if (__pfree_) @@ -180,7 +183,7 @@ strstreambuf::overflow(int_type __c) delete [] eback(); } setg(buf, buf + ninp, buf + einp); - setp(buf + einp, buf + einp + eout); + setp(buf + einp, buf + new_size); pbump(static_cast<int>(nout)); __strmode_ |= __allocated; } diff --git a/src/system_error.cpp b/src/system_error.cpp index 3023e200aa34d..87f35ae37f391 100644 --- a/src/system_error.cpp +++ b/src/system_error.cpp @@ -13,8 +13,17 @@ #include "system_error" #include "include/config_elast.h" +#include "cerrno" #include "cstring" +#include "cstdio" +#include "cstdlib" +#include "cassert" #include "string" +#include "string.h" + +#if defined(__ANDROID__) +#include <android/api-level.h> +#endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -46,10 +55,56 @@ error_category::equivalent(const error_code& code, int condition) const _NOEXCEP return *this == code.category() && code.value() == condition; } +namespace { + +// GLIBC also uses 1024 as the maximum buffer size internally. +constexpr size_t strerror_buff_size = 1024; + +string do_strerror_r(int ev); + +#if defined(__linux__) && !defined(_LIBCPP_HAS_MUSL_LIBC) \ + && (!defined(__ANDROID__) || __ANDROID_API__ >= 23) +// GNU Extended version +string do_strerror_r(int ev) { + char buffer[strerror_buff_size]; + char* ret = ::strerror_r(ev, buffer, strerror_buff_size); + return string(ret); +} +#else +// POSIX version +string do_strerror_r(int ev) { + char buffer[strerror_buff_size]; + const int old_errno = errno; + int ret; + if ((ret = ::strerror_r(ev, buffer, strerror_buff_size)) != 0) { + // If `ret == -1` then the error is specified using `errno`, otherwise + // `ret` represents the error. + const int new_errno = ret == -1 ? errno : ret; + errno = old_errno; + if (new_errno == EINVAL) { + std::snprintf(buffer, strerror_buff_size, "Unknown error %d", ev); + return string(buffer); + } else { + assert(new_errno == ERANGE); + // FIXME maybe? 'strerror_buff_size' is likely to exceed the + // maximum error size so ERANGE shouldn't be returned. + std::abort(); + } + } + return string(buffer); +} +#endif + +} // end namespace + string __do_message::message(int ev) const { - return string(strerror(ev)); +#if defined(_LIBCPP_HAS_NO_THREADS) + return string(::strerror(ev)); +#else + return do_strerror_r(ev); +#endif } class _LIBCPP_HIDDEN __generic_error_category diff --git a/src/thread.cpp b/src/thread.cpp index bd27f28783837..467402b6b423a 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -16,10 +16,15 @@ #include "future" #include "limits" #include <sys/types.h> -#if !defined(_WIN32) -# if !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) && !defined(__CloudABI__) + +#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +# include <sys/param.h> +# if defined(BSD) # include <sys/sysctl.h> -# endif // !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) && !defined(__CloudABI__) +# endif // defined(BSD) +#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) + +#if !defined(_WIN32) # include <unistd.h> #endif // !_WIN32 @@ -41,14 +46,17 @@ thread::~thread() void thread::join() { - int ec = pthread_join(__t_, 0); + int ec = EINVAL; + if (__t_ != 0) + { + ec = __libcpp_thread_join(&__t_); + if (ec == 0) + __t_ = 0; + } #ifndef _LIBCPP_NO_EXCEPTIONS if (ec) throw system_error(error_code(ec, system_category()), "thread::join failed"); -#else - (void)ec; #endif // _LIBCPP_NO_EXCEPTIONS - __t_ = 0; } void @@ -57,7 +65,7 @@ thread::detach() int ec = EINVAL; if (__t_ != 0) { - ec = pthread_detach(__t_); + ec = __libcpp_thread_detach(&__t_); if (ec == 0) __t_ = 0; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b67b3b43f83ea..d47a9e003fc03 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -10,11 +10,16 @@ set(LIBCXX_LIT_VARIANT "libcxx" CACHE STRING "Configuration variant to use for LIT.") pythonize_bool(LIBCXX_ENABLE_EXCEPTIONS) +pythonize_bool(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY) +pythonize_bool(LIBCXX_ENABLE_FILESYSTEM) pythonize_bool(LIBCXX_ENABLE_RTTI) pythonize_bool(LIBCXX_ENABLE_SHARED) pythonize_bool(LIBCXX_BUILD_32_BITS) pythonize_bool(LIBCXX_GENERATE_COVERAGE) +pythonize_bool(LIBCXXABI_ENABLE_SHARED) pythonize_bool(LIBCXXABI_USE_LLVM_UNWINDER) +pythonize_bool(LIBCXX_HAS_ATOMIC_LIB) +pythonize_bool(LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB) # The tests shouldn't link to any ABI library when it has been linked into # libc++ statically or via a linker script. @@ -22,6 +27,13 @@ if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY OR LIBCXX_ENABLE_ABI_LINKER_SCRIPT) set(LIBCXX_CXX_ABI_LIBNAME "none") endif() +# By default, for non-standalone builds, libcxx and libcxxabi share a library +# directory. +if (NOT LIBCXX_CXX_ABI_LIBRARY_PATH) + set(LIBCXX_CXX_ABI_LIBRARY_PATH "${LIBCXX_LIBRARY_DIR}" CACHE PATH + "The path to libc++abi library.") +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 @@ -34,15 +46,19 @@ configure_file( ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg @ONLY) +if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY) + set(experimental_dep cxx_experimental) +endif() + add_lit_testsuite(check-libcxx "Running libcxx tests" ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS cxx) + DEPENDS cxx ${experimental_dep}) 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(capture_dirs "${LIBCXX_LIB_CMAKEFILES_DIR}/cxx.dir/;${LIBCXX_LIB_CMAKEFILES_DIR}/cxx_experimental.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/std/algorithms/version.pass.cpp b/test/libcxx/algorithms/version.pass.cpp index 20f0637e641b0..20f0637e641b0 100644 --- a/test/std/algorithms/version.pass.cpp +++ b/test/libcxx/algorithms/version.pass.cpp diff --git a/test/std/atomics/atomics.flag/init03.pass.cpp b/test/libcxx/atomics/atomics.flag/init_bool.pass.cpp index 0910bc5ceccb6..d7b172cd1212d 100644 --- a/test/std/atomics/atomics.flag/init03.pass.cpp +++ b/test/libcxx/atomics/atomics.flag/init_bool.pass.cpp @@ -20,6 +20,12 @@ int main() { - std::atomic_flag f(false); - assert(f.test_and_set() == 0); + { + std::atomic_flag f(false); + assert(f.test_and_set() == 0); + } + { + std::atomic_flag f(true); + assert(f.test_and_set() == 1); + } } diff --git a/test/std/atomics/version.pass.cpp b/test/libcxx/atomics/version.pass.cpp index fae2736d229f2..fae2736d229f2 100644 --- a/test/std/atomics/version.pass.cpp +++ b/test/libcxx/atomics/version.pass.cpp diff --git a/test/libcxx/compiler.py b/test/libcxx/compiler.py index 7dfb13abbd41e..17e6cf441ec1d 100644 --- a/test/libcxx/compiler.py +++ b/test/libcxx/compiler.py @@ -47,9 +47,10 @@ class CXXCompiler(object): self.type = compiler_type self.version = (major_ver, minor_ver, patchlevel) - def _basicCmd(self, source_files, out, is_link=False, input_is_cxx=False): + def _basicCmd(self, source_files, out, is_link=False, input_is_cxx=False, + disable_ccache=False): cmd = [] - if self.use_ccache and not is_link: + if self.use_ccache and not disable_ccache and not is_link: cmd += ['ccache'] cmd += [self.path] if out is not None: @@ -65,12 +66,15 @@ class CXXCompiler(object): return cmd def preprocessCmd(self, source_files, out=None, flags=[]): - cmd = self._basicCmd(source_files, out, input_is_cxx=True) + ['-E'] + cmd = self._basicCmd(source_files, out, input_is_cxx=True, + disable_ccache=True) + ['-E'] cmd += self.flags + self.compile_flags + flags return cmd - def compileCmd(self, source_files, out=None, flags=[]): - cmd = self._basicCmd(source_files, out, input_is_cxx=True) + ['-c'] + def compileCmd(self, source_files, out=None, flags=[], + disable_ccache=False): + cmd = self._basicCmd(source_files, out, input_is_cxx=True, + disable_ccache=disable_ccache) + ['-c'] cmd += self.flags + self.compile_flags + flags return cmd @@ -89,8 +93,10 @@ class CXXCompiler(object): out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd) return cmd, out, err, rc - def compile(self, source_files, out=None, flags=[], env=None, cwd=None): - cmd = self.compileCmd(source_files, out, flags) + def compile(self, source_files, out=None, flags=[], env=None, cwd=None, + disable_ccache=False): + cmd = self.compileCmd(source_files, out, flags, + disable_ccache=disable_ccache) out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd) return cmd, out, err, rc @@ -106,7 +112,8 @@ class CXXCompiler(object): return cmd, out, err, rc def compileLinkTwoSteps(self, source_file, out=None, object_file=None, - flags=[], env=None, cwd=None): + flags=[], env=None, cwd=None, + disable_ccache=False): if not isinstance(source_file, str): raise TypeError('This function only accepts a single input file') if object_file is None: @@ -117,7 +124,8 @@ class CXXCompiler(object): with_fn = lambda: libcxx.util.nullContext(object_file) with with_fn() as object_file: cc_cmd, cc_stdout, cc_stderr, rc = self.compile( - source_file, object_file, flags=flags, env=env, cwd=cwd) + source_file, object_file, flags=flags, env=env, cwd=cwd, + disable_ccache=disable_ccache) if rc != 0: return cc_cmd, cc_stdout, cc_stderr, rc diff --git a/test/std/containers/associative/map/version.pass.cpp b/test/libcxx/containers/associative/map/version.pass.cpp index b2e3fa43e7879..b2e3fa43e7879 100644 --- a/test/std/containers/associative/map/version.pass.cpp +++ b/test/libcxx/containers/associative/map/version.pass.cpp diff --git a/test/std/containers/associative/set/version.pass.cpp b/test/libcxx/containers/associative/set/version.pass.cpp index c3c4d926e5c33..c3c4d926e5c33 100644 --- a/test/std/containers/associative/set/version.pass.cpp +++ b/test/libcxx/containers/associative/set/version.pass.cpp diff --git a/test/std/containers/associative/tree_balance_after_insert.pass.cpp b/test/libcxx/containers/associative/tree_balance_after_insert.pass.cpp index b0a3e74cab0af..300c1e9a49157 100644 --- a/test/std/containers/associative/tree_balance_after_insert.pass.cpp +++ b/test/libcxx/containers/associative/tree_balance_after_insert.pass.cpp @@ -24,6 +24,9 @@ struct Node Node* __parent_; bool __is_black_; + Node* __parent_unsafe() const { return __parent_; } + void __set_parent(Node* x) { __parent_ = x;} + Node() : __left_(), __right_(), __parent_(), __is_black_() {} }; diff --git a/test/libcxx/containers/associative/tree_key_value_traits.pass.cpp b/test/libcxx/containers/associative/tree_key_value_traits.pass.cpp new file mode 100644 index 0000000000000..0befd749a50c0 --- /dev/null +++ b/test/libcxx/containers/associative/tree_key_value_traits.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// 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 <__tree> +#include <map> +#include <set> +#include <type_traits> + +#include "test_macros.h" +#include "min_allocator.h" + +void testKeyValueTrait() { + { + typedef int Tp; + typedef std::__tree_key_value_types<Tp> Traits; + static_assert((std::is_same<Traits::key_type, int>::value), ""); + static_assert((std::is_same<Traits::__node_value_type, Tp>::value), ""); + static_assert((std::is_same<Traits::__container_value_type, Tp>::value), ""); + static_assert(Traits::__is_map == false, ""); + } + { + typedef std::pair<int, int> Tp; + typedef std::__tree_key_value_types<Tp> Traits; + static_assert((std::is_same<Traits::key_type, Tp>::value), ""); + static_assert((std::is_same<Traits::__node_value_type, Tp>::value), ""); + static_assert((std::is_same<Traits::__container_value_type, Tp>::value), ""); + static_assert(Traits::__is_map == false, ""); + } + { + typedef std::pair<const int, int> Tp; + typedef std::__tree_key_value_types<Tp> Traits; + static_assert((std::is_same<Traits::key_type, Tp>::value), ""); + static_assert((std::is_same<Traits::__node_value_type, Tp>::value), ""); + static_assert((std::is_same<Traits::__container_value_type, Tp>::value), ""); + static_assert(Traits::__is_map == false, ""); + } + { + typedef std::__value_type<int, int> Tp; + typedef std::__tree_key_value_types<Tp> Traits; + static_assert((std::is_same<Traits::key_type, int>::value), ""); + static_assert((std::is_same<Traits::mapped_type, int>::value), ""); + static_assert((std::is_same<Traits::__node_value_type, Tp>::value), ""); + static_assert((std::is_same<Traits::__container_value_type, + std::pair<const int, int> >::value), ""); + static_assert((std::is_same<Traits::__map_value_type, + std::pair<const int, int> >::value), ""); + static_assert(Traits::__is_map == true, ""); + } +} + +int main() { + testKeyValueTrait(); +} diff --git a/test/std/containers/associative/tree_left_rotate.pass.cpp b/test/libcxx/containers/associative/tree_left_rotate.pass.cpp index 774cbc6879856..2720b448bdd4e 100644 --- a/test/std/containers/associative/tree_left_rotate.pass.cpp +++ b/test/libcxx/containers/associative/tree_left_rotate.pass.cpp @@ -23,6 +23,9 @@ struct Node Node* __right_; Node* __parent_; + Node* __parent_unsafe() const { return __parent_; } + void __set_parent(Node* x) { __parent_ = x;} + Node() : __left_(), __right_(), __parent_() {} }; diff --git a/test/std/containers/associative/tree_remove.pass.cpp b/test/libcxx/containers/associative/tree_remove.pass.cpp index fb14bd929e913..fa0b7d4a13117 100644 --- a/test/std/containers/associative/tree_remove.pass.cpp +++ b/test/libcxx/containers/associative/tree_remove.pass.cpp @@ -24,6 +24,9 @@ struct Node Node* __parent_; bool __is_black_; + Node* __parent_unsafe() const { return __parent_; } + void __set_parent(Node* x) { __parent_ = x;} + Node() : __left_(), __right_(), __parent_(), __is_black_() {} }; diff --git a/test/std/containers/associative/tree_right_rotate.pass.cpp b/test/libcxx/containers/associative/tree_right_rotate.pass.cpp index 06ec7b8894525..9355a46b4e2b7 100644 --- a/test/std/containers/associative/tree_right_rotate.pass.cpp +++ b/test/libcxx/containers/associative/tree_right_rotate.pass.cpp @@ -23,6 +23,9 @@ struct Node Node* __right_; Node* __parent_; + Node* __parent_unsafe() const { return __parent_; } + void __set_parent(Node* x) { __parent_ = x;} + Node() : __left_(), __right_(), __parent_() {} }; diff --git a/test/std/containers/container.adaptors/queue/version.pass.cpp b/test/libcxx/containers/container.adaptors/queue/version.pass.cpp index 35b94b33c517d..35b94b33c517d 100644 --- a/test/std/containers/container.adaptors/queue/version.pass.cpp +++ b/test/libcxx/containers/container.adaptors/queue/version.pass.cpp diff --git a/test/std/containers/container.adaptors/stack/version.pass.cpp b/test/libcxx/containers/container.adaptors/stack/version.pass.cpp index 339d0f4dda8f7..339d0f4dda8f7 100644 --- a/test/std/containers/container.adaptors/stack/version.pass.cpp +++ b/test/libcxx/containers/container.adaptors/stack/version.pass.cpp diff --git a/test/libcxx/containers/gnu_cxx/hash_map.pass.cpp b/test/libcxx/containers/gnu_cxx/hash_map.pass.cpp new file mode 100644 index 0000000000000..0d9115d0f6938 --- /dev/null +++ b/test/libcxx/containers/gnu_cxx/hash_map.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// Prevent emission of the deprecated warning. +#ifdef __clang__ +#pragma clang diagnostic ignored "-W#warnings" +#endif + +#include <ext/hash_map> + +namespace __gnu_cxx { +template class hash_map<int, int>; +} + +int main() { + typedef __gnu_cxx::hash_map<int, int> Map; + Map m; + Map m2(m); + ((void)m2); +} diff --git a/test/libcxx/containers/gnu_cxx/hash_set.pass.cpp b/test/libcxx/containers/gnu_cxx/hash_set.pass.cpp new file mode 100644 index 0000000000000..5fd4bde66e0ac --- /dev/null +++ b/test/libcxx/containers/gnu_cxx/hash_set.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// Prevent emission of the deprecated warning. +#ifdef __clang__ +#pragma clang diagnostic ignored "-W#warnings" +#endif + +#include <ext/hash_set> + +namespace __gnu_cxx { +template class hash_set<int>; +} + +int main() { + typedef __gnu_cxx::hash_set<int> Set; + Set s; + Set s2(s); + ((void)s2); +} diff --git a/test/std/containers/sequences/array/version.pass.cpp b/test/libcxx/containers/sequences/array/version.pass.cpp index b89a8dd8cca3b..b89a8dd8cca3b 100644 --- a/test/std/containers/sequences/array/version.pass.cpp +++ b/test/libcxx/containers/sequences/array/version.pass.cpp diff --git a/test/std/containers/sequences/deque/version.pass.cpp b/test/libcxx/containers/sequences/deque/version.pass.cpp index 22e663d9bc227..22e663d9bc227 100644 --- a/test/std/containers/sequences/deque/version.pass.cpp +++ b/test/libcxx/containers/sequences/deque/version.pass.cpp diff --git a/test/std/containers/sequences/forwardlist/version.pass.cpp b/test/libcxx/containers/sequences/forwardlist/version.pass.cpp index 918c8dd5d73cd..918c8dd5d73cd 100644 --- a/test/std/containers/sequences/forwardlist/version.pass.cpp +++ b/test/libcxx/containers/sequences/forwardlist/version.pass.cpp diff --git a/test/std/containers/sequences/list/db_back.pass.cpp b/test/libcxx/containers/sequences/list/db_back.pass.cpp index b16c0e90701e6..96dfd2d8d2ecd 100644 --- a/test/std/containers/sequences/list/db_back.pass.cpp +++ b/test/libcxx/containers/sequences/list/db_back.pass.cpp @@ -11,8 +11,7 @@ // Call back() on empty container. -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) #include <list> @@ -21,11 +20,8 @@ #include <exception> #include <cstdlib> -#include "min_allocator.h" - int main() { - { typedef int T; typedef std::list<T> C; C c(1); @@ -33,24 +29,4 @@ int main() c.clear(); assert(c.back() == 0); assert(false); - } -#if __cplusplus >= 201103L - { - typedef int T; - typedef std::list<T, min_allocator<T>> C; - C c(1); - assert(c.back() == 0); - c.clear(); - assert(c.back() == 0); - assert(false); - } -#endif } - -#else - -int main() -{ -} - -#endif diff --git a/test/std/containers/sequences/list/db_cback.pass.cpp b/test/libcxx/containers/sequences/list/db_cback.pass.cpp index ba3977e16f48e..1e25307c4602b 100644 --- a/test/std/containers/sequences/list/db_cback.pass.cpp +++ b/test/libcxx/containers/sequences/list/db_cback.pass.cpp @@ -11,8 +11,7 @@ // Call back() on empty const container. -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) #include <list> @@ -21,32 +20,11 @@ #include <exception> #include <cstdlib> -#include "min_allocator.h" - int main() { - { typedef int T; typedef std::list<T> C; const C c; assert(c.back() == 0); assert(false); - } -#if __cplusplus >= 201103L - { - typedef int T; - typedef std::list<T, min_allocator<T>> C; - const C c; - assert(c.back() == 0); - assert(false); - } -#endif } - -#else - -int main() -{ -} - -#endif diff --git a/test/std/containers/sequences/list/db_cfront.pass.cpp b/test/libcxx/containers/sequences/list/db_cfront.pass.cpp index d42290c43c084..9501ce1931382 100644 --- a/test/std/containers/sequences/list/db_cfront.pass.cpp +++ b/test/libcxx/containers/sequences/list/db_cfront.pass.cpp @@ -11,8 +11,7 @@ // Call front() on empty const container. -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) #include <list> @@ -21,32 +20,11 @@ #include <exception> #include <cstdlib> -#include "min_allocator.h" - int main() { - { typedef int T; typedef std::list<T> C; const C c; assert(c.front() == 0); assert(false); - } -#if __cplusplus >= 201103L - { - typedef int T; - typedef std::list<T, min_allocator<T>> C; - const C c; - assert(c.front() == 0); - assert(false); - } -#endif } - -#else - -int main() -{ -} - -#endif diff --git a/test/std/containers/sequences/list/db_front.pass.cpp b/test/libcxx/containers/sequences/list/db_front.pass.cpp index 037b16035c66b..fc02895a8912c 100644 --- a/test/std/containers/sequences/list/db_front.pass.cpp +++ b/test/libcxx/containers/sequences/list/db_front.pass.cpp @@ -11,8 +11,7 @@ // Call front() on empty container. -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) #include <list> @@ -21,11 +20,8 @@ #include <exception> #include <cstdlib> -#include "min_allocator.h" - int main() { - { typedef int T; typedef std::list<T> C; C c(1); @@ -33,24 +29,4 @@ int main() c.clear(); assert(c.front() == 0); assert(false); - } -#if __cplusplus >= 201103L - { - typedef int T; - typedef std::list<T, min_allocator<T>> C; - C c(1); - assert(c.front() == 0); - c.clear(); - assert(c.front() == 0); - assert(false); - } -#endif } - -#else - -int main() -{ -} - -#endif diff --git a/test/std/containers/sequences/list/db_iterators_6.pass.cpp b/test/libcxx/containers/sequences/list/db_iterators_6.pass.cpp index a5b8020b37335..3f0fd015e9a4d 100644 --- a/test/std/containers/sequences/list/db_iterators_6.pass.cpp +++ b/test/libcxx/containers/sequences/list/db_iterators_6.pass.cpp @@ -11,8 +11,7 @@ // Decrement iterator prior to begin. -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) #include <list> @@ -21,11 +20,8 @@ #include <exception> #include <cstdlib> -#include "min_allocator.h" - int main() { - { typedef int T; typedef std::list<T> C; C c(1); @@ -34,25 +30,4 @@ int main() assert(i == c.begin()); --i; assert(false); - } -#if __cplusplus >= 201103L - { - typedef int T; - typedef std::list<T, min_allocator<T>> C; - C c(1); - C::iterator i = c.end(); - --i; - assert(i == c.begin()); - --i; - assert(false); - } -#endif } - -#else - -int main() -{ -} - -#endif diff --git a/test/std/containers/sequences/list/db_iterators_7.pass.cpp b/test/libcxx/containers/sequences/list/db_iterators_7.pass.cpp index 76a491b1184dc..bc2b7f4e1da21 100644 --- a/test/std/containers/sequences/list/db_iterators_7.pass.cpp +++ b/test/libcxx/containers/sequences/list/db_iterators_7.pass.cpp @@ -11,8 +11,7 @@ // Increment iterator past end. -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) #include <list> @@ -21,11 +20,8 @@ #include <exception> #include <cstdlib> -#include "min_allocator.h" - int main() { - { typedef int T; typedef std::list<T> C; C c(1); @@ -34,25 +30,4 @@ int main() assert(i == c.end()); ++i; assert(false); - } -#if __cplusplus >= 201103L - { - typedef int T; - typedef std::list<T, min_allocator<T>> C; - C c(1); - C::iterator i = c.begin(); - ++i; - assert(i == c.end()); - ++i; - assert(false); - } -#endif } - -#else - -int main() -{ -} - -#endif diff --git a/test/std/containers/sequences/list/db_iterators_8.pass.cpp b/test/libcxx/containers/sequences/list/db_iterators_8.pass.cpp index 1d1ee23a393a5..08c10d34a01ee 100644 --- a/test/std/containers/sequences/list/db_iterators_8.pass.cpp +++ b/test/libcxx/containers/sequences/list/db_iterators_8.pass.cpp @@ -11,8 +11,7 @@ // Dereference non-dereferenceable iterator. -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) #include <list> @@ -21,34 +20,12 @@ #include <exception> #include <cstdlib> -#include "min_allocator.h" - int main() { - { typedef int T; typedef std::list<T> C; C c(1); C::iterator i = c.end(); T j = *i; assert(false); - } -#if __cplusplus >= 201103L - { - typedef int T; - typedef std::list<T, min_allocator<T>> C; - C c(1); - C::iterator i = c.end(); - T j = *i; - assert(false); - } -#endif } - -#else - -int main() -{ -} - -#endif diff --git a/test/std/containers/sequences/list/db_iterators_9.pass.cpp b/test/libcxx/containers/sequences/list/db_iterators_9.pass.cpp index d02fcd6e44971..e2b95d8b16647 100644 --- a/test/std/containers/sequences/list/db_iterators_9.pass.cpp +++ b/test/libcxx/containers/sequences/list/db_iterators_9.pass.cpp @@ -7,12 +7,14 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 +// UNSUPPORTED: libcpp-no-exceptions + // <list> // Operations on "NULL" iterators -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) do { if (!x) throw 1; } while(0) #include <list> @@ -25,7 +27,6 @@ struct S { int val; }; int main() { -#if _LIBCPP_STD_VER > 11 { unsigned lib_asserts; @@ -33,7 +34,7 @@ int main() typedef std::list<T> C; C::iterator i{}; C::const_iterator ci{}; - + lib_asserts = 0; try { ++i; } catch (int) { ++lib_asserts; } try { i++; } catch (int) { ++lib_asserts; } @@ -55,13 +56,4 @@ int main() try { (void) ci->val; } catch (int) { ++lib_asserts; } assert(lib_asserts == 4); } -#endif } - -#else - -int main() -{ -} - -#endif diff --git a/test/libcxx/containers/sequences/list/list.cons/db_copy.pass.cpp b/test/libcxx/containers/sequences/list/list.cons/db_copy.pass.cpp new file mode 100644 index 0000000000000..c84960f37686f --- /dev/null +++ b/test/libcxx/containers/sequences/list/list.cons/db_copy.pass.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. +// +//===----------------------------------------------------------------------===// + +// <list> + +// list(list&& c); + +#define _LIBCPP_DEBUG 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <list> +#include <cstdlib> +#include <cassert> + +int main() +{ + std::list<int> l1; + l1.push_back(1); l1.push_back(2); l1.push_back(3); + std::list<int>::iterator i = l1.begin(); + std::list<int> l2 = l1; + l2.erase(i); + assert(false); +} diff --git a/test/libcxx/containers/sequences/list/list.cons/db_move.pass.cpp b/test/libcxx/containers/sequences/list/list.cons/db_move.pass.cpp new file mode 100644 index 0000000000000..dd424e89e7568 --- /dev/null +++ b/test/libcxx/containers/sequences/list/list.cons/db_move.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <list> + +// list(list&& c); + +#define _LIBCPP_DEBUG 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(1)) + +#include <list> +#include <cstdlib> +#include <cassert> +#include "MoveOnly.h" +#include "test_allocator.h" +#include "min_allocator.h" + +int main() +{ + std::list<int> l1 = {1, 2, 3}; + std::list<int>::iterator i = l1.begin(); + std::list<int> l2 = std::move(l1); + assert(*l2.erase(i) == 2); +} diff --git a/test/libcxx/containers/sequences/list/list.modifiers/emplace_db1.pass.cpp b/test/libcxx/containers/sequences/list/list.modifiers/emplace_db1.pass.cpp new file mode 100644 index 0000000000000..1d64f9bd9e275 --- /dev/null +++ b/test/libcxx/containers/sequences/list/list.modifiers/emplace_db1.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <list> + +// template <class... Args> void emplace(const_iterator p, Args&&... args); + +#define _LIBCPP_DEBUG 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <list> +#include <cstdlib> +#include <cassert> + +class A +{ + int i_; + double d_; + + A(const A&); + A& operator=(const A&); +public: + A(int i, double d) + : i_(i), d_(d) {} + + int geti() const {return i_;} + double getd() const {return d_;} +}; + +int main() +{ + std::list<A> c1; + std::list<A> c2; + std::list<A>::iterator i = c1.emplace(c2.cbegin(), 2, 3.5); + assert(false); +} diff --git a/test/std/containers/sequences/list/list.modifiers/erase_iter_db1.pass.cpp b/test/libcxx/containers/sequences/list/list.modifiers/erase_iter_db1.pass.cpp index 18c15eb02c85b..ec5de0264cb47 100644 --- a/test/std/containers/sequences/list/list.modifiers/erase_iter_db1.pass.cpp +++ b/test/libcxx/containers/sequences/list/list.modifiers/erase_iter_db1.pass.cpp @@ -11,41 +11,18 @@ // Call erase(const_iterator position) with end() -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) #include <list> #include <cassert> #include <cstdlib> -#include <exception> - -#include "min_allocator.h" int main() { - { int a1[] = {1, 2, 3}; std::list<int> l1(a1, a1+3); std::list<int>::const_iterator i = l1.end(); l1.erase(i); assert(false); - } -#if __cplusplus >= 201103L - { - int a1[] = {1, 2, 3}; - std::list<int, min_allocator<int>> l1(a1, a1+3); - std::list<int, min_allocator<int>>::const_iterator i = l1.end(); - l1.erase(i); - assert(false); - } -#endif } - -#else - -int main() -{ -} - -#endif diff --git a/test/std/containers/sequences/list/list.modifiers/erase_iter_db2.pass.cpp b/test/libcxx/containers/sequences/list/list.modifiers/erase_iter_db2.pass.cpp index 61ff8409c964f..833e2b54dfaf1 100644 --- a/test/std/containers/sequences/list/list.modifiers/erase_iter_db2.pass.cpp +++ b/test/libcxx/containers/sequences/list/list.modifiers/erase_iter_db2.pass.cpp @@ -11,43 +11,19 @@ // Call erase(const_iterator position) with iterator from another container -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) #include <list> #include <cassert> #include <cstdlib> -#include <exception> - -#include "min_allocator.h" int main() { - { int a1[] = {1, 2, 3}; std::list<int> l1(a1, a1+3); std::list<int> l2(a1, a1+3); std::list<int>::const_iterator i = l2.begin(); l1.erase(i); assert(false); - } -#if __cplusplus >= 201103L - { - int a1[] = {1, 2, 3}; - std::list<int, min_allocator<int>> l1(a1, a1+3); - std::list<int, min_allocator<int>> l2(a1, a1+3); - std::list<int, min_allocator<int>>::const_iterator i = l2.begin(); - l1.erase(i); - assert(false); - } -#endif } - -#else - -int main() -{ -} - -#endif diff --git a/test/std/containers/sequences/list/list.modifiers/erase_iter_iter_db1.pass.cpp b/test/libcxx/containers/sequences/list/list.modifiers/erase_iter_iter_db1.pass.cpp index 71ad497e7d97d..eef7a98e739a9 100644 --- a/test/std/containers/sequences/list/list.modifiers/erase_iter_iter_db1.pass.cpp +++ b/test/libcxx/containers/sequences/list/list.modifiers/erase_iter_iter_db1.pass.cpp @@ -11,41 +11,19 @@ // Call erase(const_iterator first, const_iterator last); with first iterator from another container -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) #include <list> #include <cassert> -#include <exception> #include <cstdlib> -#include "min_allocator.h" - int main() { - { int a1[] = {1, 2, 3}; std::list<int> l1(a1, a1+3); std::list<int> l2(a1, a1+3); std::list<int>::iterator i = l1.erase(l2.cbegin(), next(l1.cbegin())); assert(false); - } -#if __cplusplus >= 201103L - { - int a1[] = {1, 2, 3}; - std::list<int, min_allocator<int>> l1(a1, a1+3); - std::list<int, min_allocator<int>> l2(a1, a1+3); - std::list<int, min_allocator<int>>::iterator i = l1.erase(l2.cbegin(), next(l1.cbegin())); - assert(false); - } -#endif -} - -#else - -int main() -{ } -#endif diff --git a/test/std/containers/sequences/list/list.modifiers/erase_iter_iter_db2.pass.cpp b/test/libcxx/containers/sequences/list/list.modifiers/erase_iter_iter_db2.pass.cpp index db76b4de4865a..0dd03dc50da1b 100644 --- a/test/std/containers/sequences/list/list.modifiers/erase_iter_iter_db2.pass.cpp +++ b/test/libcxx/containers/sequences/list/list.modifiers/erase_iter_iter_db2.pass.cpp @@ -11,41 +11,18 @@ // Call erase(const_iterator first, const_iterator last); with second iterator from another container -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) #include <list> #include <cassert> -#include <exception> #include <cstdlib> -#include "min_allocator.h" - int main() { - { int a1[] = {1, 2, 3}; std::list<int> l1(a1, a1+3); std::list<int> l2(a1, a1+3); std::list<int>::iterator i = l1.erase(l1.cbegin(), next(l2.cbegin())); assert(false); - } -#if __cplusplus >= 201103L - { - int a1[] = {1, 2, 3}; - std::list<int, min_allocator<int>> l1(a1, a1+3); - std::list<int, min_allocator<int>> l2(a1, a1+3); - std::list<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l2.cbegin())); - assert(false); - } -#endif -} - -#else - -int main() -{ } - -#endif diff --git a/test/std/containers/sequences/list/list.modifiers/erase_iter_iter_db3.pass.cpp b/test/libcxx/containers/sequences/list/list.modifiers/erase_iter_iter_db3.pass.cpp index 25c5c6147a01b..22273a89f1e55 100644 --- a/test/std/containers/sequences/list/list.modifiers/erase_iter_iter_db3.pass.cpp +++ b/test/libcxx/containers/sequences/list/list.modifiers/erase_iter_iter_db3.pass.cpp @@ -11,41 +11,18 @@ // Call erase(const_iterator first, const_iterator last); with both iterators from another container -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) #include <list> #include <cassert> -#include <exception> #include <cstdlib> -#include "min_allocator.h" - int main() { - { int a1[] = {1, 2, 3}; std::list<int> l1(a1, a1+3); std::list<int> l2(a1, a1+3); std::list<int>::iterator i = l1.erase(l2.cbegin(), next(l2.cbegin())); assert(false); - } -#if __cplusplus >= 201103L - { - int a1[] = {1, 2, 3}; - std::list<int, min_allocator<int>> l1(a1, a1+3); - std::list<int, min_allocator<int>> l2(a1, a1+3); - std::list<int, min_allocator<int>>::iterator i = l1.erase(l2.cbegin(), next(l2.cbegin())); - assert(false); - } -#endif -} - -#else - -int main() -{ } - -#endif diff --git a/test/std/containers/sequences/list/list.modifiers/erase_iter_iter_db4.pass.cpp b/test/libcxx/containers/sequences/list/list.modifiers/erase_iter_iter_db4.pass.cpp index 35a4ceb4848a7..d1e03c8ac7109 100644 --- a/test/std/containers/sequences/list/list.modifiers/erase_iter_iter_db4.pass.cpp +++ b/test/libcxx/containers/sequences/list/list.modifiers/erase_iter_iter_db4.pass.cpp @@ -11,39 +11,17 @@ // Call erase(const_iterator first, const_iterator last); with a bad range -#if _LIBCPP_DEBUG >= 1 - +#define _LIBCPP_DEBUG 1 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) #include <list> #include <cassert> -#include <exception> #include <cstdlib> -#include "min_allocator.h" - int main() { - { int a1[] = {1, 2, 3}; std::list<int> l1(a1, a1+3); std::list<int>::iterator i = l1.erase(next(l1.cbegin()), l1.cbegin()); assert(false); - } -#if __cplusplus >= 201103L - { - int a1[] = {1, 2, 3}; - std::list<int, min_allocator<int>> l1(a1, a1+3); - std::list<int, min_allocator<int>>::iterator i = l1.erase(next(l1.cbegin()), l1.cbegin()); - assert(false); - } -#endif -} - -#else - -int main() -{ } - -#endif diff --git a/test/libcxx/containers/sequences/list/list.modifiers/insert_iter_iter_iter_db1.pass.cpp b/test/libcxx/containers/sequences/list/list.modifiers/insert_iter_iter_iter_db1.pass.cpp new file mode 100644 index 0000000000000..7fadb14affdda --- /dev/null +++ b/test/libcxx/containers/sequences/list/list.modifiers/insert_iter_iter_iter_db1.pass.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. +// +//===----------------------------------------------------------------------===// + +// <list> + +// template <InputIterator Iter> +// iterator insert(const_iterator position, Iter first, Iter last); + + +#define _LIBCPP_DEBUG 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <list> +#include <cstdlib> +#include <cassert> +#include "test_iterators.h" + +int main() +{ + { + std::list<int> v(100); + std::list<int> v2(100); + int a[] = {1, 2, 3, 4, 5}; + const int N = sizeof(a)/sizeof(a[0]); + std::list<int>::iterator i = v.insert(next(v2.cbegin(), 10), + input_iterator<const int*>(a), + input_iterator<const int*>(a+N)); + assert(false); + } +} diff --git a/test/libcxx/containers/sequences/list/list.modifiers/insert_iter_rvalue_db1.pass.cpp b/test/libcxx/containers/sequences/list/list.modifiers/insert_iter_rvalue_db1.pass.cpp new file mode 100644 index 0000000000000..0d0fd100fc91b --- /dev/null +++ b/test/libcxx/containers/sequences/list/list.modifiers/insert_iter_rvalue_db1.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <list> + +// iterator insert(const_iterator position, value_type&& x); + +#define _LIBCPP_DEBUG 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <list> +#include <cstdlib> +#include <cassert> + +int main() +{ + std::list<int> v1(3); + std::list<int> v2(3); + v1.insert(v2.begin(), 4); + assert(false); +}
\ No newline at end of file diff --git a/test/libcxx/containers/sequences/list/list.modifiers/insert_iter_size_value_db1.pass.cpp b/test/libcxx/containers/sequences/list/list.modifiers/insert_iter_size_value_db1.pass.cpp new file mode 100644 index 0000000000000..4fdfbfa50cbbb --- /dev/null +++ b/test/libcxx/containers/sequences/list/list.modifiers/insert_iter_size_value_db1.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <list> + +// iterator insert(const_iterator position, size_type n, const value_type& x); + +#define _LIBCPP_DEBUG 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <list> +#include <cstdlib> +#include <cassert> + +int main() +{ + std::list<int> c1(100); + std::list<int> c2; + std::list<int>::iterator i = c1.insert(next(c2.cbegin(), 10), 5, 1); + assert(false); +} diff --git a/test/libcxx/containers/sequences/list/list.modifiers/insert_iter_value_db1.pass.cpp b/test/libcxx/containers/sequences/list/list.modifiers/insert_iter_value_db1.pass.cpp new file mode 100644 index 0000000000000..9a13520b98eb2 --- /dev/null +++ b/test/libcxx/containers/sequences/list/list.modifiers/insert_iter_value_db1.pass.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. +// +//===----------------------------------------------------------------------===// + +// <list> + +// iterator insert(const_iterator position, const value_type& x); + +#define _LIBCPP_DEBUG 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <list> +#include <cstdlib> +#include <cassert> + + +int main() +{ + std::list<int> v1(3); + std::list<int> v2(3); + int i = 4; + v1.insert(v2.begin(), i); + assert(false); +} diff --git a/test/libcxx/containers/sequences/list/list.modifiers/pop_back_db1.pass.cpp b/test/libcxx/containers/sequences/list/list.modifiers/pop_back_db1.pass.cpp new file mode 100644 index 0000000000000..795e66d9702a8 --- /dev/null +++ b/test/libcxx/containers/sequences/list/list.modifiers/pop_back_db1.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <list> + +// void pop_back(); + +#define _LIBCPP_DEBUG 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <list> +#include <cstdlib> +#include <cassert> + +int main() +{ + int a[] = {1, 2, 3}; + std::list<int> c(a, a+3); + c.pop_back(); + assert(c == std::list<int>(a, a+2)); + c.pop_back(); + assert(c == std::list<int>(a, a+1)); + c.pop_back(); + assert(c.empty()); + c.pop_back(); // operation under test + assert(false); +} diff --git a/test/libcxx/containers/sequences/list/list.ops/db_splice_pos_list.pass.cpp b/test/libcxx/containers/sequences/list/list.ops/db_splice_pos_list.pass.cpp new file mode 100644 index 0000000000000..7a1180a9b5857 --- /dev/null +++ b/test/libcxx/containers/sequences/list/list.ops/db_splice_pos_list.pass.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. +// +//===----------------------------------------------------------------------===// + +// <list> + +// void splice(const_iterator position, list& x); + +#define _LIBCPP_DEBUG 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <list> +#include <cstdlib> +#include <cassert> + +int main() +{ + { + std::list<int> v1(3); + std::list<int> v2(3); + v1.splice(v2.begin(), v2); + assert(false); + } +} diff --git a/test/libcxx/containers/sequences/list/list.ops/db_splice_pos_list_iter.pass.cpp b/test/libcxx/containers/sequences/list/list.ops/db_splice_pos_list_iter.pass.cpp new file mode 100644 index 0000000000000..fa5243e322bfd --- /dev/null +++ b/test/libcxx/containers/sequences/list/list.ops/db_splice_pos_list_iter.pass.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. +// +//===----------------------------------------------------------------------===// + +// <list> + +// void splice(const_iterator position, list<T,Allocator>& x, iterator i); + +#define _LIBCPP_DEBUG 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <list> +#include <cstdlib> +#include <cassert> + +int main() +{ + { + std::list<int> v1(3); + std::list<int> v2(3); + v1.splice(v1.begin(), v2, v1.begin()); + assert(false); + } +} diff --git a/test/libcxx/containers/sequences/list/list.ops/db_splice_pos_list_iter_iter.pass.cpp b/test/libcxx/containers/sequences/list/list.ops/db_splice_pos_list_iter_iter.pass.cpp new file mode 100644 index 0000000000000..a385b4cf7afa4 --- /dev/null +++ b/test/libcxx/containers/sequences/list/list.ops/db_splice_pos_list_iter_iter.pass.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. +// +//===----------------------------------------------------------------------===// + +// <list> + +// void splice(const_iterator position, list& x, iterator first, iterator last); + +#define _LIBCPP_DEBUG 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <list> +#include <cstdlib> +#include <cassert> + +int main() +{ + { + std::list<int> v1(3); + std::list<int> v2(3); + v1.splice(v1.begin(), v2, v2.begin(), v1.end()); + assert(false); + } +} diff --git a/test/libcxx/containers/sequences/list/list.special/db_swap_1.pass.cpp b/test/libcxx/containers/sequences/list/list.special/db_swap_1.pass.cpp new file mode 100644 index 0000000000000..900f338c29eb4 --- /dev/null +++ b/test/libcxx/containers/sequences/list/list.special/db_swap_1.pass.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. +// +//===----------------------------------------------------------------------===// + +// <list> + +// template <class T, class Alloc> +// void swap(list<T,Alloc>& x, list<T,Alloc>& y); + +#define _LIBCPP_DEBUG 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <list> +#include <cstdlib> +#include <cassert> + +int main() +{ + int a1[] = {1, 3, 7, 9, 10}; + int a2[] = {0, 2, 4, 5, 6, 8, 11}; + std::list<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0])); + std::list<int> c2(a2, a2+sizeof(a2)/sizeof(a2[0])); + std::list<int>::iterator i1 = c1.begin(); + std::list<int>::iterator i2 = c2.begin(); + swap(c1, c2); + c1.erase(i2); + c2.erase(i1); + std::list<int>::iterator j = i1; + c1.erase(i1); // called with iterator not refering to list. + assert(false); +} diff --git a/test/libcxx/containers/sequences/list/list.special/db_swap_2.pass.cpp b/test/libcxx/containers/sequences/list/list.special/db_swap_2.pass.cpp new file mode 100644 index 0000000000000..ace9a713aae78 --- /dev/null +++ b/test/libcxx/containers/sequences/list/list.special/db_swap_2.pass.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. +// +//===----------------------------------------------------------------------===// + +// <list> + +// template <class T, class Alloc> +// void swap(list<T,Alloc>& x, list<T,Alloc>& y); + + +#define _LIBCPP_DEBUG 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include <list> +#include <cassert> +#include "test_allocator.h" +#include "min_allocator.h" + +int main() +{ + // allocators do not compare equal + { + int a1[] = {1, 3, 7, 9, 10}; + int a2[] = {0, 2, 4, 5, 6, 8, 11}; + typedef test_allocator<int> A; + std::list<int, A> c1(a1, a1+sizeof(a1)/sizeof(a1[0]), A(1)); + std::list<int, A> c2(a2, a2+sizeof(a2)/sizeof(a2[0]), A(2)); + swap(c1, c2); + assert(false); + } +} diff --git a/test/std/containers/sequences/list/version.pass.cpp b/test/libcxx/containers/sequences/list/version.pass.cpp index 097c013f52cb8..097c013f52cb8 100644 --- a/test/std/containers/sequences/list/version.pass.cpp +++ b/test/libcxx/containers/sequences/list/version.pass.cpp diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/libcxx/containers/sequences/vector/const_value_type.pass.cpp index e16e439dec4dc..2a150f7cce542 100644 --- a/test/std/containers/sequences/vector/const_value_type.pass.cpp +++ b/test/libcxx/containers/sequences/vector/const_value_type.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <vector> // vector<const int> v; // an extension @@ -16,7 +18,5 @@ int main() { -#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS std::vector<const int> v = {1, 2, 3}; -#endif } diff --git a/test/std/containers/sequences/vector/db_back.pass.cpp b/test/libcxx/containers/sequences/vector/db_back.pass.cpp index 05f3d07712eb5..05f3d07712eb5 100644 --- a/test/std/containers/sequences/vector/db_back.pass.cpp +++ b/test/libcxx/containers/sequences/vector/db_back.pass.cpp diff --git a/test/std/containers/sequences/vector/db_cback.pass.cpp b/test/libcxx/containers/sequences/vector/db_cback.pass.cpp index 5eb1a353e8b04..5eb1a353e8b04 100644 --- a/test/std/containers/sequences/vector/db_cback.pass.cpp +++ b/test/libcxx/containers/sequences/vector/db_cback.pass.cpp diff --git a/test/std/containers/sequences/vector/db_cfront.pass.cpp b/test/libcxx/containers/sequences/vector/db_cfront.pass.cpp index 5e54da1d444e9..5e54da1d444e9 100644 --- a/test/std/containers/sequences/vector/db_cfront.pass.cpp +++ b/test/libcxx/containers/sequences/vector/db_cfront.pass.cpp diff --git a/test/std/containers/sequences/vector/db_cindex.pass.cpp b/test/libcxx/containers/sequences/vector/db_cindex.pass.cpp index 133aa56528245..133aa56528245 100644 --- a/test/std/containers/sequences/vector/db_cindex.pass.cpp +++ b/test/libcxx/containers/sequences/vector/db_cindex.pass.cpp diff --git a/test/std/containers/sequences/vector/db_front.pass.cpp b/test/libcxx/containers/sequences/vector/db_front.pass.cpp index 388058fb31593..388058fb31593 100644 --- a/test/std/containers/sequences/vector/db_front.pass.cpp +++ b/test/libcxx/containers/sequences/vector/db_front.pass.cpp diff --git a/test/std/containers/sequences/vector/db_index.pass.cpp b/test/libcxx/containers/sequences/vector/db_index.pass.cpp index 1daf076da67c1..1daf076da67c1 100644 --- a/test/std/containers/sequences/vector/db_index.pass.cpp +++ b/test/libcxx/containers/sequences/vector/db_index.pass.cpp diff --git a/test/std/containers/sequences/vector/db_iterators_2.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_2.pass.cpp index 2d43843067b75..2d43843067b75 100644 --- a/test/std/containers/sequences/vector/db_iterators_2.pass.cpp +++ b/test/libcxx/containers/sequences/vector/db_iterators_2.pass.cpp diff --git a/test/std/containers/sequences/vector/db_iterators_3.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_3.pass.cpp index 051d66c33394d..051d66c33394d 100644 --- a/test/std/containers/sequences/vector/db_iterators_3.pass.cpp +++ b/test/libcxx/containers/sequences/vector/db_iterators_3.pass.cpp diff --git a/test/std/containers/sequences/vector/db_iterators_4.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_4.pass.cpp index 4c2aa628de143..4c2aa628de143 100644 --- a/test/std/containers/sequences/vector/db_iterators_4.pass.cpp +++ b/test/libcxx/containers/sequences/vector/db_iterators_4.pass.cpp diff --git a/test/std/containers/sequences/vector/db_iterators_5.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_5.pass.cpp index 1b1090499c276..1b1090499c276 100644 --- a/test/std/containers/sequences/vector/db_iterators_5.pass.cpp +++ b/test/libcxx/containers/sequences/vector/db_iterators_5.pass.cpp diff --git a/test/std/containers/sequences/vector/db_iterators_6.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_6.pass.cpp index 424bc939b1366..424bc939b1366 100644 --- a/test/std/containers/sequences/vector/db_iterators_6.pass.cpp +++ b/test/libcxx/containers/sequences/vector/db_iterators_6.pass.cpp diff --git a/test/std/containers/sequences/vector/db_iterators_7.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_7.pass.cpp index 72cdb10cbc855..72cdb10cbc855 100644 --- a/test/std/containers/sequences/vector/db_iterators_7.pass.cpp +++ b/test/libcxx/containers/sequences/vector/db_iterators_7.pass.cpp diff --git a/test/std/containers/sequences/vector/db_iterators_8.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_8.pass.cpp index 7b898533197c6..7b898533197c6 100644 --- a/test/std/containers/sequences/vector/db_iterators_8.pass.cpp +++ b/test/libcxx/containers/sequences/vector/db_iterators_8.pass.cpp diff --git a/test/std/containers/sequences/vector/version.pass.cpp b/test/libcxx/containers/sequences/vector/version.pass.cpp index 2c4fa1263de31..2c4fa1263de31 100644 --- a/test/std/containers/sequences/vector/version.pass.cpp +++ b/test/libcxx/containers/sequences/vector/version.pass.cpp diff --git a/test/libcxx/containers/unord/key_value_traits.pass.cpp b/test/libcxx/containers/unord/key_value_traits.pass.cpp new file mode 100644 index 0000000000000..a6d1ea7a527cc --- /dev/null +++ b/test/libcxx/containers/unord/key_value_traits.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// 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 <__hash_table> +#include <unordered_map> +#include <unordered_set> +#include <type_traits> + +#include "test_macros.h" +#include "min_allocator.h" + +void testKeyValueTrait() { + { + typedef int Tp; + typedef std::__hash_key_value_types<Tp> Traits; + static_assert((std::is_same<Traits::key_type, int>::value), ""); + static_assert((std::is_same<Traits::__node_value_type, Tp>::value), ""); + static_assert((std::is_same<Traits::__container_value_type, Tp>::value), ""); + static_assert(Traits::__is_map == false, ""); + } + { + typedef std::pair<int, int> Tp; + typedef std::__hash_key_value_types<Tp> Traits; + static_assert((std::is_same<Traits::key_type, Tp>::value), ""); + static_assert((std::is_same<Traits::__node_value_type, Tp>::value), ""); + static_assert((std::is_same<Traits::__container_value_type, Tp>::value), ""); + static_assert(Traits::__is_map == false, ""); + } + { + typedef std::pair<const int, int> Tp; + typedef std::__hash_key_value_types<Tp> Traits; + static_assert((std::is_same<Traits::key_type, Tp>::value), ""); + static_assert((std::is_same<Traits::__node_value_type, Tp>::value), ""); + static_assert((std::is_same<Traits::__container_value_type, Tp>::value), ""); + static_assert(Traits::__is_map == false, ""); + } + { + typedef std::__hash_value_type<int, int> Tp; + typedef std::__hash_key_value_types<Tp> Traits; + static_assert((std::is_same<Traits::key_type, int>::value), ""); + static_assert((std::is_same<Traits::mapped_type, int>::value), ""); + static_assert((std::is_same<Traits::__node_value_type, Tp>::value), ""); + static_assert((std::is_same<Traits::__container_value_type, + std::pair<const int, int> >::value), ""); + static_assert((std::is_same<Traits::__map_value_type, + std::pair<const int, int> >::value), ""); + static_assert(Traits::__is_map == true, ""); + } +} + +int main() { + testKeyValueTrait(); +} diff --git a/test/std/containers/unord/next_prime.pass.cpp b/test/libcxx/containers/unord/next_prime.pass.cpp index 266d7f1f9d1ea..266d7f1f9d1ea 100644 --- a/test/std/containers/unord/next_prime.pass.cpp +++ b/test/libcxx/containers/unord/next_prime.pass.cpp diff --git a/test/std/containers/unord/unord.map/db_iterators_7.pass.cpp b/test/libcxx/containers/unord/unord.map/db_iterators_7.pass.cpp index b8db0a35ffc3e..b8db0a35ffc3e 100644 --- a/test/std/containers/unord/unord.map/db_iterators_7.pass.cpp +++ b/test/libcxx/containers/unord/unord.map/db_iterators_7.pass.cpp diff --git a/test/std/containers/unord/unord.map/db_iterators_8.pass.cpp b/test/libcxx/containers/unord/unord.map/db_iterators_8.pass.cpp index c923dd77862e6..c923dd77862e6 100644 --- a/test/std/containers/unord/unord.map/db_iterators_8.pass.cpp +++ b/test/libcxx/containers/unord/unord.map/db_iterators_8.pass.cpp diff --git a/test/std/containers/unord/unord.map/db_local_iterators_7.pass.cpp b/test/libcxx/containers/unord/unord.map/db_local_iterators_7.pass.cpp index fa1886bfff189..fa1886bfff189 100644 --- a/test/std/containers/unord/unord.map/db_local_iterators_7.pass.cpp +++ b/test/libcxx/containers/unord/unord.map/db_local_iterators_7.pass.cpp diff --git a/test/std/containers/unord/unord.map/db_local_iterators_8.pass.cpp b/test/libcxx/containers/unord/unord.map/db_local_iterators_8.pass.cpp index 4b071cad7b473..4b071cad7b473 100644 --- a/test/std/containers/unord/unord.map/db_local_iterators_8.pass.cpp +++ b/test/libcxx/containers/unord/unord.map/db_local_iterators_8.pass.cpp diff --git a/test/std/containers/unord/unord.map/version.pass.cpp b/test/libcxx/containers/unord/unord.map/version.pass.cpp index fc47a326c571e..fc47a326c571e 100644 --- a/test/std/containers/unord/unord.map/version.pass.cpp +++ b/test/libcxx/containers/unord/unord.map/version.pass.cpp 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 deleted file mode 100644 index 76ceafed22088..0000000000000 --- a/test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp +++ /dev/null @@ -1,48 +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. -// -//===----------------------------------------------------------------------===// - -// 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/std/containers/unord/unord.set/version.pass.cpp b/test/libcxx/containers/unord/unord.set/version.pass.cpp index d651ebdfc456e..d651ebdfc456e 100644 --- a/test/std/containers/unord/unord.set/version.pass.cpp +++ b/test/libcxx/containers/unord/unord.set/version.pass.cpp diff --git a/test/std/depr/depr.c.headers/extern_c.pass.cpp b/test/libcxx/depr/depr.c.headers/extern_c.pass.cpp index d4d8b5fafdde0..d4d8b5fafdde0 100644 --- a/test/std/depr/depr.c.headers/extern_c.pass.cpp +++ b/test/libcxx/depr/depr.c.headers/extern_c.pass.cpp diff --git a/test/std/depr/depr.str.strstreams/version.pass.cpp b/test/libcxx/depr/depr.str.strstreams/version.pass.cpp index f27665f15bcd7..f27665f15bcd7 100644 --- a/test/std/depr/depr.str.strstreams/version.pass.cpp +++ b/test/libcxx/depr/depr.str.strstreams/version.pass.cpp diff --git a/test/libcxx/diagnostics/assertions/version_cassert.pass.cpp b/test/libcxx/diagnostics/assertions/version_cassert.pass.cpp new file mode 100644 index 0000000000000..f123a05256ec2 --- /dev/null +++ b/test/libcxx/diagnostics/assertions/version_cassert.pass.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// 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 <cassert> + +#include <cassert> + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() +{ +} diff --git a/test/libcxx/diagnostics/errno/version_cerrno.pass.cpp b/test/libcxx/diagnostics/errno/version_cerrno.pass.cpp new file mode 100644 index 0000000000000..7cd2be8efa92c --- /dev/null +++ b/test/libcxx/diagnostics/errno/version_cerrno.pass.cpp @@ -0,0 +1,19 @@ +// -*- 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. +// +//===----------------------------------------------------------------------===// + +// test <cerrno> + +#include <cerrno> + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() {} diff --git a/test/std/diagnostics/std.exceptions/version.pass.cpp b/test/libcxx/diagnostics/std.exceptions/version.pass.cpp index d9ab009a4365f..d9ab009a4365f 100644 --- a/test/std/diagnostics/std.exceptions/version.pass.cpp +++ b/test/libcxx/diagnostics/std.exceptions/version.pass.cpp diff --git a/test/std/diagnostics/syserr/version.pass.cpp b/test/libcxx/diagnostics/syserr/version.pass.cpp index 3851150fdf908..3851150fdf908 100644 --- a/test/std/diagnostics/syserr/version.pass.cpp +++ b/test/libcxx/diagnostics/syserr/version.pass.cpp diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp index d274bc030881e..c6a83cc61bdcb 100644 --- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp +++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // dynarray.cons // template <class Alloc> @@ -20,10 +21,8 @@ // ~dynarray(); - -#include <__config> -#if _LIBCPP_STD_VER > 11 +#include <__config> #include <experimental/dynarray> #include <cassert> @@ -44,7 +43,7 @@ void check_allocator ( const dynarray<T> &dyn, const Allocator &alloc ) { template <class T, class Allocator> void test ( const std::initializer_list<T> &vals, const Allocator &alloc ) { typedef dynarray<T> dynA; - + dynA d1 ( vals, alloc ); assert ( d1.size () == vals.size() ); assert ( std::equal ( vals.begin (), vals.end (), d1.begin (), d1.end ())); @@ -55,7 +54,7 @@ void test ( const std::initializer_list<T> &vals, const Allocator &alloc ) { template <class T, class Allocator> void test ( const T &val, const Allocator &alloc1, const Allocator &alloc2 ) { typedef dynarray<T> dynA; - + dynA d1 ( 4, alloc1 ); assert ( d1.size () == 4 ); assert ( std::all_of ( d1.begin (), d1.end (), []( const T &item ){ return item == T(); } )); @@ -68,19 +67,17 @@ void test ( const T &val, const Allocator &alloc1, const Allocator &alloc2 ) { dynA d3 ( d2, alloc2 ); assert ( d3.size () == 7 ); - assert ( std::all_of ( d3.begin (), d3.end (), [&val]( const T &item ){ return item == val; } )); + assert ( std::all_of ( d3.begin (), d3.end (), [&val]( const T &item ){ return item == val; } )); check_allocator ( d3, alloc2 ); } int main() { -// This test is waiting on the resolution of LWG issue #2235 +// This test is waiting on the resolution of LWG issue #2235 // typedef test_allocator<char> Alloc; // typedef std::basic_string<char, std::char_traits<char>, Alloc> nstr; -// +// // test ( nstr("fourteen"), Alloc(3), Alloc(4) ); // test ( { nstr("1"), nstr("1"), nstr("2"), nstr("3"), nstr("5"), nstr("8")}, Alloc(6)); } -#else -int main() {} -#endif + diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp index 738c0c72592e3..cd5c56c7ac51a 100644 --- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp +++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp @@ -35,7 +35,7 @@ using std::experimental::dynarray; template <class T> void testInitList( const std::initializer_list<T> &vals ) { typedef dynarray<T> dynA; - + dynA d1 ( vals ); assert ( d1.size () == vals.size() ); assert ( std::equal ( vals.begin (), vals.end (), d1.begin (), d1.end ())); @@ -45,7 +45,7 @@ void testInitList( const std::initializer_list<T> &vals ) { template <class T> void test ( const T &val, bool DefaultValueIsIndeterminate = false) { typedef dynarray<T> dynA; - + dynA d1 ( 4 ); assert ( d1.size () == 4 ); if (!DefaultValueIsIndeterminate) { @@ -58,7 +58,7 @@ void test ( const T &val, bool DefaultValueIsIndeterminate = false) { dynA d3 ( d2 ); assert ( d3.size () == 7 ); - assert ( std::all_of ( d3.begin (), d3.end (), [&val]( const T &item ){ return item == val; } )); + assert ( std::all_of ( d3.begin (), d3.end (), [&val]( const T &item ){ return item == val; } )); } void test_bad_length () { @@ -76,12 +76,12 @@ int main() test<double> ( 14.0, true ); test<std::complex<double>> ( std::complex<double> ( 14, 0 )); test<std::string> ( "fourteen" ); - + testInitList( { 1, 1, 2, 3, 5, 8 } ); testInitList( { 1., 1., 2., 3., 5., 8. } ); testInitList( { std::string("1"), std::string("1"), std::string("2"), std::string("3"), std::string("5"), std::string("8")} ); - + // Make sure we don't pick up the Allocator version here dynarray<long> d1 ( 20, 3 ); assert ( d1.size() == 20 ); diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp index 1bbd8cde92fe1..84c602925cb49 100644 --- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp +++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp @@ -42,7 +42,7 @@ void dyn_test( dynarray<T> &dyn, bool CheckEquals = true) { } } - + template <class T> void test(const T &val, bool DefaultValueIsIndeterminate = false) { @@ -53,7 +53,7 @@ void test(const T &val, bool DefaultValueIsIndeterminate = false) { dynA d1(4); dyn_test(d1, CheckDefaultValues); dyn_test_const(d1, CheckDefaultValues); - + dynA d2 (7, val); dyn_test ( d2 ); dyn_test_const ( d2 ); diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp index c57887ddaf94c..376c94a6bcd8d 100644 --- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp +++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp @@ -7,15 +7,14 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // dynarray.data // void fill(const T& v); // const T* data() const noexcept; - -#include <__config> -#if _LIBCPP_STD_VER > 11 +#include <__config> #include <experimental/dynarray> #include <cassert> @@ -29,11 +28,11 @@ using std::experimental::dynarray; template <class T> void test ( const T &val ) { typedef dynarray<T> dynA; - + dynA d1 ( 4 ); d1.fill ( val ); - assert ( std::all_of ( d1.begin (), d1.end (), - [&val]( const T &item ){ return item == val; } )); + assert ( std::all_of ( d1.begin (), d1.end (), + [&val]( const T &item ){ return item == val; } )); } int main() @@ -43,6 +42,4 @@ int main() test<std::complex<double>> ( std::complex<double> ( 14, 0 )); test<std::string> ( "fourteen" ); } -#else -int main() {} -#endif + diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp index 8c0d085387166..a6825b68d0f17 100644 --- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp +++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp @@ -7,15 +7,14 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // dynarray.overview // const_reference at(size_type n) const; // reference at(size_type n); - -#include <__config> -#if _LIBCPP_STD_VER > 11 +#include <__config> #include <experimental/dynarray> #include <cassert> @@ -73,7 +72,7 @@ void dyn_test ( dynarray<T> &dyn, const std::initializer_list<T> &vals ) { template <class T> void test ( std::initializer_list<T> vals ) { typedef dynarray<T> dynA; - + dynA d1 ( vals ); dyn_test ( d1, vals ); dyn_test_const ( d1, vals ); @@ -83,13 +82,11 @@ int main() { test ( { 1, 1, 2, 3, 5, 8 } ); test ( { 1., 1., 2., 3., 5., 8. } ); - test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"), + test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"), std::string("5"), std::string("8")} ); test<int> ( {} ); test<std::complex<double>> ( {} ); test<std::string> ( {} ); } -#else -int main() {} -#endif + diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp index 695e1aa9f14ae..fe425b7e8c185 100644 --- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp +++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // dynarray.overview @@ -16,7 +17,7 @@ // iterator end() noexcept; // const_iterator end() const noexcept; // const_iterator cend() const noexcept; -// +// // reverse_iterator rbegin() noexcept; // const_reverse_iterator rbegin() const noexcept; // const_reverse_iterator crbegin() const noexcept; @@ -24,10 +25,8 @@ // const_reverse_iterator rend() const noexcept; // const_reverse_iterator crend() const noexcept; - -#include <__config> -#if _LIBCPP_STD_VER > 11 +#include <__config> #include <experimental/dynarray> #include <cassert> @@ -86,11 +85,11 @@ void dyn_test ( dynarray<T> &dyn ) { template <class T> void test ( const T &val ) { typedef dynarray<T> dynA; - + dynA d1 ( 4 ); dyn_test ( d1 ); dyn_test_const ( d1 ); - + dynA d2 ( 7, val ); dyn_test ( d2 ); dyn_test_const ( d2 ); @@ -103,6 +102,4 @@ int main() test<std::complex<double>> ( std::complex<double> ( 14, 0 )); test<std::string> ( "fourteen" ); } -#else -int main() {} -#endif + diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp index 6d28eef1b0578..95262aab1bdcc 100644 --- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp +++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp @@ -7,16 +7,15 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // dynarray.overview // size_type size() const noexcept; // size_type max_size() const noexcept; -// bool empty() const noexcept; +// bool empty() const noexcept; #include <__config> -#if _LIBCPP_STD_VER > 11 - #include <experimental/dynarray> #include <cassert> @@ -36,7 +35,7 @@ void dyn_test ( const dynarray<T> &dyn, size_t sz ) { template <class T> void test ( std::initializer_list<T> vals ) { typedef dynarray<T> dynA; - + dynA d1 ( vals ); dyn_test ( d1, vals.size ()); } @@ -45,13 +44,11 @@ int main() { test ( { 1, 1, 2, 3, 5, 8 } ); test ( { 1., 1., 2., 3., 5., 8. } ); - test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"), + test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"), std::string("5"), std::string("8")} ); test<int> ( {} ); test<std::complex<double>> ( {} ); test<std::string> ( {} ); } -#else -int main() {} -#endif + diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp index 2af862a5530fb..4f1d0978dd11f 100644 --- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp +++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp @@ -58,7 +58,7 @@ void test ( const T &val, bool DefaultValueIsIndeterminate = false) { dynA d1 ( 4 ); dyn_test ( d1, CheckDefaultValues ); dyn_test_const ( d1, CheckDefaultValues ); - + dynA d2 ( 7, val ); dyn_test ( d2 ); dyn_test_const ( d2 ); diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp index 7317a2023cb1e..4bcb229ebce02 100644 --- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp +++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // dynarray.overview // const_reference at(size_type n) const; // reference at(size_type n); - -#include <__config> -#if _LIBCPP_STD_VER > 11 +#include <__config> #include <experimental/dynarray> #include <cassert> @@ -49,7 +48,7 @@ void dyn_test ( dynarray<T> &dyn, const std::initializer_list<T> &vals ) { template <class T> void test ( std::initializer_list<T> vals ) { typedef dynarray<T> dynA; - + dynA d1 ( vals ); dyn_test ( d1, vals ); dyn_test_const ( d1, vals ); @@ -59,13 +58,11 @@ int main() { test ( { 1, 1, 2, 3, 5, 8 } ); test ( { 1., 1., 2., 3., 5., 8. } ); - test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"), + test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"), std::string("5"), std::string("8")} ); test<int> ( {} ); test<std::complex<double>> ( {} ); test<std::string> ( {} ); } -#else -int main() {} -#endif + diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp index 9b8240d4cd82f..48da6d885773f 100644 --- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp +++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp @@ -7,15 +7,14 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // dynarray.data // template <class Type, class Alloc> // struct uses_allocator<dynarray<Type>, Alloc> : true_type { }; - -#include <__config> -#if _LIBCPP_STD_VER > 11 +#include <__config> #include <experimental/dynarray> #include "test_allocator.h" @@ -26,6 +25,4 @@ int main() { static_assert ( std::uses_allocator<dynarray<int>, test_allocator<int>>::value, "" ); } -#else -int main() {} -#endif + diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp index 93f3b18f192f5..c0e0180930e9b 100644 --- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp +++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp @@ -7,18 +7,17 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // dynarray.zero // dynarray shall provide support for the special case of construction with a size of zero. -// In the case that the size is zero, begin() == end() == unique value. -// The return value of data() is unspecified. +// In the case that the size is zero, begin() == end() == unique value. +// The return value of data() is unspecified. // The effect of calling front() or back() for a zero-sized dynarray is undefined. - -#include <__config> -#if _LIBCPP_STD_VER > 11 +#include <__config> #include <experimental/dynarray> #include <cassert> @@ -32,7 +31,7 @@ using std::experimental::dynarray; template <class T> void test ( ) { typedef dynarray<T> dynA; - + dynA d1 ( 0 ); assert ( d1.size() == 0 ); assert ( d1.begin() == d1.end ()); @@ -45,6 +44,4 @@ int main() test<std::complex<double>> (); test<std::string> (); } -#else -int main() {} -#endif + diff --git a/test/libcxx/experimental/filesystem/class.path/path.req/is_pathable.pass.cpp b/test/libcxx/experimental/filesystem/class.path/path.req/is_pathable.pass.cpp new file mode 100644 index 0000000000000..94de2108f8b59 --- /dev/null +++ b/test/libcxx/experimental/filesystem/class.path/path.req/is_pathable.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 + +// <experimental/filesystem> + +// template <class Tp> struct __is_pathable + +// [path.req] +// In addition to the requirements (5), function template parameters named +// `Source` shall be one of: +// * basic_string<_ECharT, _Traits, _Alloc> +// * InputIterator with a value_type of _ECharT +// * A character array, which points to a NTCTS after array-to-pointer decay. + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "min_allocator.h" + +namespace fs = std::experimental::filesystem; + +using fs::__is_pathable; + +template <class Tp> +struct Identity { typedef Tp type; }; + +template <class Source> +Identity<Source> CheckSourceType(Source const&); + +template <class Tp> +using GetSourceType = typename decltype(CheckSourceType(std::declval<Tp>()))::type; + +template <class Tp, class Exp, + class ExpQual = typename std::remove_const<Exp>::type> +using CheckPass = std::is_same<ExpQual, GetSourceType<Tp>>; + +template <class Source> +using CheckPassSource = std::integral_constant<bool, + CheckPass<Source&, Source>::value && + CheckPass<Source const&, Source>::value && + CheckPass<Source&&, Source>::value && + CheckPass<Source const&&, Source>::value + >; + +template <class CharT> +struct MakeTestType { + using value_type = CharT; + using string_type = std::basic_string<CharT>; + using string_type2 = std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>; + using cstr_type = CharT* const; + using const_cstr_type = const CharT*; + using array_type = CharT[25]; + using const_array_type = const CharT[25]; + using iter_type = input_iterator<CharT*>; + using bad_iter_type = input_iterator<signed char*>; + + template <class TestT> + static void AssertPathable() { + static_assert(__is_pathable<TestT>::value, ""); + static_assert(CheckPassSource<TestT>::value, "cannot pass as Source const&"); + ASSERT_SAME_TYPE(CharT, typename __is_pathable<TestT>::__char_type); + } + + template <class TestT> + static void AssertNotPathable() { + static_assert(!__is_pathable<TestT>::value, ""); + } + + static void Test() { + AssertPathable<string_type>(); + AssertPathable<string_type2>(); + AssertPathable<cstr_type>(); + AssertPathable<const_cstr_type>(); + AssertPathable<array_type>(); + AssertPathable<const_array_type>(); + AssertPathable<iter_type>(); + + AssertNotPathable<CharT>(); + AssertNotPathable<bad_iter_type>(); + AssertNotPathable<signed char*>(); + } +}; + +int main() { + MakeTestType<char>::Test(); + MakeTestType<wchar_t>::Test(); + MakeTestType<char16_t>::Test(); + MakeTestType<char32_t>::Test(); +} diff --git a/test/libcxx/experimental/filesystem/lit.local.cfg b/test/libcxx/experimental/filesystem/lit.local.cfg new file mode 100644 index 0000000000000..3d9360431f486 --- /dev/null +++ b/test/libcxx/experimental/filesystem/lit.local.cfg @@ -0,0 +1,3 @@ +# Disable all of the filesystem tests if the correct feature is not available. +if 'c++filesystem' not in config.available_features: + config.unsupported = True diff --git a/test/libcxx/experimental/filesystem/version.pass.cpp b/test/libcxx/experimental/filesystem/version.pass.cpp new file mode 100644 index 0000000000000..723380a26fbae --- /dev/null +++ b/test/libcxx/experimental/filesystem/version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +#include <experimental/filesystem> + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() +{ +} diff --git a/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp b/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp new file mode 100644 index 0000000000000..83b3041963719 --- /dev/null +++ b/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp @@ -0,0 +1,178 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U1, class U2, class ...Args1, class ...Args2> +// void polymorphic_allocator<T>::construct(pair<T1, T2>*, piecewise_construct_t +// tuple<Args1...> x, tuple<Args2...>) + +// The stardard specifiers a tranformation to uses-allocator construction as +// follows: +// - If uses_allocator_v<T1,memory_resource*> is false and +// is_constructible_v<T,Args1...> is true, then xprime is x. +// - Otherwise, if uses_allocator_v<T1,memory_resource*> is true and +// is_constructible_v<T1,allocator_arg_t,memory_resource*,Args1...> is true, +// then xprime is +// tuple_cat(make_tuple(allocator_arg, this->resource()), std::move(x)). +// - Otherwise, if uses_allocator_v<T1,memory_resource*> is true and +// is_constructible_v<T1,Args1...,memory_resource*> is true, then xprime is +// tuple_cat(std::move(x), make_tuple(this->resource())). +// - Otherwise the program is ill formed. +// +// The use of "xprime = tuple_cat(..., std::move(x), ...)" causes all of the +// objects in 'x' to be copied into 'xprime'. If 'x' contains any types which +// are stored by value this causes an unessary copy to occur. To prevent this +// libc++ changes this call into +// "xprime = forward_as_tuple(..., std::get<Idx>(std::move(x))..., ...)". +// 'xprime' contains references to the values in 'x' instead of copying them. + +// This test checks the number of copies incurred to the elements in +// 'tuple<Args1...>' and 'tuple<Args2...>'. + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +template <class T> +struct TestHarness { + TestResource R; + ex::memory_resource * M = &R; + ex::polymorphic_allocator<T> A = M; + bool constructed = false; + T * ptr; + + TestHarness() : ptr(A.allocate(1)) {} + + template <class ...Args> + void construct(Args&&... args) { + A.construct(ptr, std::forward<Args>(args)...); + constructed = true; + } + + ~TestHarness() { + if (constructed) A.destroy(ptr); + A.deallocate(ptr, 1); + } +}; + +struct CountCopies { + int count; + CountCopies() : count(0) {} + CountCopies(CountCopies const& o) : count(o.count + 1) {} +}; + +struct CountCopiesAllocV1 { + typedef ex::memory_resource* allocator_type; + allocator_type alloc; + int count; + CountCopiesAllocV1() : alloc(nullptr), count(0) {} + CountCopiesAllocV1(std::allocator_arg_t, allocator_type const& a, + CountCopiesAllocV1 const& o) : alloc(a), count(o.count + 1) + {} + + CountCopiesAllocV1(CountCopiesAllocV1 const& o) : count(o.count + 1) {} +}; + + +struct CountCopiesAllocV2 { + typedef ex::memory_resource* allocator_type; + allocator_type alloc; + int count; + CountCopiesAllocV2() : alloc(nullptr), count(0) {} + CountCopiesAllocV2(CountCopiesAllocV2 const& o, allocator_type const& a) + : alloc(a), count(o.count + 1) + { } + + CountCopiesAllocV2(CountCopiesAllocV2 const& o) : count(o.count + 1) {} +}; + + +int main() +{ + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<char>; + + { + using T = CountCopies; + using U = CountCopiesAllocV1; + using P = std::pair<T, U>; + using TH = TestHarness<P>; + + std::tuple<T> t1; + std::tuple<U> t2; + + TestHarness<P> h; + h.construct(std::piecewise_construct, t1, t2); + P const& p = *h.ptr; + assert(p.first.count == 2); + assert(p.second.count == 2); + assert(p.second.alloc == h.M); + } + { + using T = CountCopiesAllocV1; + using U = CountCopiesAllocV2; + using P = std::pair<T, U>; + using TH = TestHarness<P>; + + std::tuple<T> t1; + std::tuple<U> t2; + + TestHarness<P> h; + h.construct(std::piecewise_construct, std::move(t1), std::move(t2)); + P const& p = *h.ptr; + assert(p.first.count == 2); + assert(p.first.alloc == h.M); + assert(p.second.count == 2); + assert(p.second.alloc == h.M); + } + { + using T = CountCopiesAllocV2; + using U = CountCopiesAllocV1; + using P = std::pair<T, U>; + using TH = TestHarness<P>; + + std::tuple<T> t1; + std::tuple<U> t2; + + TestHarness<P> h; + h.construct(std::piecewise_construct, std::move(t1), std::move(t2)); + P const& p = *h.ptr; + assert(p.first.count == 2); + assert(p.first.alloc == h.M); + assert(p.second.count == 2); + assert(p.second.alloc == h.M); + } + { + using T = CountCopiesAllocV2; + using U = CountCopies; + using P = std::pair<T, U>; + using TH = TestHarness<P>; + + std::tuple<T> t1; + std::tuple<U> t2; + + TestHarness<P> h; + h.construct(std::piecewise_construct, t1, t2); + P const& p = *h.ptr; + assert(p.first.count == 2); + assert(p.first.alloc == h.M); + assert(p.second.count == 2); + } +} diff --git a/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/db_deallocate.pass.cpp b/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/db_deallocate.pass.cpp new file mode 100644 index 0000000000000..020133fc40481 --- /dev/null +++ b/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/db_deallocate.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// T* polymorphic_allocator<T>::deallocate(T*, size_t size) + +int AssertCount = 0; + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (void)::AssertCount++) +#define _LIBCPP_DEBUG 0 +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + using Alloc = ex::polymorphic_allocator<int>; + using Traits = std::allocator_traits<Alloc>; + NullResource R; + Alloc a(&R); + const std::size_t maxSize = Traits::max_size(a); + + a.deallocate(nullptr, maxSize); + assert(AssertCount == 0); + a.deallocate(nullptr, maxSize + 1); + assert(AssertCount == 1); +} diff --git a/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/max_size.pass.cpp b/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/max_size.pass.cpp new file mode 100644 index 0000000000000..ac685a99be494 --- /dev/null +++ b/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/max_size.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// EXTENSION +// std::size_t polymorphic_allocator<T>::max_size() const noexcept + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +template <std::size_t S> +std::size_t getMaxSize() { + using T = typename std::aligned_storage<S>::type; + static_assert(sizeof(T) == S, "Required for test"); + return ex::polymorphic_allocator<T>{}.max_size(); +} + +template <std::size_t S, std::size_t A> +std::size_t getMaxSize() { + using T = typename std::aligned_storage<S, A>::type; + static_assert(sizeof(T) == S, "Required for test"); + return ex::polymorphic_allocator<T>{}.max_size(); +} + +int main() +{ + { + using Alloc = ex::polymorphic_allocator<int>; + using Traits = std::allocator_traits<Alloc>; + const Alloc a; + static_assert(std::is_same<decltype(a.max_size()), Traits::size_type>::value, ""); + static_assert(noexcept(a.max_size()), ""); + } + { + constexpr std::size_t Max = std::numeric_limits<std::size_t>::max(); + assert(getMaxSize<1>() == Max); + assert(getMaxSize<2>() == Max / 2); + assert(getMaxSize<4>() == Max / 4); + assert(getMaxSize<8>() == Max / 8); + assert(getMaxSize<16>() == Max / 16); + assert(getMaxSize<32>() == Max / 32); + assert(getMaxSize<64>() == Max / 64); + assert(getMaxSize<1024>() == Max / 1024); + + assert((getMaxSize<6, 2>() == Max / 6)); + assert((getMaxSize<12, 4>() == Max / 12)); + } +} diff --git a/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp b/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp new file mode 100644 index 0000000000000..ccb9b710e5dcd --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.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 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// T* polymorphic_allocator<T>::deallocate(T*, size_t size) + +int AssertCount = 0; + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (void)::AssertCount++) +#define _LIBCPP_DEBUG 0 +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + using Alloc = NullAllocator<char>; + using R = ex::resource_adaptor<Alloc>; + AllocController P; + ex::resource_adaptor<Alloc> r(Alloc{P}); + ex::memory_resource & m1 = r; + + std::size_t maxSize = std::numeric_limits<std::size_t>::max() + - alignof(std::max_align_t); + + m1.deallocate(nullptr, maxSize); + assert(AssertCount == 0); + m1.deallocate(nullptr, maxSize + 1); + assert(AssertCount >= 1); +} diff --git a/test/libcxx/experimental/memory/memory.resource.aliases/header_deque_libcpp_version.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_deque_libcpp_version.pass.cpp new file mode 100644 index 0000000000000..04b361dfe5a43 --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_deque_libcpp_version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/deque> + +#include <experimental/deque> + +#ifndef _LIBCPP_VERSION +#error header must provide _LIBCPP_VERSION +#endif + +int main() +{ +} diff --git a/test/libcxx/experimental/memory/memory.resource.aliases/header_forward_list_libcpp_version.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_forward_list_libcpp_version.pass.cpp new file mode 100644 index 0000000000000..11fc21b3b03cb --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_forward_list_libcpp_version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/forward_list> + +#include <experimental/forward_list> + +#ifndef _LIBCPP_VERSION +#error header must provide _LIBCPP_VERSION +#endif + +int main() +{ +} diff --git a/test/libcxx/experimental/memory/memory.resource.aliases/header_list_libcpp_version.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_list_libcpp_version.pass.cpp new file mode 100644 index 0000000000000..9a72979e0af04 --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_list_libcpp_version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/list> + +#include <experimental/list> + +#ifndef _LIBCPP_VERSION +#error header must provide _LIBCPP_VERSION +#endif + +int main() +{ +} diff --git a/test/libcxx/experimental/memory/memory.resource.aliases/header_map_libcpp_version.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_map_libcpp_version.pass.cpp new file mode 100644 index 0000000000000..24a1bf3042c1a --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_map_libcpp_version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/map> + +#include <experimental/map> + +#ifndef _LIBCPP_VERSION +#error header must provide _LIBCPP_VERSION +#endif + +int main() +{ +} diff --git a/test/libcxx/experimental/memory/memory.resource.aliases/header_regex_libcpp_version.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_regex_libcpp_version.pass.cpp new file mode 100644 index 0000000000000..ff81bc09b850d --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_regex_libcpp_version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/regex> + +#include <experimental/regex> + +#ifndef _LIBCPP_VERSION +#error header must provide _LIBCPP_VERSION +#endif + +int main() +{ +} diff --git a/test/libcxx/experimental/memory/memory.resource.aliases/header_set_libcpp_version.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_set_libcpp_version.pass.cpp new file mode 100644 index 0000000000000..6b02f46b4f73c --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_set_libcpp_version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/set> + +#include <experimental/set> + +#ifndef _LIBCPP_VERSION +#error header must provide _LIBCPP_VERSION +#endif + +int main() +{ +} diff --git a/test/libcxx/experimental/memory/memory.resource.aliases/header_string_libcpp_version.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_string_libcpp_version.pass.cpp new file mode 100644 index 0000000000000..b4b7fdf10f592 --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_string_libcpp_version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/string> + +#include <experimental/string> + +#ifndef _LIBCPP_VERSION +#error header must provide _LIBCPP_VERSION +#endif + +int main() +{ +} diff --git a/test/libcxx/experimental/memory/memory.resource.aliases/header_unordered_map_libcpp_version.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_unordered_map_libcpp_version.pass.cpp new file mode 100644 index 0000000000000..ab9cc189b73d0 --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_unordered_map_libcpp_version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/unordered_map> + +#include <experimental/unordered_map> + +#ifndef _LIBCPP_VERSION +#error header must provide _LIBCPP_VERSION +#endif + +int main() +{ +} diff --git a/test/libcxx/experimental/memory/memory.resource.aliases/header_unordered_set_libcpp_version.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_unordered_set_libcpp_version.pass.cpp new file mode 100644 index 0000000000000..37533c7fd87c4 --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_unordered_set_libcpp_version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/unordered_set> + +#include <experimental/unordered_set> + +#ifndef _LIBCPP_VERSION +#error header must provide _LIBCPP_VERSION +#endif + +int main() +{ +} diff --git a/test/libcxx/experimental/memory/memory.resource.aliases/header_vector_libcpp_version.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_vector_libcpp_version.pass.cpp new file mode 100644 index 0000000000000..103d32becf9c1 --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_vector_libcpp_version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/vector> + +#include <experimental/vector> + +#ifndef _LIBCPP_VERSION +#error header must provide _LIBCPP_VERSION +#endif + +int main() +{ +} diff --git a/test/libcxx/experimental/memory/memory.resource.global/global_memory_resource_lifetime.pass.cpp b/test/libcxx/experimental/memory/memory.resource.global/global_memory_resource_lifetime.pass.cpp new file mode 100644 index 0000000000000..341a88c0bab12 --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.global/global_memory_resource_lifetime.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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// memory_resource * new_delete_resource() + +// The lifetime of the value returned by 'new_delete_resource()' should +// never end, even very late into program termination. This test constructs +// attempts to use 'new_delete_resource()' very late in program termination +// to detect lifetime issues. + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +struct POSType { + ex::memory_resource* res = nullptr; + void* ptr = nullptr; + int n = 0; + POSType() {} + POSType(ex::memory_resource* r, void* p, int s) : res(r), ptr(p), n(s) {} + ~POSType() { + if (ptr) { + if (!res) res = ex::get_default_resource(); + res->deallocate(ptr, n); + } + } +}; + +void swap(POSType & L, POSType & R) { + std::swap(L.res, R.res); + std::swap(L.ptr, R.ptr); + std::swap(L.n, R.n); +} + +POSType constructed_before_resources; +POSType constructed_before_resources2; + +// Constructs resources +ex::memory_resource* resource = ex::get_default_resource(); + +POSType constructed_after_resources(resource, resource->allocate(1024), 1024); +POSType constructed_after_resources2(nullptr, resource->allocate(1024), 1024); + +int main() +{ + swap(constructed_after_resources, constructed_before_resources); + swap(constructed_before_resources2, constructed_after_resources2); +} diff --git a/test/libcxx/experimental/memory/memory.resource.global/new_delete_resource_lifetime.pass.cpp b/test/libcxx/experimental/memory/memory.resource.global/new_delete_resource_lifetime.pass.cpp new file mode 100644 index 0000000000000..9b92d02bc4374 --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.global/new_delete_resource_lifetime.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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// memory_resource * new_delete_resource() + +// The lifetime of the value returned by 'new_delete_resource()' should +// never end, even very late into program termination. This test constructs +// attempts to use 'new_delete_resource()' very late in program termination +// to detect lifetime issues. + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +struct POSType { + ex::memory_resource* res = nullptr; + void* ptr = nullptr; + int n = 0; + POSType() {res = ex::new_delete_resource(); ptr = res->allocate(42); n = 42; } + POSType(ex::memory_resource* r, void* p, int s) : res(r), ptr(p), n(s) {} + ~POSType() { if (ptr) res->deallocate(ptr, n); } +}; + +void swap(POSType & L, POSType & R) { + std::swap(L.res, R.res); + std::swap(L.ptr, R.ptr); + std::swap(L.n, R.n); +} + +POSType constructed_before_resources; + +// Constructs resources +ex::memory_resource* resource = ex::new_delete_resource(); + +POSType constructed_after_resources(resource, resource->allocate(1024), 1024); + +int main() +{ + swap(constructed_after_resources, constructed_before_resources); +} diff --git a/test/libcxx/experimental/memory/memory.resource.synop/version.pass.cpp b/test/libcxx/experimental/memory/memory.resource.synop/version.pass.cpp new file mode 100644 index 0000000000000..d05575e8849e5 --- /dev/null +++ b/test/libcxx/experimental/memory/memory.resource.synop/version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/memory_resource> + +#include <experimental/memory_resource> + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() +{ +} diff --git a/test/std/experimental/optional/version.pass.cpp b/test/libcxx/experimental/optional/version.pass.cpp index 585b7a24eea5a..585b7a24eea5a 100644 --- a/test/std/experimental/optional/version.pass.cpp +++ b/test/libcxx/experimental/optional/version.pass.cpp diff --git a/test/std/experimental/utilities/meta/version.pass.cpp b/test/libcxx/experimental/utilities/meta/version.pass.cpp index 593fb52a4c3b2..593fb52a4c3b2 100644 --- a/test/std/experimental/utilities/meta/version.pass.cpp +++ b/test/libcxx/experimental/utilities/meta/version.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 db9026aebd84f..ea7ef6cbc1088 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 @@ -7,16 +7,15 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/ratio> // Test that <ratio> is included. #include <experimental/ratio> -#if _LIBCPP_STD_VER > 11 -# ifndef _LIBCPP_RATIO -# error " <experimental/ratio> must include <ratio>" -# endif +#ifndef _LIBCPP_RATIO +# error " <experimental/ratio> must include <ratio>" #endif int main() 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 88c7458395d4b..be3aacdc362ca 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 @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/system_error> #include <experimental/system_error> -#if _LIBCPP_STD_VER > 11 -# ifndef _LIBCPP_SYSTEM_ERROR -# error "<experimental/system_error> must include <system_error>" -# endif +#ifndef _LIBCPP_SYSTEM_ERROR +# error "<experimental/system_error> must include <system_error>" #endif int main() diff --git a/test/libcxx/experimental/utilities/time/header.chrono.synop/includes.pass.cpp b/test/libcxx/experimental/utilities/time/header.chrono.synop/includes.pass.cpp index ad4a79105b0b8..e91068c742e18 100644 --- a/test/libcxx/experimental/utilities/time/header.chrono.synop/includes.pass.cpp +++ b/test/libcxx/experimental/utilities/time/header.chrono.synop/includes.pass.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/chrono> #include <experimental/chrono> -#if _LIBCPP_STD_VER > 11 -# ifndef _LIBCPP_CHRONO -# error "<experimental/chrono> must include <chrono>" -# endif +#ifndef _LIBCPP_CHRONO +# error "<experimental/chrono> must include <chrono>" #endif int main() diff --git a/test/libcxx/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp b/test/libcxx/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp index 544ddfb269f2c..defa454d68f75 100644 --- a/test/libcxx/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp +++ b/test/libcxx/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp @@ -7,15 +7,14 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <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 */ +#ifndef _LIBCPP_TUPLE +# error "<experimental/tuple> must include <tuple>" +#endif } diff --git a/test/std/experimental/utilities/utility/version.pass.cpp b/test/libcxx/experimental/utilities/utility/version.pass.cpp index 437712454ae5c..437712454ae5c 100644 --- a/test/std/experimental/utilities/utility/version.pass.cpp +++ b/test/libcxx/experimental/utilities/utility/version.pass.cpp diff --git a/test/std/extensions/hash/specializations.fail.cpp b/test/libcxx/extensions/hash/specializations.fail.cpp index 8eeffb5802e72..8eeffb5802e72 100644 --- a/test/std/extensions/hash/specializations.fail.cpp +++ b/test/libcxx/extensions/hash/specializations.fail.cpp diff --git a/test/std/extensions/hash/specializations.pass.cpp b/test/libcxx/extensions/hash/specializations.pass.cpp index a222b1eb5c6d0..a222b1eb5c6d0 100644 --- a/test/std/extensions/hash/specializations.pass.cpp +++ b/test/libcxx/extensions/hash/specializations.pass.cpp diff --git a/test/std/extensions/hash_map/const_iterator.fail.cpp b/test/libcxx/extensions/hash_map/const_iterator.fail.cpp index e4c536e8f33ab..e4c536e8f33ab 100644 --- a/test/std/extensions/hash_map/const_iterator.fail.cpp +++ b/test/libcxx/extensions/hash_map/const_iterator.fail.cpp diff --git a/test/std/extensions/nothing_to_do.pass.cpp b/test/libcxx/extensions/nothing_to_do.pass.cpp index b58f5c55b643a..b58f5c55b643a 100644 --- a/test/std/extensions/nothing_to_do.pass.cpp +++ b/test/libcxx/extensions/nothing_to_do.pass.cpp diff --git a/test/std/input.output/file.streams/c.files/version_ccstdio.pass.cpp b/test/libcxx/input.output/file.streams/c.files/version_ccstdio.pass.cpp index 0d7fc5605324b..0d7fc5605324b 100644 --- a/test/std/input.output/file.streams/c.files/version_ccstdio.pass.cpp +++ b/test/libcxx/input.output/file.streams/c.files/version_ccstdio.pass.cpp diff --git a/test/std/input.output/file.streams/c.files/version_cinttypes.pass.cpp b/test/libcxx/input.output/file.streams/c.files/version_cinttypes.pass.cpp index bfd379e43493b..bfd379e43493b 100644 --- a/test/std/input.output/file.streams/c.files/version_cinttypes.pass.cpp +++ b/test/libcxx/input.output/file.streams/c.files/version_cinttypes.pass.cpp diff --git a/test/std/input.output/file.streams/fstreams/version.pass.cpp b/test/libcxx/input.output/file.streams/fstreams/version.pass.cpp index 44b851416808c..44b851416808c 100644 --- a/test/std/input.output/file.streams/fstreams/version.pass.cpp +++ b/test/libcxx/input.output/file.streams/fstreams/version.pass.cpp diff --git a/test/std/input.output/iostream.format/input.streams/version.pass.cpp b/test/libcxx/input.output/iostream.format/input.streams/version.pass.cpp index b03ef2aaa04e0..b03ef2aaa04e0 100644 --- a/test/std/input.output/iostream.format/input.streams/version.pass.cpp +++ b/test/libcxx/input.output/iostream.format/input.streams/version.pass.cpp diff --git a/test/std/input.output/iostream.format/output.streams/version.pass.cpp b/test/libcxx/input.output/iostream.format/output.streams/version.pass.cpp index 662b6987b3c81..662b6987b3c81 100644 --- a/test/std/input.output/iostream.format/output.streams/version.pass.cpp +++ b/test/libcxx/input.output/iostream.format/output.streams/version.pass.cpp diff --git a/test/std/input.output/iostream.format/std.manip/version.pass.cpp b/test/libcxx/input.output/iostream.format/std.manip/version.pass.cpp index ca4fd3d463eeb..ca4fd3d463eeb 100644 --- a/test/std/input.output/iostream.format/std.manip/version.pass.cpp +++ b/test/libcxx/input.output/iostream.format/std.manip/version.pass.cpp diff --git a/test/std/input.output/iostream.forward/version.pass.cpp b/test/libcxx/input.output/iostream.forward/version.pass.cpp index cf91332d55977..cf91332d55977 100644 --- a/test/std/input.output/iostream.forward/version.pass.cpp +++ b/test/libcxx/input.output/iostream.forward/version.pass.cpp diff --git a/test/std/input.output/iostream.objects/version.pass.cpp b/test/libcxx/input.output/iostream.objects/version.pass.cpp index 09b3611f6df92..09b3611f6df92 100644 --- a/test/std/input.output/iostream.objects/version.pass.cpp +++ b/test/libcxx/input.output/iostream.objects/version.pass.cpp diff --git a/test/std/input.output/iostreams.base/version.pass.cpp b/test/libcxx/input.output/iostreams.base/version.pass.cpp index f56846d38b8db..f56846d38b8db 100644 --- a/test/std/input.output/iostreams.base/version.pass.cpp +++ b/test/libcxx/input.output/iostreams.base/version.pass.cpp diff --git a/test/std/input.output/stream.buffers/version.pass.cpp b/test/libcxx/input.output/stream.buffers/version.pass.cpp index c4b06be601871..c4b06be601871 100644 --- a/test/std/input.output/stream.buffers/version.pass.cpp +++ b/test/libcxx/input.output/stream.buffers/version.pass.cpp diff --git a/test/std/input.output/string.streams/version.pass.cpp b/test/libcxx/input.output/string.streams/version.pass.cpp index 103897106d37c..103897106d37c 100644 --- a/test/std/input.output/string.streams/version.pass.cpp +++ b/test/libcxx/input.output/string.streams/version.pass.cpp diff --git a/test/libcxx/iterators/trivial_iterators.pass.cpp b/test/libcxx/iterators/trivial_iterators.pass.cpp index 0b7a47316d65f..33c8302517694 100644 --- a/test/libcxx/iterators/trivial_iterators.pass.cpp +++ b/test/libcxx/iterators/trivial_iterators.pass.cpp @@ -13,7 +13,7 @@ // __libcpp_is_trivial_iterator<Tp> // __libcpp_is_trivial_iterator determines if an iterator is a "trivial" one, -// that can be used w/o worrying about its operations throwing exceptions. +// that can be used w/o worrying about its operations throwing exceptions. // Pointers are trivial iterators. Libc++ has three "iterator wrappers": // reverse_iterator, move_iterator, and __wrap_iter. If the underlying iterator // is trivial, then those are as well. @@ -113,16 +113,16 @@ int main() static_assert(( std::__libcpp_is_trivial_iterator<std::__wrap_iter<int *> > ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator<std::__wrap_iter<T *> > ::value), ""); - static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<std::__wrap_iter<char *> > > ::value), ""); - + static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<std::__wrap_iter<char *> > > ::value), ""); + // iterators in the libc++ test suite - static_assert((!std::__libcpp_is_trivial_iterator<output_iterator <char *> >::value), ""); - static_assert((!std::__libcpp_is_trivial_iterator<input_iterator <char *> >::value), ""); - static_assert((!std::__libcpp_is_trivial_iterator<forward_iterator <char *> >::value), ""); - static_assert((!std::__libcpp_is_trivial_iterator<bidirectional_iterator<char *> >::value), ""); - static_assert((!std::__libcpp_is_trivial_iterator<random_access_iterator<char *> >::value), ""); - static_assert((!std::__libcpp_is_trivial_iterator<ThrowingIterator <char *> >::value), ""); - static_assert((!std::__libcpp_is_trivial_iterator<NonThrowingIterator <char *> >::value), ""); + static_assert((!std::__libcpp_is_trivial_iterator<output_iterator <char *> >::value), ""); + static_assert((!std::__libcpp_is_trivial_iterator<input_iterator <char *> >::value), ""); + static_assert((!std::__libcpp_is_trivial_iterator<forward_iterator <char *> >::value), ""); + static_assert((!std::__libcpp_is_trivial_iterator<bidirectional_iterator<char *> >::value), ""); + static_assert((!std::__libcpp_is_trivial_iterator<random_access_iterator<char *> >::value), ""); + static_assert((!std::__libcpp_is_trivial_iterator<ThrowingIterator <char *> >::value), ""); + static_assert((!std::__libcpp_is_trivial_iterator<NonThrowingIterator <char *> >::value), ""); // Iterator classification @@ -137,7 +137,7 @@ int main() static_assert((!std::__is_bidirectional_iterator<input_iterator<char *> >::value), "" ); static_assert((!std::__is_random_access_iterator<input_iterator<char *> >::value), "" ); static_assert(( std::__is_exactly_input_iterator<input_iterator<char *> >::value), "" ); - + static_assert(( std::__is_input_iterator <forward_iterator<char *> >::value), "" ); static_assert(( std::__is_forward_iterator <forward_iterator<char *> >::value), "" ); static_assert((!std::__is_bidirectional_iterator<forward_iterator<char *> >::value), "" ); @@ -171,7 +171,7 @@ int main() static_assert(( std::__libcpp_is_trivial_iterator<std::vector<char>::const_iterator> ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator<std::vector<char>::reverse_iterator> ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator<std::vector<char>::const_reverse_iterator>::value), ""); - + // vector static_assert(( std::__libcpp_is_trivial_iterator<std::basic_string<char>::iterator> ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator<std::basic_string<char>::const_iterator> ::value), ""); diff --git a/test/std/iterators/version.pass.cpp b/test/libcxx/iterators/version.pass.cpp index dd097850388e5..dd097850388e5 100644 --- a/test/std/iterators/version.pass.cpp +++ b/test/libcxx/iterators/version.pass.cpp diff --git a/test/std/language.support/cstdint/version.pass.cpp b/test/libcxx/language.support/cstdint/version.pass.cpp index 4c9a43a62abc0..4c9a43a62abc0 100644 --- a/test/std/language.support/cstdint/version.pass.cpp +++ b/test/libcxx/language.support/cstdint/version.pass.cpp diff --git a/test/std/language.support/support.dynamic/alloc.errors/new.badlength/bad_array_length.pass.cpp b/test/libcxx/language.support/support.dynamic/alloc.errors/new.badlength/bad_array_length.pass.cpp index 7de5033045566..cc99b83aca4e9 100644 --- a/test/std/language.support/support.dynamic/alloc.errors/new.badlength/bad_array_length.pass.cpp +++ b/test/libcxx/language.support/support.dynamic/alloc.errors/new.badlength/bad_array_length.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // test bad_array_length #include <new> @@ -15,7 +16,6 @@ int main() { -#if __LIBCPP_STD_VER > 11 static_assert((std::is_base_of<std::bad_alloc, std::bad_array_length>::value), "std::is_base_of<std::bad_alloc, std::bad_array_length>::value"); static_assert(std::is_polymorphic<std::bad_array_length>::value, @@ -25,5 +25,4 @@ int main() b2 = b; const char* w = b2.what(); assert(w); -#endif } diff --git a/test/std/language.support/support.dynamic/version.pass.cpp b/test/libcxx/language.support/support.dynamic/version.pass.cpp index ba1ff518e51f0..ba1ff518e51f0 100644 --- a/test/std/language.support/support.dynamic/version.pass.cpp +++ b/test/libcxx/language.support/support.dynamic/version.pass.cpp diff --git a/test/std/language.support/support.exception/version.pass.cpp b/test/libcxx/language.support/support.exception/version.pass.cpp index acdedbb31fe32..acdedbb31fe32 100644 --- a/test/std/language.support/support.exception/version.pass.cpp +++ b/test/libcxx/language.support/support.exception/version.pass.cpp diff --git a/test/std/language.support/support.initlist/version.pass.cpp b/test/libcxx/language.support/support.initlist/version.pass.cpp index f3f08cd1f864e..f3f08cd1f864e 100644 --- a/test/std/language.support/support.initlist/version.pass.cpp +++ b/test/libcxx/language.support/support.initlist/version.pass.cpp diff --git a/test/std/language.support/support.limits/c.limits/version_cfloat.pass.cpp b/test/libcxx/language.support/support.limits/c.limits/version_cfloat.pass.cpp index 19b463199cd61..19b463199cd61 100644 --- a/test/std/language.support/support.limits/c.limits/version_cfloat.pass.cpp +++ b/test/libcxx/language.support/support.limits/c.limits/version_cfloat.pass.cpp diff --git a/test/std/language.support/support.limits/c.limits/version_climits.pass.cpp b/test/libcxx/language.support/support.limits/c.limits/version_climits.pass.cpp index 3fe07a5174b30..3fe07a5174b30 100644 --- a/test/std/language.support/support.limits/c.limits/version_climits.pass.cpp +++ b/test/libcxx/language.support/support.limits/c.limits/version_climits.pass.cpp diff --git a/test/std/language.support/support.limits/limits/version.pass.cpp b/test/libcxx/language.support/support.limits/limits/version.pass.cpp index 0cb3f6f52a4e6..0cb3f6f52a4e6 100644 --- a/test/std/language.support/support.limits/limits/version.pass.cpp +++ b/test/libcxx/language.support/support.limits/limits/version.pass.cpp diff --git a/test/std/language.support/support.rtti/version.pass.cpp b/test/libcxx/language.support/support.rtti/version.pass.cpp index 0a9ece34f97ea..0a9ece34f97ea 100644 --- a/test/std/language.support/support.rtti/version.pass.cpp +++ b/test/libcxx/language.support/support.rtti/version.pass.cpp diff --git a/test/std/language.support/support.runtime/version_csetjmp.pass.cpp b/test/libcxx/language.support/support.runtime/version_csetjmp.pass.cpp index 7e37716d01459..7e37716d01459 100644 --- a/test/std/language.support/support.runtime/version_csetjmp.pass.cpp +++ b/test/libcxx/language.support/support.runtime/version_csetjmp.pass.cpp diff --git a/test/std/language.support/support.runtime/version_csignal.pass.cpp b/test/libcxx/language.support/support.runtime/version_csignal.pass.cpp index be1045f1eb3b1..be1045f1eb3b1 100644 --- a/test/std/language.support/support.runtime/version_csignal.pass.cpp +++ b/test/libcxx/language.support/support.runtime/version_csignal.pass.cpp diff --git a/test/std/language.support/support.runtime/version_cstdarg.pass.cpp b/test/libcxx/language.support/support.runtime/version_cstdarg.pass.cpp index f3ca9389b15d2..f3ca9389b15d2 100644 --- a/test/std/language.support/support.runtime/version_cstdarg.pass.cpp +++ b/test/libcxx/language.support/support.runtime/version_cstdarg.pass.cpp diff --git a/test/std/language.support/support.runtime/version_cstdbool.pass.cpp b/test/libcxx/language.support/support.runtime/version_cstdbool.pass.cpp index 0415227e58ead..0415227e58ead 100644 --- a/test/std/language.support/support.runtime/version_cstdbool.pass.cpp +++ b/test/libcxx/language.support/support.runtime/version_cstdbool.pass.cpp diff --git a/test/std/language.support/support.runtime/version_cstdlib.pass.cpp b/test/libcxx/language.support/support.runtime/version_cstdlib.pass.cpp index db419524f5783..db419524f5783 100644 --- a/test/std/language.support/support.runtime/version_cstdlib.pass.cpp +++ b/test/libcxx/language.support/support.runtime/version_cstdlib.pass.cpp diff --git a/test/std/language.support/support.runtime/version_ctime.pass.cpp b/test/libcxx/language.support/support.runtime/version_ctime.pass.cpp index ce0bf2cf1853c..ce0bf2cf1853c 100644 --- a/test/std/language.support/support.runtime/version_ctime.pass.cpp +++ b/test/libcxx/language.support/support.runtime/version_ctime.pass.cpp diff --git a/test/std/language.support/support.types/version.pass.cpp b/test/libcxx/language.support/support.types/version.pass.cpp index 2ab7c188de1d8..2ab7c188de1d8 100644 --- a/test/std/language.support/support.types/version.pass.cpp +++ b/test/libcxx/language.support/support.types/version.pass.cpp diff --git a/test/std/localization/c.locales/version.pass.cpp b/test/libcxx/localization/c.locales/version.pass.cpp index 0fce59e2b0b84..0fce59e2b0b84 100644 --- a/test/std/localization/c.locales/version.pass.cpp +++ b/test/libcxx/localization/c.locales/version.pass.cpp diff --git a/test/std/localization/locale.categories/__scan_keyword.pass.cpp b/test/libcxx/localization/locale.categories/__scan_keyword.pass.cpp index b33aab9a730a6..b33aab9a730a6 100644 --- a/test/std/localization/locale.categories/__scan_keyword.pass.cpp +++ b/test/libcxx/localization/locale.categories/__scan_keyword.pass.cpp diff --git a/test/std/localization/locale.stdcvt/version.pass.cpp b/test/libcxx/localization/locale.stdcvt/version.pass.cpp index 3885380854cc4..3885380854cc4 100644 --- a/test/std/localization/locale.stdcvt/version.pass.cpp +++ b/test/libcxx/localization/locale.stdcvt/version.pass.cpp diff --git a/test/libcxx/localization/locales/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp b/test/libcxx/localization/locales/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp new file mode 100644 index 0000000000000..75e2aeb064eb4 --- /dev/null +++ b/test/libcxx/localization/locales/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <locale> + +// wstring_convert<Codecvt, Elem, Wide_alloc, Byte_alloc> + +// wstring_convert(wstring_convert&& other); // EXTENSION + +#include <locale> +#include <codecvt> +#include <cassert> + +int main() +{ + typedef std::codecvt_utf8<wchar_t> Codecvt; + typedef std::wstring_convert<Codecvt> Myconv; + // create a converter and perform some conversions to generate some + // interesting state. + Myconv myconv; + myconv.from_bytes("\xF1\x80\x80\x83"); + const int old_converted = myconv.converted(); + assert(myconv.converted() == 4); + // move construct a new converter and make sure the state is the same. + Myconv myconv2(std::move(myconv)); + assert(myconv2.converted() == 4); +} diff --git a/test/std/localization/locales/locale/locale.types/locale.facet/facet.pass.cpp b/test/libcxx/localization/locales/locale/locale.types/locale.facet/facet.pass.cpp index 4a7f77ad5d9a3..4a7f77ad5d9a3 100644 --- a/test/std/localization/locales/locale/locale.types/locale.facet/facet.pass.cpp +++ b/test/libcxx/localization/locales/locale/locale.types/locale.facet/facet.pass.cpp diff --git a/test/std/localization/locales/locale/locale.types/locale.id/id.pass.cpp b/test/libcxx/localization/locales/locale/locale.types/locale.id/id.pass.cpp index 3233624d87b44..3233624d87b44 100644 --- a/test/std/localization/locales/locale/locale.types/locale.id/id.pass.cpp +++ b/test/libcxx/localization/locales/locale/locale.types/locale.id/id.pass.cpp diff --git a/test/std/localization/version.pass.cpp b/test/libcxx/localization/version.pass.cpp index a64534c9f58bf..a64534c9f58bf 100644 --- a/test/std/localization/version.pass.cpp +++ b/test/libcxx/localization/version.pass.cpp diff --git a/test/std/numerics/cfenv/version.pass.cpp b/test/libcxx/numerics/cfenv/version.pass.cpp index 727d5bdf39946..727d5bdf39946 100644 --- a/test/std/numerics/cfenv/version.pass.cpp +++ b/test/libcxx/numerics/cfenv/version.pass.cpp diff --git a/test/std/numerics/complex.number/version.pass.cpp b/test/libcxx/numerics/complex.number/version.pass.cpp index 316cfec739a9a..316cfec739a9a 100644 --- a/test/std/numerics/complex.number/version.pass.cpp +++ b/test/libcxx/numerics/complex.number/version.pass.cpp diff --git a/test/std/numerics/numarray/version.pass.cpp b/test/libcxx/numerics/numarray/version.pass.cpp index 85457d4329ece..85457d4329ece 100644 --- a/test/std/numerics/numarray/version.pass.cpp +++ b/test/libcxx/numerics/numarray/version.pass.cpp diff --git a/test/std/numerics/numeric.ops/version.pass.cpp b/test/libcxx/numerics/numeric.ops/version.pass.cpp index fb6e0a1063cee..fb6e0a1063cee 100644 --- a/test/std/numerics/numeric.ops/version.pass.cpp +++ b/test/libcxx/numerics/numeric.ops/version.pass.cpp diff --git a/test/std/numerics/rand/rand.synopsis/version.pass.cpp b/test/libcxx/numerics/rand/rand.synopsis/version.pass.cpp index eae6c493e919e..eae6c493e919e 100644 --- a/test/std/numerics/rand/rand.synopsis/version.pass.cpp +++ b/test/libcxx/numerics/rand/rand.synopsis/version.pass.cpp diff --git a/test/libcxx/selftest/test_macros.pass.cpp b/test/libcxx/selftest/test_macros.pass.cpp index 2c8ed4f454a7e..69e75b788711a 100644 --- a/test/libcxx/selftest/test_macros.pass.cpp +++ b/test/libcxx/selftest/test_macros.pass.cpp @@ -8,51 +8,59 @@ //===----------------------------------------------------------------------===// // // Test the "test_macros.h" header. +#include <__config> #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 +#ifndef LIBCPP_ASSERT +#error LIBCPP_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; } +#ifndef LIBCPP_STATIC_ASSERT +#error LIBCPP_STATIC_ASSERT must be defined +#endif void test_noexcept() TEST_NOEXCEPT { } -void test_decltype() +void test_libcxx_macros() { - typedef TEST_DECLTYPE(foo()) MyType; - TEST_STATIC_ASSERT((is_same<MyType, int>::value), "is same"); -} +// ===== C++14 features ===== +// defined(TEST_HAS_EXTENDED_CONSTEXPR) != defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +#ifdef TEST_HAS_EXTENDED_CONSTEXPR +# ifdef _LIBCPP_HAS_NO_CXX14_CONSTEXPR +# error "TEST_EXTENDED_CONSTEXPR mismatch (1)" +# endif +#else +# ifndef _LIBCPP_HAS_NO_CXX14_CONSTEXPR +# error "TEST_EXTENDED_CONSTEXPR mismatch (2)" +# endif +#endif -void test_static_assert() -{ - TEST_STATIC_ASSERT((is_same<int, int>::value), "is same"); - TEST_STATIC_ASSERT((!is_same<int, long>::value), "not same"); +// defined(TEST_HAS_VARIABLE_TEMPLATES) != defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +#ifdef TEST_HAS_VARIABLE_TEMPLATES +# ifdef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES +# error "TEST_VARIABLE_TEMPLATES mismatch (1)" +# endif +#else +# ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES +# error "TEST_VARIABLE_TEMPLATES mismatch (2)" +# endif +#endif + +// ===== C++1z features ===== } int main() { test_noexcept(); - test_decltype(); - test_static_assert(); + test_libcxx_macros(); } diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_db1.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_db1.pass.cpp index 6c2929d7f1d3a..6c2929d7f1d3a 100644 --- a/test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_db1.pass.cpp +++ b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_db1.pass.cpp diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_db2.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_db2.pass.cpp index d20fcd4623b7d..d20fcd4623b7d 100644 --- a/test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_db2.pass.cpp +++ b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_db2.pass.cpp diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db1.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db1.pass.cpp index 5015241ad63ea..5015241ad63ea 100644 --- a/test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db1.pass.cpp +++ b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db1.pass.cpp diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db2.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db2.pass.cpp index 6a23bf88ca5c0..6a23bf88ca5c0 100644 --- a/test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db2.pass.cpp +++ b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db2.pass.cpp diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db3.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db3.pass.cpp index a8443818aea5b..a8443818aea5b 100644 --- a/test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db3.pass.cpp +++ b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db3.pass.cpp diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db4.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db4.pass.cpp index 0549e816b44c8..0549e816b44c8 100644 --- a/test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db4.pass.cpp +++ b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db4.pass.cpp diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_pop_back_db1.pass.cpp index ffc715fe9a5bd..8a6c3f0cf38f4 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp +++ b/test/libcxx/strings/basic.string/string.modifiers/erase_pop_back_db1.pass.cpp @@ -7,21 +7,26 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++98, c++03, c++11 +// <string> -#include <tuple> -#include <string> -#include <memory> +// void pop_back(); + +#if _LIBCPP_DEBUG >= 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif +#include <string> #include <cassert> +#include "test_macros.h" + int main() { -#if _LIBCPP_STD_VER > 11 - typedef std::unique_ptr<int> upint; - std::tuple<upint> t(upint(new int(4))); - upint p = std::get<upint>(t); -#else -#error +#if _LIBCPP_DEBUG >= 1 + { + std::string s; + s.pop_back(); + assert(false); + } #endif } diff --git a/test/libcxx/strings/basic.string/string.modifiers/insert_iter_char_db1.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/insert_iter_char_db1.pass.cpp new file mode 100644 index 0000000000000..fbb26d1789977 --- /dev/null +++ b/test/libcxx/strings/basic.string/string.modifiers/insert_iter_char_db1.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. +// +//===----------------------------------------------------------------------===// + +// <string> + +// iterator insert(const_iterator p, charT c); + +#if _LIBCPP_DEBUG >= 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include <string> +#include <stdexcept> +#include <cassert> + + +int main() +{ +#if _LIBCPP_DEBUG >= 1 + { + typedef std::string S; + S s; + S s2; + s.insert(s2.begin(), '1'); + assert(false); + } +#endif +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp b/test/libcxx/strings/basic.string/string.modifiers/insert_iter_size_char_db1.pass.cpp index 0a4550f387dc0..7ddd2b00d402c 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp +++ b/test/libcxx/strings/basic.string/string.modifiers/insert_iter_size_char_db1.pass.cpp @@ -7,21 +7,25 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++98, c++03, c++11 +// <string> -#include <tuple> -#include <string> -#include <complex> +// iterator insert(const_iterator p, size_type n, charT c); + +#if _LIBCPP_DEBUG >= 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif +#include <string> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 - typedef std::complex<float> cf; - auto t1 = std::make_tuple<double, int, std::string, cf, int> ( 42, 21, "Hi", { 1,2 } ); - assert ( std::get<int>(t1) == 42 ); // two ints here (one at the end) -#else -#error +#if _LIBCPP_DEBUG >= 1 + { + std::string s; + std::string s2; + s.insert(s2.begin(), 1, 'a'); + assert(false); + } #endif } diff --git a/test/std/strings/c.strings/version_cctype.pass.cpp b/test/libcxx/strings/c.strings/version_cctype.pass.cpp index e0919d9d27b0e..e0919d9d27b0e 100644 --- a/test/std/strings/c.strings/version_cctype.pass.cpp +++ b/test/libcxx/strings/c.strings/version_cctype.pass.cpp diff --git a/test/std/strings/c.strings/version_cstring.pass.cpp b/test/libcxx/strings/c.strings/version_cstring.pass.cpp index 87e705aec4cc7..87e705aec4cc7 100644 --- a/test/std/strings/c.strings/version_cstring.pass.cpp +++ b/test/libcxx/strings/c.strings/version_cstring.pass.cpp diff --git a/test/std/strings/c.strings/version_cuchar.pass.cpp b/test/libcxx/strings/c.strings/version_cuchar.pass.cpp index dcfdcc37ac7eb..dcfdcc37ac7eb 100644 --- a/test/std/strings/c.strings/version_cuchar.pass.cpp +++ b/test/libcxx/strings/c.strings/version_cuchar.pass.cpp diff --git a/test/std/strings/c.strings/version_cwchar.pass.cpp b/test/libcxx/strings/c.strings/version_cwchar.pass.cpp index 72e9855c54e5a..72e9855c54e5a 100644 --- a/test/std/strings/c.strings/version_cwchar.pass.cpp +++ b/test/libcxx/strings/c.strings/version_cwchar.pass.cpp diff --git a/test/std/strings/c.strings/version_cwctype.pass.cpp b/test/libcxx/strings/c.strings/version_cwctype.pass.cpp index 461482abe7652..461482abe7652 100644 --- a/test/std/strings/c.strings/version_cwctype.pass.cpp +++ b/test/libcxx/strings/c.strings/version_cwctype.pass.cpp diff --git a/test/libcxx/strings/iterators.exceptions.pass.cpp b/test/libcxx/strings/iterators.exceptions.pass.cpp index 591782b5dd4a0..02ec921cc6133 100644 --- a/test/libcxx/strings/iterators.exceptions.pass.cpp +++ b/test/libcxx/strings/iterators.exceptions.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // - +// XFAIL: libcpp-no-exceptions // <iterator> // __libcpp_is_trivial_iterator<Tp> @@ -23,6 +23,7 @@ #include <vector> #include <initializer_list> +#include "test_macros.h" #include "test_iterators.h" int main() @@ -30,17 +31,17 @@ int main() // basic tests static_assert(( std::__libcpp_string_gets_noexcept_iterator<char *>::value), ""); static_assert(( std::__libcpp_string_gets_noexcept_iterator<const char *>::value), ""); - + static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::move_iterator<char *> > ::value), ""); static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::move_iterator<const char *> >::value), ""); static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::reverse_iterator<char *> > ::value), ""); static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::reverse_iterator<const char *> >::value), ""); - + static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::__wrap_iter<char *> > ::value), ""); static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::__wrap_iter<const char *> >::value), ""); - + static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::reverse_iterator<std::__wrap_iter<char *> > > ::value), ""); - + // iterators in the libc++ test suite static_assert((!std::__libcpp_string_gets_noexcept_iterator<output_iterator <char *> >::value), ""); static_assert((!std::__libcpp_string_gets_noexcept_iterator<input_iterator <char *> >::value), ""); @@ -48,13 +49,13 @@ int main() static_assert((!std::__libcpp_string_gets_noexcept_iterator<bidirectional_iterator<char *> >::value), ""); static_assert((!std::__libcpp_string_gets_noexcept_iterator<random_access_iterator<char *> >::value), ""); static_assert((!std::__libcpp_string_gets_noexcept_iterator<ThrowingIterator <char *> >::value), ""); - -#if __has_feature(cxx_noexcept) + +#if TEST_STD_VER >= 11 static_assert(( std::__libcpp_string_gets_noexcept_iterator<NonThrowingIterator <char *> >::value), ""); #else static_assert((!std::__libcpp_string_gets_noexcept_iterator<NonThrowingIterator <char *> >::value), ""); #endif - + // // iterators from libc++'s containers // diff --git a/test/libcxx/strings/iterators.noexcept.pass.cpp b/test/libcxx/strings/iterators.noexcept.pass.cpp index f39a4deac7358..283cf0897cca8 100644 --- a/test/libcxx/strings/iterators.noexcept.pass.cpp +++ b/test/libcxx/strings/iterators.noexcept.pass.cpp @@ -34,17 +34,17 @@ int main() // basic tests static_assert(( std::__libcpp_string_gets_noexcept_iterator<char *>::value), ""); static_assert(( std::__libcpp_string_gets_noexcept_iterator<const char *>::value), ""); - + static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::move_iterator<char *> > ::value), ""); static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::move_iterator<const char *> >::value), ""); static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::reverse_iterator<char *> > ::value), ""); static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::reverse_iterator<const char *> >::value), ""); - + static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::__wrap_iter<char *> > ::value), ""); static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::__wrap_iter<const char *> >::value), ""); - + static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::reverse_iterator<std::__wrap_iter<char *> > > ::value), ""); - + // iterators in the libc++ test suite static_assert(( std::__libcpp_string_gets_noexcept_iterator<output_iterator <char *> >::value), ""); static_assert(( std::__libcpp_string_gets_noexcept_iterator<input_iterator <char *> >::value), ""); @@ -52,9 +52,9 @@ int main() static_assert(( std::__libcpp_string_gets_noexcept_iterator<bidirectional_iterator<char *> >::value), ""); static_assert(( std::__libcpp_string_gets_noexcept_iterator<random_access_iterator<char *> >::value), ""); static_assert(( std::__libcpp_string_gets_noexcept_iterator<ThrowingIterator <char *> >::value), ""); - + static_assert(( std::__libcpp_string_gets_noexcept_iterator<NonThrowingIterator <char *> >::value), ""); - + // // iterators from libc++'s containers // diff --git a/test/std/strings/version.pass.cpp b/test/libcxx/strings/version.pass.cpp index 0c79c1af2ce84..0c79c1af2ce84 100644 --- a/test/std/strings/version.pass.cpp +++ b/test/libcxx/strings/version.pass.cpp diff --git a/test/libcxx/test/config.py b/test/libcxx/test/config.py index f8096ad15f8a0..593f9805447d3 100644 --- a/test/libcxx/test/config.py +++ b/test/libcxx/test/config.py @@ -61,6 +61,7 @@ class Configuration(object): self.libcxx_src_root = None self.libcxx_obj_root = None self.cxx_library_root = None + self.cxx_runtime_root = None self.abi_library_root = None self.env = {} self.use_target = False @@ -98,9 +99,11 @@ class Configuration(object): self.configure_cxx_library_root() self.configure_use_system_cxx_lib() self.configure_use_clang_verify() + self.configure_use_thread_safety() self.configure_execute_external() self.configure_ccache() self.configure_compile_flags() + self.configure_filesystem_compile_flags() self.configure_link_flags() self.configure_env() self.configure_color_diagnostics() @@ -194,6 +197,8 @@ class Configuration(object): def configure_cxx_library_root(self): self.cxx_library_root = self.get_lit_conf('cxx_library_root', self.libcxx_obj_root) + self.cxx_runtime_root = self.get_lit_conf('cxx_runtime_root', + self.cxx_library_root) def configure_use_system_cxx_lib(self): # This test suite supports testing against either the system library or @@ -218,6 +223,14 @@ class Configuration(object): self.lit_config.note( "inferred use_clang_verify as: %r" % self.use_clang_verify) + def configure_use_thread_safety(self): + '''If set, run clang with -verify on failing tests.''' + has_thread_safety = self.cxx.hasCompileFlag('-Werror=thread-safety') + if has_thread_safety: + self.cxx.compile_flags += ['-Werror=thread-safety'] + self.config.available_features.add('thread-safety') + self.lit_config.note("enabling thread-safety annotations") + def configure_execute_external(self): # Choose between lit's internal shell pipeline runner and a real shell. # If LIT_USE_INTERNAL_SHELL is in the environment, we use that as the @@ -277,10 +290,17 @@ class Configuration(object): if self.cxx.hasCompileFlag('-fsized-deallocation'): self.config.available_features.add('fsized-deallocation') + if self.get_lit_bool('has_libatomic', False): + self.config.available_features.add('libatomic') + def configure_compile_flags(self): no_default_flags = self.get_lit_bool('no_default_flags', False) if not no_default_flags: self.configure_default_compile_flags() + # This include is always needed so add so add it regardless of + # 'no_default_flags'. + support_path = os.path.join(self.libcxx_src_root, 'test/support') + self.cxx.compile_flags += ['-I' + support_path] # Configure extra flags compile_flags_str = self.get_lit_conf('compile_flags', '') self.cxx.compile_flags += shlex.split(compile_flags_str) @@ -329,7 +349,6 @@ class Configuration(object): 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] self.cxx.compile_flags += ['-include', os.path.join(support_path, 'nasty_macros.hpp')] self.configure_config_site_header() libcxx_headers = self.get_lit_conf( @@ -412,6 +431,37 @@ class Configuration(object): self.config.available_features.add('libcpp-abi-unstable') self.cxx.compile_flags += ['-D_LIBCPP_ABI_UNSTABLE'] + def configure_filesystem_compile_flags(self): + enable_fs = self.get_lit_bool('enable_filesystem', default=False) + if not enable_fs: + return + enable_experimental = self.get_lit_bool('enable_experimental', default=False) + if not enable_experimental: + self.lit_config.fatal( + 'filesystem is enabled but libc++experimental.a is not.') + self.config.available_features.add('c++filesystem') + static_env = os.path.join(self.libcxx_src_root, 'test', 'std', + 'experimental', 'filesystem', 'Inputs', 'static_test_env') + static_env = os.path.realpath(static_env) + assert os.path.isdir(static_env) + self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_STATIC_TEST_ROOT="%s"' % static_env] + + dynamic_env = os.path.join(self.libcxx_obj_root, 'test', + 'filesystem', 'Output', 'dynamic_env') + dynamic_env = os.path.realpath(dynamic_env) + if not os.path.isdir(dynamic_env): + os.makedirs(dynamic_env) + self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT="%s"' % dynamic_env] + self.env['LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT'] = ("%s" % dynamic_env) + + dynamic_helper = os.path.join(self.libcxx_src_root, 'test', 'support', + 'filesystem_dynamic_test_helper.py') + assert os.path.isfile(dynamic_helper) + + self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER="%s %s"' + % (sys.executable, dynamic_helper)] + + def configure_link_flags(self): no_default_flags = self.get_lit_bool('no_default_flags', False) if not no_default_flags: @@ -430,23 +480,11 @@ class Configuration(object): self.cxx.link_flags += shlex.split(link_flags_str) def configure_link_flags_cxx_library_path(self): - libcxx_library = self.get_lit_conf('libcxx_library') - # Configure libc++ library paths. - if libcxx_library is not None: - # Check that the given value for libcxx_library is valid. - if not os.path.isfile(libcxx_library): - self.lit_config.fatal( - "libcxx_library='%s' is not a valid file." % - libcxx_library) - if self.use_system_cxx_lib: - self.lit_config.fatal( - "Conflicting options: 'libcxx_library' cannot be used " - "with 'use_system_cxx_lib=true'") - self.cxx.link_flags += ['-Wl,-rpath,' + - os.path.dirname(libcxx_library)] - elif not self.use_system_cxx_lib and self.cxx_library_root: - self.cxx.link_flags += ['-L' + self.cxx_library_root, - '-Wl,-rpath,' + self.cxx_library_root] + if not self.use_system_cxx_lib: + if self.cxx_library_root: + self.cxx.link_flags += ['-L' + self.cxx_library_root] + if self.cxx_runtime_root: + self.cxx.link_flags += ['-Wl,-rpath,' + self.cxx_runtime_root] def configure_link_flags_abi_library_path(self): # Configure ABI library paths. @@ -456,11 +494,20 @@ class Configuration(object): '-Wl,-rpath,' + self.abi_library_root] def configure_link_flags_cxx_library(self): - libcxx_library = self.get_lit_conf('libcxx_library') - if libcxx_library: - self.cxx.link_flags += [libcxx_library] - else: + libcxx_experimental = self.get_lit_bool('enable_experimental', default=False) + if libcxx_experimental: + self.config.available_features.add('c++experimental') + self.cxx.link_flags += ['-lc++experimental'] + libcxx_shared = self.get_lit_bool('enable_shared', default=True) + if libcxx_shared: self.cxx.link_flags += ['-lc++'] + else: + cxx_library_root = self.get_lit_conf('cxx_library_root') + if cxx_library_root: + abs_path = os.path.join(cxx_library_root, 'libc++.a') + self.cxx.link_flags += [abs_path] + else: + self.cxx.link_flags += ['-lc++'] def configure_link_flags_abi_library(self): cxx_abi = self.get_lit_conf('cxx_abi', 'libcxxabi') @@ -470,7 +517,16 @@ class Configuration(object): self.cxx.link_flags += ['-lsupc++'] elif cxx_abi == 'libcxxabi': if self.target_info.allow_cxxabi_link(): - self.cxx.link_flags += ['-lc++abi'] + libcxxabi_shared = self.get_lit_bool('libcxxabi_shared', default=True) + if libcxxabi_shared: + self.cxx.link_flags += ['-lc++abi'] + else: + cxxabi_library_root = self.get_lit_conf('abi_library_path') + if cxxabi_library_root: + abs_path = os.path.join(cxxabi_library_root, 'libc++abi.a') + self.cxx.link_flags += [abs_path] + else: + self.cxx.link_flags += ['-lc++abi'] elif cxx_abi == 'libcxxrt': self.cxx.link_flags += ['-lcxxrt'] elif cxx_abi == 'none': @@ -515,8 +571,9 @@ class Configuration(object): if enable_warnings: self.cxx.compile_flags += [ '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER', - '-Wall', '-Werror' + '-Wall', '-Wextra', '-Werror' ] + self.cxx.addWarningFlagIfSupported('-Wno-unused-command-line-argument') self.cxx.addWarningFlagIfSupported('-Wno-attributes') self.cxx.addWarningFlagIfSupported('-Wno-pessimizing-move') self.cxx.addWarningFlagIfSupported('-Wno-c++11-extensions') @@ -525,6 +582,8 @@ class Configuration(object): # compiles clean with them. self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef') self.cxx.addWarningFlagIfSupported('-Wno-unused-variable') + self.cxx.addWarningFlagIfSupported('-Wno-unused-parameter') + self.cxx.addWarningFlagIfSupported('-Wno-sign-compare') 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 @@ -551,6 +610,9 @@ class Configuration(object): self.cxx.flags += ['-fsanitize=address'] if llvm_symbolizer is not None: self.env['ASAN_SYMBOLIZER_PATH'] = llvm_symbolizer + # FIXME: Turn ODR violation back on after PR28391 is resolved + # https://llvm.org/bugs/show_bug.cgi?id=28391 + self.env['ASAN_OPTIONS'] = 'detect_odr_violation=0' self.config.available_features.add('asan') self.config.available_features.add('sanitizer-new-delete') elif san == 'Memory' or san == 'MemoryWithOrigins': @@ -563,9 +625,12 @@ class Configuration(object): self.config.available_features.add('msan') self.config.available_features.add('sanitizer-new-delete') elif san == 'Undefined': + blacklist = os.path.join(self.libcxx_src_root, + 'test/ubsan_blacklist.txt') self.cxx.flags += ['-fsanitize=undefined', - '-fno-sanitize=vptr,function', - '-fno-sanitize-recover'] + '-fno-sanitize=vptr,function,float-divide-by-zero', + '-fno-sanitize-recover=all', + '-fsanitize-blacklist=' + blacklist] self.cxx.compile_flags += ['-O3'] self.env['UBSAN_OPTIONS'] = 'print_stacktrace=1' self.config.available_features.add('ubsan') diff --git a/test/libcxx/test/format.py b/test/libcxx/test/format.py index aaa9a1845ae40..b9ec2ba2aa7bb 100644 --- a/test/libcxx/test/format.py +++ b/test/libcxx/test/format.py @@ -161,12 +161,19 @@ class LibcxxTestFormat(object): 'expected-error', 'expected-no-diagnostics'] use_verify = self.use_verify_for_fail and \ any([tag in contents for tag in verify_tags]) - extra_flags = ['-fsyntax-only'] + # FIXME(EricWF): GCC 5 does not evaluate static assertions that + # are dependant on a template parameter when '-fsyntax-only' is passed. + # This is fixed in GCC 6. However for now we only pass "-fsyntax-only" + # when using Clang. + extra_flags = [] + if self.cxx.type != 'gcc': + extra_flags += ['-fsyntax-only'] 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) + flags=extra_flags, + disable_ccache=True) expected_rc = 0 if use_verify else 1 if rc == expected_rc: return lit.Test.PASS, '' diff --git a/test/libcxx/test/target_info.py b/test/libcxx/test/target_info.py index 7ca08bea193af..a743595a1046d 100644 --- a/test/libcxx/test/target_info.py +++ b/test/libcxx/test/target_info.py @@ -90,13 +90,10 @@ class DarwinLocalTI(DefaultTargetInfo): def configure_env(self, env): library_paths = [] # Configure the library path for libc++ - libcxx_library = self.full_config.get_lit_conf('libcxx_library') if self.full_config.use_system_cxx_lib: pass - elif libcxx_library: - library_paths += [os.path.dirname(libcxx_library)] - elif self.full_config.cxx_library_root: - library_paths += [self.full_config.cxx_library_root] + elif self.full_config.cxx_runtime_root: + library_paths += [self.full_config.cxx_runtime_root] # Configure the abi library path if self.full_config.abi_library_root: library_paths += [self.full_config.abi_library_root] @@ -104,6 +101,15 @@ class DarwinLocalTI(DefaultTargetInfo): env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths) def allow_cxxabi_link(self): + # FIXME: PR27405 + # libc++ *should* export all of the symbols found in libc++abi on OS X. + # For this reason LibcxxConfiguration will not link libc++abi in OS X. + # However __cxa_throw_bad_new_array_length doesn't get exported into + # libc++ yet so we still need to explicitly link libc++abi when testing + # libc++abi + # See PR22654. + if(self.full_config.get_lit_conf('name', '') == 'libc++abi'): + return True # Don't link libc++abi explicitly on OS X because the symbols # should be available in libc++ directly. return False @@ -162,16 +168,22 @@ class LinuxLocalTI(DefaultTargetInfo): enable_threads = ('libcpp-has-no-threads' not in self.full_config.config.available_features) llvm_unwinder = self.full_config.get_lit_bool('llvm_unwinder', False) + shared_libcxx = self.full_config.get_lit_bool('enable_shared', True) flags += ['-lm'] if not llvm_unwinder: flags += ['-lgcc_s', '-lgcc'] if enable_threads: flags += ['-lpthread'] + if not shared_libcxx: + flags += ['-lrt'] flags += ['-lc'] if llvm_unwinder: flags += ['-lunwind', '-ldl'] else: flags += ['-lgcc_s', '-lgcc'] + use_libatomic = self.full_config.get_lit_bool('use_libatomic', False) + if use_libatomic: + flags += ['-latomic'] san = self.full_config.get_lit_conf('use_sanitizer', '').strip() if san: # The libraries and their order are taken from the diff --git a/test/libcxx/thread/futures/futures.promise/set_exception.pass.cpp b/test/libcxx/thread/futures/futures.promise/set_exception.pass.cpp new file mode 100644 index 0000000000000..bf567a30243ad --- /dev/null +++ b/test/libcxx/thread/futures/futures.promise/set_exception.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-no-exceptions +// UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: c++98, c++03 + +// <future> + +// class promise<R> + +// void set_exception(exception_ptr p); +// Test that a null exception_ptr is diagnosed. + +#define _LIBCPP_ASSERT(x, m) ((x) ? ((void)0) : throw 42) + +#define _LIBCPP_DEBUG 0 +#include <future> +#include <exception> +#include <cstdlib> +#include <cassert> + + +int main() +{ + { + typedef int T; + std::promise<T> p; + try { + p.set_exception(std::exception_ptr()); + assert(false); + } catch (int const& value) { + assert(value == 42); + } + } + { + typedef int& T; + std::promise<T> p; + try { + p.set_exception(std::exception_ptr()); + assert(false); + } catch (int const& value) { + assert(value == 42); + } + } +} diff --git a/test/libcxx/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp b/test/libcxx/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp new file mode 100644 index 0000000000000..1cb61d9af297e --- /dev/null +++ b/test/libcxx/thread/futures/futures.promise/set_exception_at_thread_exit.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-no-exceptions +// UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: c++98, c++03 + +// <future> + +// class promise<R> + +// void set_exception_on_thread_exit(exception_ptr p); +// Test that a null exception_ptr is diagnosed. + +#define _LIBCPP_ASSERT(x, m) ((x) ? ((void)0) : throw 42) + +#define _LIBCPP_DEBUG 0 +#include <future> +#include <exception> +#include <cstdlib> +#include <cassert> + + +int main() +{ + { + typedef int T; + std::promise<T> p; + try { + p.set_exception_at_thread_exit(std::exception_ptr()); + assert(false); + } catch (int const& value) { + assert(value == 42); + } + } + { + typedef int& T; + std::promise<T> p; + try { + p.set_exception_at_thread_exit(std::exception_ptr()); + assert(false); + } catch (int const& value) { + assert(value == 42); + } + } +} diff --git a/test/std/thread/futures/futures.tas/types.pass.cpp b/test/libcxx/thread/futures/futures.task/types.pass.cpp index f7c9b223add1f..cb0fb803c6ab2 100644 --- a/test/std/thread/futures/futures.tas/types.pass.cpp +++ b/test/libcxx/thread/futures/futures.task/types.pass.cpp @@ -16,7 +16,9 @@ // class packaged_task<R(ArgTypes...)> // { // public: -// typedef R result_type; +// typedef R result_type; // extension + +// This is a libc++ extension. #include <future> #include <type_traits> diff --git a/test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp b/test/libcxx/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp index bf28e01a0e861..bf28e01a0e861 100644 --- a/test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp +++ b/test/libcxx/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp diff --git a/test/std/thread/thread.condition/version.pass.cpp b/test/libcxx/thread/thread.condition/version.pass.cpp index 12a775e833982..12a775e833982 100644 --- a/test/std/thread/thread.condition/version.pass.cpp +++ b/test/libcxx/thread/thread.condition/version.pass.cpp diff --git a/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp b/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp new file mode 100644 index 0000000000000..aae0afbffd37a --- /dev/null +++ b/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// TODO(EricWF) Investigate why typeid(...).name() returns a different string +// on GCC 4.9 but not newer GCCs. +// XFAIL: gcc-4.9 + +// THIS TESTS C++03 EXTENSIONS. + +// <mutex> + +// template <class ...Mutex> class lock_guard; + +// Test that the the variadic lock guard implementation mangles the same in +// C++11 and C++03. This is important since the mangling of `lock_guard` depends +// on it being declared as a variadic template, even in C++03. + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include <mutex> +#include <string> +#include <typeinfo> +#include <cassert> + +int main() { + const std::string expect = "NSt3__110lock_guardIJNS_5mutexEEEE"; + assert(typeid(std::lock_guard<std::mutex>).name() == expect); +} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp b/test/libcxx/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp index 12c80f02c340d..12c80f02c340d 100644 --- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp +++ b/test/libcxx/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp b/test/libcxx/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp index 10626bc4072e0..10626bc4072e0 100644 --- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp +++ b/test/libcxx/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp diff --git a/test/libcxx/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp b/test/libcxx/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp new file mode 100644 index 0000000000000..d9ac92c270c30 --- /dev/null +++ b/test/libcxx/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// This test does not define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS so it +// should compile without any warnings or errors even though this pattern is not +// understood by the thread safety annotations. + +#include <mutex> + +int main() { + std::mutex m; + m.lock(); + { + std::unique_lock<std::mutex> g(m, std::adopt_lock); + } +} diff --git a/test/libcxx/thread/thread.mutex/thread_safety_lock_guard.pass.cpp b/test/libcxx/thread/thread.mutex/thread_safety_lock_guard.pass.cpp new file mode 100644 index 0000000000000..4e85a039686a0 --- /dev/null +++ b/test/libcxx/thread/thread.mutex/thread_safety_lock_guard.pass.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: libcpp-has-no-threads +// REQUIRES: thread-safety + +// <mutex> + +#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS + +#include <mutex> + +std::mutex m; +int foo __attribute__((guarded_by(m))); + +int main() { + std::lock_guard<std::mutex> lock(m); + foo++; +} diff --git a/test/libcxx/thread/thread.mutex/thread_safety_lock_unlock.pass.cpp b/test/libcxx/thread/thread.mutex/thread_safety_lock_unlock.pass.cpp new file mode 100644 index 0000000000000..40b97c396ad66 --- /dev/null +++ b/test/libcxx/thread/thread.mutex/thread_safety_lock_unlock.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// REQUIRES: thread-safety + +// <mutex> + +#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS + +#include <mutex> + +std::mutex m; +int foo __attribute__((guarded_by(m))); + +int main() { + m.lock(); + foo++; + m.unlock(); +} diff --git a/test/libcxx/thread/thread.mutex/thread_safety_missing_unlock.fail.cpp b/test/libcxx/thread/thread.mutex/thread_safety_missing_unlock.fail.cpp new file mode 100644 index 0000000000000..c1425c960c005 --- /dev/null +++ b/test/libcxx/thread/thread.mutex/thread_safety_missing_unlock.fail.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: libcpp-has-no-threads +// REQUIRES: thread-safety + +// <mutex> + +#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS + +#include <mutex> + +std::mutex m; + +int main() { + m.lock(); +} // expected-error {{mutex 'm' is still held at the end of function}} diff --git a/test/libcxx/thread/thread.mutex/thread_safety_requires_capability.pass.cpp b/test/libcxx/thread/thread.mutex/thread_safety_requires_capability.pass.cpp new file mode 100644 index 0000000000000..e03f5eabffcfe --- /dev/null +++ b/test/libcxx/thread/thread.mutex/thread_safety_requires_capability.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// REQUIRES: thread-safety + +// <mutex> + +#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS + +#include <mutex> + +std::mutex m; +int foo __attribute__((guarded_by(m))); + +void increment() __attribute__((requires_capability(m))) { + foo++; +} + +int main() { + m.lock(); + increment(); + m.unlock(); +} diff --git a/test/std/thread/thread.mutex/version.pass.cpp b/test/libcxx/thread/thread.mutex/version.pass.cpp index 81b52c79204b8..81b52c79204b8 100644 --- a/test/std/thread/thread.mutex/version.pass.cpp +++ b/test/libcxx/thread/thread.mutex/version.pass.cpp diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp b/test/libcxx/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp index c8807a965c44b..c8807a965c44b 100644 --- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp +++ b/test/libcxx/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp diff --git a/test/std/thread/thread.threads/thread.thread.class/types.pass.cpp b/test/libcxx/thread/thread.threads/thread.thread.class/types.pass.cpp index a5bf77031ccaf..a5bf77031ccaf 100644 --- a/test/std/thread/thread.threads/thread.thread.class/types.pass.cpp +++ b/test/libcxx/thread/thread.threads/thread.thread.class/types.pass.cpp diff --git a/test/std/thread/thread.threads/version.pass.cpp b/test/libcxx/thread/thread.threads/version.pass.cpp index d16b0eb068428..d16b0eb068428 100644 --- a/test/std/thread/thread.threads/version.pass.cpp +++ b/test/libcxx/thread/thread.threads/version.pass.cpp diff --git a/test/std/utilities/function.objects/func.require/bullet_1_and_2.pass.cpp b/test/libcxx/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp index e579f207a33f2..509c751b455dd 100644 --- a/test/std/utilities/function.objects/func.require/bullet_1_and_2.pass.cpp +++ b/test/libcxx/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp @@ -14,12 +14,14 @@ //------------------------------------------------------------------------------ // TESTING INVOKE(f, t1, t2, ..., tN) // - Bullet 1 -- (t1.*f)(t2, ..., tN) -// - Bullet 2 -- ((*t1).*f)(t2, ..., tN) +// - Bullet 2 -- (t1.get().*f)(t2, ..., tN) // t1 is a reference_wrapper +// - Bullet 3 -- ((*t1).*f)(t2, ..., tN) // // Overview: -// Bullets 1 and 2 handle the case where 'f' is a pointer to member function. +// Bullets 1, 2 and 3 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. +// type derived from 'T'. Bullet 2 handles the case where 't1' is a reference +// wrapper and bullet 3 handles all other cases. // // Concerns: // 1) cv-qualified member function signatures are accepted. @@ -31,6 +33,7 @@ // 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. +// 9) reference_wrappers are properly handled and unwrapped. // // // Plan: @@ -123,6 +126,7 @@ private: #endif // TEST_STD_VER >= 11 + //============================================================================== // TestCase - A test case for a single member function. // ClassType - The type of the class being tested. @@ -151,6 +155,8 @@ private: D* der_ptr = &der; DerefToType<T> dref; DerefPropType<T> dref2; + std::reference_wrapper<T> rref(obj); + std::reference_wrapper<D> drref(der); // (Plan-3) Dispatch based on the CV tags. CV tag; @@ -158,9 +164,13 @@ private: runTestDispatch(tag, obj); runTestDispatch(tag, der); runTestDispatch(tag, dref2); - runTestDispatchIf(NotRValue, tag, dref); - runTestDispatchIf(NotRValue, tag, obj_ptr); + runTestDispatchIf(NotRValue, tag, dref); + runTestDispatchIf(NotRValue, tag, obj_ptr); runTestDispatchIf(NotRValue, tag, der_ptr); +#if TEST_STD_VER >= 11 + runTestDispatchIf(NotRValue, tag, rref); + runTestDispatchIf(NotRValue, tag, drref); +#endif } template <class QT, class Tp> @@ -179,27 +189,43 @@ private: template <class Tp> void runTestDispatch(Q_Const, Tp& v) { - Tp const& cv = v; runTest(v); - runTest(cv); + runTest(makeConst(v)); } template <class Tp> void runTestDispatch(Q_Volatile, Tp& v) { - Tp volatile& vv = v; runTest(v); - runTest(vv); + runTest(makeVolatile(v)); + } 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); + runTest(makeConst(v)); + runTest(makeVolatile(v)); + runTest(makeCV(v)); + } + + template <class T> + void runTest(const std::reference_wrapper<T>& 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 T> + void runTest(T* 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 Obj> @@ -221,6 +247,30 @@ template <class Sig, int Arity, class CV, bool RValue = false> struct TestCase11 : public TestCaseImp<MemFun11, Sig, Arity, CV, RValue, true> {}; #endif +template <class Tp> +struct DerivedFromRefWrap : public std::reference_wrapper<Tp> { + DerivedFromRefWrap(Tp& tp) : std::reference_wrapper<Tp>(tp) {} +}; + +#if TEST_STD_VER >= 11 +void test_derived_from_ref_wrap() { + int x = 42; + std::reference_wrapper<int> r(x); + std::reference_wrapper<std::reference_wrapper<int>> r2(r); + DerivedFromRefWrap<int> d(x); + auto get_fn = &std::reference_wrapper<int>::get; + auto& ret = std::__invoke(get_fn, r); + auto& cret = std::__invoke_constexpr(get_fn, r); + assert(&ret == &x); + assert(&cret == &x); + auto& ret2 = std::__invoke(get_fn, d); + auto& cret2 = std::__invoke_constexpr(get_fn, d); + assert(&ret2 == &x); + auto& ret3 = std::__invoke(get_fn, r2); + assert(&ret3 == &x); +} +#endif + int main() { typedef void*& R; typedef ArgType A; @@ -314,5 +364,7 @@ int main() { 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(); + + test_derived_from_ref_wrap(); #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/libcxx/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp index b6fe190bd2a77..803c501f8c9e3 100644 --- a/test/std/utilities/function.objects/func.require/bullet_3_and_4.pass.cpp +++ b/test/libcxx/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp @@ -13,13 +13,15 @@ //------------------------------------------------------------------------------ // TESTING INVOKE(f, t1, t2, ..., tN) -// - Bullet 3 -- t1.*f -// - Bullet 4 -- (*t1).*f +// - Bullet 4 -- t1.*f +// - Bullet 5 -- t1.get().*f // t1 is a reference wrapper. +// - Bullet 6 -- (*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. +// Bullets 4, 5 and 6 handle the case where 'f' is a pointer to member object. +// Bullet 4 only handles the cases where t1 is an object of type T or a +// type derived from 'T'. Bullet 5 handles cases where 't1' is a reference_wrapper +// and bullet 6 handles all other cases. // // Concerns: // 1) The return type is always an lvalue reference. @@ -30,6 +32,7 @@ // 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_wrapper's are properly unwrapped before invoking the function. #include <functional> #include <type_traits> @@ -66,6 +69,8 @@ private: Derived* der_ptr = &der; DerefToType<TestType> dref; DerefPropType<TestType> dref2; + std::reference_wrapper<TestType> rref(obj); + std::reference_wrapper<Derived> drref(der); { typedef ObjectType (TestType::*MemPtr); @@ -74,9 +79,13 @@ private: 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); + runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object); + runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object); +#if TEST_STD_VER >= 11 + runTestPropCVDispatch<E>(M, rref, &(rref.get().object)); + runTestPropCVDispatch<E>(M, drref, &(drref.get().object)); +#endif + runTestNoPropDispatch<E>(M, dref, &dref.object.object); } { typedef ObjectType const (TestType::*CMemPtr); @@ -85,9 +94,13 @@ private: 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); + runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object); + runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object); +#if TEST_STD_VER >= 11 + runTestPropCVDispatch<E>(M, rref, &(rref.get().object)); + runTestPropCVDispatch<E>(M, drref, &(drref.get().object)); +#endif + runTestNoPropDispatch<E>(M, dref, &dref.object.object); } { typedef ObjectType volatile (TestType::*VMemPtr); @@ -96,9 +109,13 @@ private: 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); + runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object); + runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object); +#if TEST_STD_VER >= 11 + runTestPropCVDispatch<E>(M, rref, &(rref.get().object)); + runTestPropCVDispatch<E>(M, drref, &(drref.get().object)); +#endif + runTestNoPropDispatch<E>(M, dref, &dref.object.object); } { typedef ObjectType const volatile (TestType::*CVMemPtr); @@ -107,9 +124,13 @@ private: 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); + runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object); + runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object); +#if TEST_STD_VER >= 11 + runTestPropCVDispatch<E>(M, rref, &(rref.get().object)); + runTestPropCVDispatch<E>(M, drref, &(drref.get().object)); +#endif + runTestNoPropDispatch<E>(M, dref, &dref.object.object); } } @@ -128,7 +149,15 @@ private: } template <class Expect, class Fn, class T> - void runTestPointerDispatch(Fn M, T& obj, ObjectType* expect) { + void runTestPropCVDispatch(Fn M, T& obj, ObjectType* expect) { + runTest<Expect &> (M, obj, expect); + runTest<Expect const&> (M, makeConst(obj), expect); + runTest<Expect volatile&> (M, makeVolatile(obj), expect); + runTest<Expect const volatile&>(M, makeCV(obj), expect); + } + + template <class Expect, class Fn, class T> + void runTestNoPropDispatch(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); @@ -142,19 +171,42 @@ private: } template <class Expect, class Fn, class T> + void runTest(Fn M, const T& obj, ObjectType* expect) { + static_assert((std::is_same< + decltype(std::__invoke(M, obj)), Expect + >::value), ""); + Expect e = std::__invoke(M, obj); + assert(&e == expect); + } + + 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); + { + 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); + } +#if TEST_STD_VER >= 11 + { + static_assert((std::is_same< + decltype(std::__invoke_constexpr(M, std::forward<T>(obj))), Expect + >::value), ""); + Expect e = std::__invoke_constexpr(M, std::forward<T>(obj)); + assert(&e == expect); + } +#endif } }; + + + int main() { TestCase<ArgType>::run(); TestCase<ArgType const>::run(); diff --git a/test/std/utilities/function.objects/func.require/bullet_5.pass.cpp b/test/libcxx/utilities/function.objects/func.require/bullet_7.pass.cpp index 3f3c96a9b9bda..0d14a350c8974 100644 --- a/test/std/utilities/function.objects/func.require/bullet_5.pass.cpp +++ b/test/libcxx/utilities/function.objects/func.require/bullet_7.pass.cpp @@ -13,10 +13,10 @@ //------------------------------------------------------------------------------ // TESTING INVOKE(f, t1, t2, ..., tN) -// - Bullet 5 -- f(t2, ..., tN) +// - Bullet 7 -- f(t2, ..., tN) // // Overview: -// Bullet 5 handles the cases where the first argument is not a member +// Bullet 7 handles the cases where the first argument is not a member // function. // // Concerns: diff --git a/test/std/utilities/function.objects/func.require/invoke.pass.cpp b/test/libcxx/utilities/function.objects/func.require/invoke.pass.cpp index 25681630a80c3..1d4251354dc53 100644 --- a/test/std/utilities/function.objects/func.require/invoke.pass.cpp +++ b/test/libcxx/utilities/function.objects/func.require/invoke.pass.cpp @@ -9,12 +9,10 @@ // [func.require] -// INVOKE -#if __cplusplus < 201103L -int main () {} // no __invoke in C++03 -#else - #include <type_traits> +#include <functional> + +#include "test_macros.h" template <typename T, int N> struct Array @@ -26,10 +24,9 @@ struct Type { Array<char, 1>::type& f1(); Array<char, 2>::type& f2() const; - +#if TEST_STD_VER >= 11 Array<char, 1>::type& g1() &; Array<char, 2>::type& g2() const &; -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES Array<char, 3>::type& g3() &&; Array<char, 4>::type& g4() const &&; #endif @@ -39,12 +36,10 @@ int main() { static_assert(sizeof(std::__invoke(&Type::f1, std::declval<Type >())) == 1, ""); static_assert(sizeof(std::__invoke(&Type::f2, std::declval<Type const >())) == 2, ""); - +#if TEST_STD_VER >= 11 static_assert(sizeof(std::__invoke(&Type::g1, std::declval<Type &>())) == 1, ""); static_assert(sizeof(std::__invoke(&Type::g2, std::declval<Type const &>())) == 2, ""); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES static_assert(sizeof(std::__invoke(&Type::g3, std::declval<Type &&>())) == 3, ""); static_assert(sizeof(std::__invoke(&Type::g4, std::declval<Type const&&>())) == 4, ""); #endif } -#endif diff --git a/test/std/utilities/function.objects/func.require/invoke_helpers.h b/test/libcxx/utilities/function.objects/func.require/invoke_helpers.h index a85b39f371758..7e7a5fd24a627 100644 --- a/test/std/utilities/function.objects/func.require/invoke_helpers.h +++ b/test/libcxx/utilities/function.objects/func.require/invoke_helpers.h @@ -79,6 +79,40 @@ typedef Caster<Q_Const, true> MoveConstCaster; typedef Caster<Q_Volatile, true> MoveVolatileCaster; typedef Caster<Q_CV, true> MoveCVCaster; + +template <class Tp> +Tp const& makeConst(Tp& ref) { return ref; } + +template <class Tp> +Tp const* makeConst(Tp* ptr) { return ptr; } + +template <class Tp> +std::reference_wrapper<const Tp> makeConst(std::reference_wrapper<Tp>& ref) { + return std::reference_wrapper<const Tp>(ref.get()); +} + +template <class Tp> +Tp volatile& makeVolatile(Tp& ref) { return ref; } + +template <class Tp> +Tp volatile* makeVolatile(Tp* ptr) { return ptr; } + +template <class Tp> +std::reference_wrapper<volatile Tp> makeVolatile(std::reference_wrapper<Tp>& ref) { + return std::reference_wrapper<volatile Tp>(ref.get()); +} + +template <class Tp> +Tp const volatile& makeCV(Tp& ref) { return ref; } + +template <class Tp> +Tp const volatile* makeCV(Tp* ptr) { return ptr; } + +template <class Tp> +std::reference_wrapper<const volatile Tp> makeCV(std::reference_wrapper<Tp>& ref) { + return std::reference_wrapper<const volatile Tp>(ref.get()); +} + // A shorter name for 'static_cast' template <class QualType, class Tp> QualType C_(Tp& v) { return static_cast<QualType>(v); }; @@ -237,89 +271,185 @@ private: ArgType a0, a1, a2; //========================================================================== - // BULLET 1 AND 2 TEST METHODS + // BULLET 1, 2 AND 3 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)); + { + 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)); + } +#if TEST_STD_VER >= 11 + { + static_assert((std::is_same< + decltype(std::__invoke_constexpr(ptr, object_cast(object))) + , CallRet>::value), ""); + assert(ID::unchecked_call == false); + CallRet ret = std::__invoke_constexpr(ptr, object_cast(object)); + assert(ID::checkCalled(ret)); + } +#endif } 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)); + { + 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)); + } +#if TEST_STD_VER >= 11 + { + static_assert((std::is_same< + decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0))) + , CallRet>::value), ""); + assert(ID::unchecked_call == false); + CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0)); + assert(ID::checkCalled(ret)); + } +#endif } 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)); + { + 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)); + } +#if TEST_STD_VER >= 11 + { + static_assert((std::is_same< + decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1))) + , CallRet>::value), ""); + assert(ID::unchecked_call == false); + CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)); + assert(ID::checkCalled(ret)); + } +#endif } 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)); + { + 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)); + } +#if TEST_STD_VER >= 11 + { + static_assert((std::is_same< + decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2))) + , CallRet>::value), ""); + assert(ID::unchecked_call == false); + CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)); + assert(ID::checkCalled(ret)); + } +#endif } //========================================================================== - // BULLET 5 TEST METHODS + // BULLET 7 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)); + { + 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)); + } +#if TEST_STD_VER >= 11 + { + static_assert((std::is_same< + decltype(std::__invoke_constexpr(object_cast(object))) + , CallRet>::value), ""); + assert(ID::unchecked_call == false); + CallRet ret = std::__invoke_constexpr(object_cast(object)); + assert(ID::checkCalled(ret)); + } +#endif } 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)); + { + 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)); + } +#if TEST_STD_VER >= 11 + { + static_assert((std::is_same< + decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0))) + , CallRet>::value), ""); + assert(ID::unchecked_call == false); + CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0)); + assert(ID::checkCalled(ret)); + } +#endif } 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)); + { + 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)); + } +#if TEST_STD_VER >= 11 + { + static_assert((std::is_same< + decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1))) + , CallRet>::value), ""); + assert(ID::unchecked_call == false); + CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1)); + assert(ID::checkCalled(ret)); + } +#endif } 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)); + { + 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)); + } +#if TEST_STD_VER >= 11 + { + static_assert((std::is_same< + decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2))) + , CallRet>::value), ""); + assert(ID::unchecked_call == false); + CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)); + assert(ID::checkCalled(ret)); + } +#endif } }; diff --git a/test/std/utilities/function.objects/version.pass.cpp b/test/libcxx/utilities/function.objects/version.pass.cpp index 99d731a74543c..99d731a74543c 100644 --- a/test/std/utilities/function.objects/version.pass.cpp +++ b/test/libcxx/utilities/function.objects/version.pass.cpp diff --git a/test/std/utilities/memory/version.pass.cpp b/test/libcxx/utilities/memory/version.pass.cpp index 790c08a3bd2d9..790c08a3bd2d9 100644 --- a/test/std/utilities/memory/version.pass.cpp +++ b/test/libcxx/utilities/memory/version.pass.cpp diff --git a/test/libcxx/utilities/meta/is_referenceable.pass.cpp b/test/libcxx/utilities/meta/is_referenceable.pass.cpp new file mode 100644 index 0000000000000..42b1f2dc3014b --- /dev/null +++ b/test/libcxx/utilities/meta/is_referenceable.pass.cpp @@ -0,0 +1,193 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// +// + +// __is_referenceable<Tp> +// +// [defns.referenceable] defines "a referenceable type" as: +// An object type, a function type that does not have cv-qualifiers +// or a ref-qualifier, or a reference type. +// + +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +struct Foo {}; + +static_assert((!std::__is_referenceable<void>::value), ""); +static_assert(( std::__is_referenceable<int>::value), ""); +static_assert(( std::__is_referenceable<int[3]>::value), ""); +static_assert(( std::__is_referenceable<int[]>::value), ""); +static_assert(( std::__is_referenceable<int &>::value), ""); +static_assert(( std::__is_referenceable<const int &>::value), ""); +static_assert(( std::__is_referenceable<int *>::value), ""); +static_assert(( std::__is_referenceable<const int *>::value), ""); +static_assert(( std::__is_referenceable<Foo>::value), ""); +static_assert(( std::__is_referenceable<const Foo>::value), ""); +static_assert(( std::__is_referenceable<Foo &>::value), ""); +static_assert(( std::__is_referenceable<const Foo &>::value), ""); +#if TEST_STD_VER >= 11 +static_assert(( std::__is_referenceable<Foo &&>::value), ""); +static_assert(( std::__is_referenceable<const Foo &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<int __attribute__((__vector_size__( 8)))>::value), ""); +static_assert(( std::__is_referenceable<const int __attribute__((__vector_size__( 8)))>::value), ""); +static_assert(( std::__is_referenceable<float __attribute__((__vector_size__(16)))>::value), ""); +static_assert(( std::__is_referenceable<const float __attribute__((__vector_size__(16)))>::value), ""); + +// Functions without cv-qualifiers are referenceable +static_assert(( std::__is_referenceable<void ()>::value), ""); +#if TEST_STD_VER >= 11 +static_assert((!std::__is_referenceable<void () const>::value), ""); +static_assert((!std::__is_referenceable<void () &>::value), ""); +static_assert((!std::__is_referenceable<void () const &>::value), ""); +static_assert((!std::__is_referenceable<void () &&>::value), ""); +static_assert((!std::__is_referenceable<void () const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (int)>::value), ""); +#if TEST_STD_VER >= 11 +static_assert((!std::__is_referenceable<void (int) const>::value), ""); +static_assert((!std::__is_referenceable<void (int) &>::value), ""); +static_assert((!std::__is_referenceable<void (int) const &>::value), ""); +static_assert((!std::__is_referenceable<void (int) &&>::value), ""); +static_assert((!std::__is_referenceable<void (int) const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (int, float)>::value), ""); +#if TEST_STD_VER >= 11 +static_assert((!std::__is_referenceable<void (int, float) const>::value), ""); +static_assert((!std::__is_referenceable<void (int, float) &>::value), ""); +static_assert((!std::__is_referenceable<void (int, float) const &>::value), ""); +static_assert((!std::__is_referenceable<void (int, float) &&>::value), ""); +static_assert((!std::__is_referenceable<void (int, float) const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (int, float, Foo &)>::value), ""); +#if TEST_STD_VER >= 11 +static_assert((!std::__is_referenceable<void (int, float, Foo &) const>::value), ""); +static_assert((!std::__is_referenceable<void (int, float, Foo &) &>::value), ""); +static_assert((!std::__is_referenceable<void (int, float, Foo &) const &>::value), ""); +static_assert((!std::__is_referenceable<void (int, float, Foo &) &&>::value), ""); +static_assert((!std::__is_referenceable<void (int, float, Foo &) const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (...)>::value), ""); +#if TEST_STD_VER >= 11 +static_assert((!std::__is_referenceable<void (...) const>::value), ""); +static_assert((!std::__is_referenceable<void (...) &>::value), ""); +static_assert((!std::__is_referenceable<void (...) const &>::value), ""); +static_assert((!std::__is_referenceable<void (...) &&>::value), ""); +static_assert((!std::__is_referenceable<void (...) const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (int, ...)>::value), ""); +#if TEST_STD_VER >= 11 +static_assert((!std::__is_referenceable<void (int, ...) const>::value), ""); +static_assert((!std::__is_referenceable<void (int, ...) &>::value), ""); +static_assert((!std::__is_referenceable<void (int, ...) const &>::value), ""); +static_assert((!std::__is_referenceable<void (int, ...) &&>::value), ""); +static_assert((!std::__is_referenceable<void (int, ...) const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (int, float, ...)>::value), ""); +#if TEST_STD_VER >= 11 +static_assert((!std::__is_referenceable<void (int, float, ...) const>::value), ""); +static_assert((!std::__is_referenceable<void (int, float, ...) &>::value), ""); +static_assert((!std::__is_referenceable<void (int, float, ...) const &>::value), ""); +static_assert((!std::__is_referenceable<void (int, float, ...) &&>::value), ""); +static_assert((!std::__is_referenceable<void (int, float, ...) const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (int, float, Foo &, ...)>::value), ""); +#if TEST_STD_VER >= 11 +static_assert((!std::__is_referenceable<void (int, float, Foo &, ...) const>::value), ""); +static_assert((!std::__is_referenceable<void (int, float, Foo &, ...) &>::value), ""); +static_assert((!std::__is_referenceable<void (int, float, Foo &, ...) const &>::value), ""); +static_assert((!std::__is_referenceable<void (int, float, Foo &, ...) &&>::value), ""); +static_assert((!std::__is_referenceable<void (int, float, Foo &, ...) const &&>::value), ""); +#endif + +// member functions with or without cv-qualifiers are referenceable +static_assert(( std::__is_referenceable<void (Foo::*)()>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)() const>::value), ""); +#if TEST_STD_VER >= 11 +static_assert(( std::__is_referenceable<void (Foo::*)() &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)() const &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)() &&>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)() const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (Foo::*)(int)>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int) const>::value), ""); +#if TEST_STD_VER >= 11 +static_assert(( std::__is_referenceable<void (Foo::*)(int) &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int) const &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int) &&>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int) const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (Foo::*)(int, float)>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float) const>::value), ""); +#if TEST_STD_VER >= 11 +static_assert(( std::__is_referenceable<void (Foo::*)(int, float) &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float) const &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float) &&>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float) const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, Foo &)>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, Foo &) const>::value), ""); +#if TEST_STD_VER >= 11 +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, Foo &) &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, Foo &) const &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, Foo &) &&>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, Foo &) const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (Foo::*)(...)>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(...) const>::value), ""); +#if TEST_STD_VER >= 11 +static_assert(( std::__is_referenceable<void (Foo::*)(...) &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(...) const &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(...) &&>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(...) const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (Foo::*)(int, ...)>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, ...) const>::value), ""); +#if TEST_STD_VER >= 11 +static_assert(( std::__is_referenceable<void (Foo::*)(int, ...) &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, ...) const &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, ...) &&>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, ...) const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, ...)>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, ...) const>::value), ""); +#if TEST_STD_VER >= 11 +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, ...) &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, ...) const &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, ...) &&>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, ...) const &&>::value), ""); +#endif + +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, Foo &, ...)>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, Foo &, ...) const>::value), ""); +#if TEST_STD_VER >= 11 +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, Foo &, ...) &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, Foo &, ...) const &>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, Foo &, ...) &&>::value), ""); +static_assert(( std::__is_referenceable<void (Foo::*)(int, float, Foo &, ...) const &&>::value), ""); +#endif + +int main () {} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp b/test/libcxx/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp index 1c715e04970c7..1c715e04970c7 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp +++ b/test/libcxx/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp diff --git a/test/std/utilities/meta/version.pass.cpp b/test/libcxx/utilities/meta/version.pass.cpp index 3a1033bbb5605..3a1033bbb5605 100644 --- a/test/std/utilities/meta/version.pass.cpp +++ b/test/libcxx/utilities/meta/version.pass.cpp diff --git a/test/std/utilities/ratio/version.pass.cpp b/test/libcxx/utilities/ratio/version.pass.cpp index 26c455fb0a9ab..26c455fb0a9ab 100644 --- a/test/std/utilities/ratio/version.pass.cpp +++ b/test/libcxx/utilities/ratio/version.pass.cpp diff --git a/test/std/utilities/template.bitset/version.pass.cpp b/test/libcxx/utilities/template.bitset/version.pass.cpp index 5ae984c0092df..5ae984c0092df 100644 --- a/test/std/utilities/template.bitset/version.pass.cpp +++ b/test/libcxx/utilities/template.bitset/version.pass.cpp diff --git a/test/std/utilities/time/version.pass.cpp b/test/libcxx/utilities/time/version.pass.cpp index bfa3f6d6797d9..bfa3f6d6797d9 100644 --- a/test/std/utilities/time/version.pass.cpp +++ b/test/libcxx/utilities/time/version.pass.cpp diff --git a/test/std/utilities/tuple/version.pass.cpp b/test/libcxx/utilities/tuple/version.pass.cpp index 2fdbb5d2784a8..2fdbb5d2784a8 100644 --- a/test/std/utilities/tuple/version.pass.cpp +++ b/test/libcxx/utilities/tuple/version.pass.cpp diff --git a/test/std/utilities/type.index/version.pass.cpp b/test/libcxx/utilities/type.index/version.pass.cpp index 26f462042fd33..26f462042fd33 100644 --- a/test/std/utilities/type.index/version.pass.cpp +++ b/test/libcxx/utilities/type.index/version.pass.cpp diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp new file mode 100644 index 0000000000000..c012ac6265e01 --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <utility> + +// template <class T1, class T2> struct pair + +// Test that we properly provide the old non-trivial copy operations +// when the ABI macro is defined. + +#define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR +#include <utility> +#include <cassert> + +#include "test_macros.h" + +#if TEST_STD_VER >= 11 +struct Dummy { + Dummy(Dummy const&) = delete; + Dummy(Dummy &&) = default; +}; +#endif + +int main() +{ + typedef std::pair<int, short> P; + { + static_assert(std::is_copy_constructible<P>::value, ""); + static_assert(!std::is_trivially_copy_constructible<P>::value, ""); + static_assert(!std::is_trivially_copyable<P>::value, ""); + } +#if TEST_STD_VER >= 11 + { + static_assert(std::is_move_constructible<P>::value, ""); + static_assert(!std::is_trivially_move_constructible<P>::value, ""); + static_assert(!std::is_trivially_copyable<P>::value, ""); + } + { + using P1 = std::pair<Dummy, int>; + // These lines fail because the non-trivial constructors do not provide + // SFINAE. + // static_assert(!std::is_copy_constructible<P1>::value, ""); + // static_assert(!std::is_trivially_copy_constructible<P1>::value, ""); + static_assert(std::is_move_constructible<P1>::value, ""); + static_assert(!std::is_trivially_move_constructible<P1>::value, ""); + static_assert(!std::is_trivially_copyable<P>::value, ""); + } +#endif +} diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp new file mode 100644 index 0000000000000..ec9cc7ec3e020 --- /dev/null +++ b/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp @@ -0,0 +1,147 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// The test fails due to the missing is_trivially_constructible intrinsic. +// XFAIL: gcc-4.9 + +// <utility> + +// template <class T1, class T2> struct pair + +// Test that we properly provide the trivial copy operations by default. + +// FreeBSD provides the old ABI. This test checks the new ABI so we need +// to manually turn it on. +#if defined(__FreeBSD__) +#define _LIBCPP_ABI_UNSTABLE +#endif + +#include <utility> +#include <type_traits> +#include <cstdlib> +#include <cassert> + +#include "test_macros.h" + +#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) +#error Non-trivial ctor ABI macro defined +#endif + +template <class T> +struct HasTrivialABI : std::integral_constant<bool, + std::is_trivially_destructible<T>::value + && (!std::is_copy_constructible<T>::value || std::is_trivially_copy_constructible<T>::value) +#if TEST_STD_VER >= 11 + && (!std::is_move_constructible<T>::value || std::is_trivially_move_constructible<T>::value) +#endif +> {}; + +#if TEST_STD_VER >= 11 +struct NonTrivialDtor { + NonTrivialDtor(NonTrivialDtor const&) = default; + ~NonTrivialDtor(); +}; +NonTrivialDtor::~NonTrivialDtor() {} +static_assert(!HasTrivialABI<NonTrivialDtor>::value, ""); + +struct NonTrivialCopy { + NonTrivialCopy(NonTrivialCopy const&); +}; +NonTrivialCopy::NonTrivialCopy(NonTrivialCopy const&) {} +static_assert(!HasTrivialABI<NonTrivialCopy>::value, ""); + +struct NonTrivialMove { + NonTrivialMove(NonTrivialMove const&) = default; + NonTrivialMove(NonTrivialMove&&); +}; +NonTrivialMove::NonTrivialMove(NonTrivialMove&&) {} +static_assert(!HasTrivialABI<NonTrivialMove>::value, ""); + +struct DeletedCopy { + DeletedCopy(DeletedCopy const&) = delete; + DeletedCopy(DeletedCopy&&) = default; +}; +static_assert(HasTrivialABI<DeletedCopy>::value, ""); + +struct TrivialMove { + TrivialMove(TrivialMove &&) = default; +}; +static_assert(HasTrivialABI<TrivialMove>::value, ""); + +struct Trivial { + Trivial(Trivial const&) = default; +}; +static_assert(HasTrivialABI<Trivial>::value, ""); +#endif + + +int main() +{ + { + typedef std::pair<int, short> P; + static_assert(std::is_copy_constructible<P>::value, ""); + static_assert(HasTrivialABI<P>::value, ""); + } +#if TEST_STD_VER >= 11 + { + typedef std::pair<int, short> P; + static_assert(std::is_move_constructible<P>::value, ""); + static_assert(HasTrivialABI<P>::value, ""); + } + { + using P = std::pair<NonTrivialDtor, int>; + static_assert(!std::is_trivially_destructible<P>::value, ""); + static_assert(std::is_copy_constructible<P>::value, ""); + static_assert(!std::is_trivially_copy_constructible<P>::value, ""); + static_assert(std::is_move_constructible<P>::value, ""); + static_assert(!std::is_trivially_move_constructible<P>::value, ""); + static_assert(!HasTrivialABI<P>::value, ""); + } + { + using P = std::pair<NonTrivialCopy, int>; + static_assert(std::is_copy_constructible<P>::value, ""); + static_assert(!std::is_trivially_copy_constructible<P>::value, ""); + static_assert(std::is_move_constructible<P>::value, ""); + static_assert(!std::is_trivially_move_constructible<P>::value, ""); + static_assert(!HasTrivialABI<P>::value, ""); + } + { + using P = std::pair<NonTrivialMove, int>; + static_assert(std::is_copy_constructible<P>::value, ""); + static_assert(std::is_trivially_copy_constructible<P>::value, ""); + static_assert(std::is_move_constructible<P>::value, ""); + static_assert(!std::is_trivially_move_constructible<P>::value, ""); + static_assert(!HasTrivialABI<P>::value, ""); + } + { + using P = std::pair<DeletedCopy, int>; + static_assert(!std::is_copy_constructible<P>::value, ""); + static_assert(!std::is_trivially_copy_constructible<P>::value, ""); + static_assert(std::is_move_constructible<P>::value, ""); + static_assert(std::is_trivially_move_constructible<P>::value, ""); + static_assert(HasTrivialABI<P>::value, ""); + } + { + using P = std::pair<Trivial, int>; + static_assert(std::is_copy_constructible<P>::value, ""); + static_assert(std::is_trivially_copy_constructible<P>::value, ""); + static_assert(std::is_move_constructible<P>::value, ""); + static_assert(std::is_trivially_move_constructible<P>::value, ""); + static_assert(HasTrivialABI<P>::value, ""); + } + { + using P = std::pair<TrivialMove, int>; + static_assert(!std::is_copy_constructible<P>::value, ""); + static_assert(!std::is_trivially_copy_constructible<P>::value, ""); + static_assert(std::is_move_constructible<P>::value, ""); + static_assert(std::is_trivially_move_constructible<P>::value, ""); + static_assert(HasTrivialABI<P>::value, ""); + } +#endif +} diff --git a/test/std/utilities/utility/version.pass.cpp b/test/libcxx/utilities/utility/version.pass.cpp index 77d145d944574..77d145d944574 100644 --- a/test/std/utilities/utility/version.pass.cpp +++ b/test/libcxx/utilities/utility/version.pass.cpp diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in index fa25834d11109..a1ae90cb479e1 100644 --- a/test/lit.site.cfg.in +++ b/test/lit.site.cfg.in @@ -5,6 +5,8 @@ config.libcxx_src_root = "@LIBCXX_SOURCE_DIR@" config.libcxx_obj_root = "@LIBCXX_BINARY_DIR@" config.cxx_library_root = "@LIBCXX_LIBRARY_DIR@" config.enable_exceptions = "@LIBCXX_ENABLE_EXCEPTIONS@" +config.enable_experimental = "@LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY@" +config.enable_filesystem = "@LIBCXX_ENABLE_FILESYSTEM@" config.enable_rtti = "@LIBCXX_ENABLE_RTTI@" config.enable_shared = "@LIBCXX_ENABLE_SHARED@" config.enable_32bit = "@LIBCXX_BUILD_32_BITS@" @@ -20,6 +22,10 @@ config.generate_coverage = "@LIBCXX_GENERATE_COVERAGE@" config.target_info = "@LIBCXX_TARGET_INFO@" config.executor = "@LIBCXX_EXECUTOR@" config.llvm_unwinder = "@LIBCXXABI_USE_LLVM_UNWINDER@" +config.has_libatomic = "@LIBCXX_HAS_ATOMIC_LIB@" +config.use_libatomic = "@LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB@" + +config.libcxxabi_shared = "@LIBCXXABI_ENABLE_SHARED@" # 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.fill/fill_n.pass.cpp b/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp index 6617cd0916f34..b56d31b9d0db5 100644 --- a/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp +++ b/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp @@ -62,7 +62,7 @@ test_int_array() struct source { source() : i(0) { } - + operator int() const { return i++; } mutable int i; }; diff --git a/test/std/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp b/test/std/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp index 234879149ae3b..449753fc263a0 100644 --- a/test/std/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp +++ b/test/std/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp @@ -61,6 +61,6 @@ int main() random_access_iterator<const int*>(ia+s), random_access_iterator<const int*>(ia), random_access_iterator<const int*>(ia+s-1))); - + #endif } 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 3e1dfd17c3ff9..054bc656cdb1f 100644 --- a/test/std/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp +++ b/test/std/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp @@ -33,7 +33,7 @@ int main() 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]); ((void)sb); // unused in c++11 - + typedef input_iterator<const int*> II; typedef random_access_iterator<const int*> RAI; typedef std::equal_to<int> EQ; @@ -48,7 +48,7 @@ int main() == (std::pair<RAI, RAI>(RAI(ia+3), RAI(ib+3)))); assert(bcp.count() > 0 && bcp.count() < sa); bcp.reset(); - + #ifdef HAS_FOUR_ITERATOR_VERSION assert(std::mismatch(II(ia), II(ia + sa), II(ib), II(ib + sb), EQ()) == (std::pair<II, II>(II(ia+3), II(ib+3)))); diff --git a/test/std/algorithms/alg.sorting/alg.clamp/clamp.comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.clamp/clamp.comp.pass.cpp new file mode 100644 index 0000000000000..3fec12b6b53d9 --- /dev/null +++ b/test/std/algorithms/alg.sorting/alg.clamp/clamp.comp.pass.cpp @@ -0,0 +1,127 @@ +//===----------------------------------------------------------------------===// +// +// 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> +// XFAIL: c++98, c++03, c++11, c++14 + +// template<class T, class Compare> +// const T& +// clamp(const T& v, const T& lo, const T& hi, Compare comp); + +#include <algorithm> +#include <functional> +#include <cassert> + +struct Tag { + Tag() : val(0), tag("Default") {} + Tag(int a, const char *b) : val(a), tag(b) {} + ~Tag() {} + + int val; + const char *tag; + }; + +bool eq(const Tag& rhs, const Tag& lhs) { return rhs.val == lhs.val && rhs.tag == lhs.tag; } +// bool operator==(const Tag& rhs, const Tag& lhs) { return rhs.val == lhs.val; } +bool comp (const Tag& rhs, const Tag& lhs) { return rhs.val < lhs.val; } + + +template <class T, class C> +void +test(const T& v, const T& lo, const T& hi, C c, const T& x) +{ + assert(&std::clamp(v, lo, hi, c) == &x); +} + +int main() +{ + { + int x = 0; + int y = 0; + int z = 0; + test(x, y, z, std::greater<int>(), x); + test(y, x, z, std::greater<int>(), y); + } + { + int x = 0; + int y = 1; + int z = -1; + test(x, y, z, std::greater<int>(), x); + test(y, x, z, std::greater<int>(), x); + } + { + int x = 1; + int y = 0; + int z = 0; + test(x, y, z, std::greater<int>(), y); + test(y, x, z, std::greater<int>(), y); + } + + { +// If they're all the same, we should get the value back. + Tag x{0, "Zero-x"}; + Tag y{0, "Zero-y"}; + Tag z{0, "Zero-z"}; + assert(eq(std::clamp(x, y, z, comp), x)); + assert(eq(std::clamp(y, x, z, comp), y)); + } + + { +// If it's the same as the lower bound, we get the value back. + Tag x{0, "Zero-x"}; + Tag y{0, "Zero-y"}; + Tag z{1, "One-z"}; + assert(eq(std::clamp(x, y, z, comp), x)); + assert(eq(std::clamp(y, x, z, comp), y)); + } + + { +// If it's the same as the upper bound, we get the value back. + Tag x{1, "One-x"}; + Tag y{0, "Zero-y"}; + Tag z{1, "One-z"}; + assert(eq(std::clamp(x, y, z, comp), x)); + assert(eq(std::clamp(z, y, x, comp), z)); + } + + { +// If the value is between, we should get the value back + Tag x{1, "One-x"}; + Tag y{0, "Zero-y"}; + Tag z{2, "Two-z"}; + assert(eq(std::clamp(x, y, z, comp), x)); + assert(eq(std::clamp(y, x, z, comp), x)); + } + + { +// If the value is less than the 'lo', we should get the lo back. + Tag x{0, "Zero-x"}; + Tag y{1, "One-y"}; + Tag z{2, "Two-z"}; + assert(eq(std::clamp(x, y, z, comp), y)); + assert(eq(std::clamp(y, x, z, comp), y)); + } + { +// If the value is greater than 'hi', we should get hi back. + Tag x{2, "Two-x"}; + Tag y{0, "Zero-y"}; + Tag z{1, "One-z"}; + assert(eq(std::clamp(x, y, z, comp), z)); + assert(eq(std::clamp(y, z, x, comp), z)); + } + + { + typedef int T; + constexpr T x = 1; + constexpr T y = 0; + constexpr T z = 0; + static_assert(std::clamp(x, y, z, std::greater<T>()) == y, "" ); + static_assert(std::clamp(y, x, z, std::greater<T>()) == y, "" ); + } +} diff --git a/test/std/algorithms/alg.sorting/alg.clamp/clamp.pass.cpp b/test/std/algorithms/alg.sorting/alg.clamp/clamp.pass.cpp new file mode 100644 index 0000000000000..779c41827c929 --- /dev/null +++ b/test/std/algorithms/alg.sorting/alg.clamp/clamp.pass.cpp @@ -0,0 +1,125 @@ +//===----------------------------------------------------------------------===// +// +// 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> +// XFAIL: c++98, c++03, c++11, c++14 + +// template<class T> +// const T& +// clamp(const T& v, const T& lo, const T& hi); + +#include <algorithm> +#include <cassert> + +struct Tag { + Tag() : val(0), tag("Default") {} + Tag(int a, const char *b) : val(a), tag(b) {} + ~Tag() {} + + int val; + const char *tag; + }; + +bool eq(const Tag& rhs, const Tag& lhs) { return rhs.val == lhs.val && rhs.tag == lhs.tag; } +// bool operator==(const Tag& rhs, const Tag& lhs) { return rhs.val == lhs.val; } +bool operator< (const Tag& rhs, const Tag& lhs) { return rhs.val < lhs.val; } + +template <class T> +void +test(const T& a, const T& lo, const T& hi, const T& x) +{ + assert(&std::clamp(a, lo, hi) == &x); +} + +int main() +{ + { + int x = 0; + int y = 0; + int z = 0; + test(x, y, z, x); + test(y, x, z, y); + } + { + int x = 0; + int y = 1; + int z = 2; + test(x, y, z, y); + test(y, x, z, y); + } + { + int x = 1; + int y = 0; + int z = 1; + test(x, y, z, x); + test(y, x, z, x); + } + + { +// If they're all the same, we should get the value back. + Tag x{0, "Zero-x"}; + Tag y{0, "Zero-y"}; + Tag z{0, "Zero-z"}; + assert(eq(std::clamp(x, y, z), x)); + assert(eq(std::clamp(y, x, z), y)); + } + + { +// If it's the same as the lower bound, we get the value back. + Tag x{0, "Zero-x"}; + Tag y{0, "Zero-y"}; + Tag z{1, "One-z"}; + assert(eq(std::clamp(x, y, z), x)); + assert(eq(std::clamp(y, x, z), y)); + } + + { +// If it's the same as the upper bound, we get the value back. + Tag x{1, "One-x"}; + Tag y{0, "Zero-y"}; + Tag z{1, "One-z"}; + assert(eq(std::clamp(x, y, z), x)); + assert(eq(std::clamp(z, y, x), z)); + } + + { +// If the value is between, we should get the value back + Tag x{1, "One-x"}; + Tag y{0, "Zero-y"}; + Tag z{2, "Two-z"}; + assert(eq(std::clamp(x, y, z), x)); + assert(eq(std::clamp(y, x, z), x)); + } + + { +// If the value is less than the 'lo', we should get the lo back. + Tag x{0, "Zero-x"}; + Tag y{1, "One-y"}; + Tag z{2, "Two-z"}; + assert(eq(std::clamp(x, y, z), y)); + assert(eq(std::clamp(y, x, z), y)); + } + { +// If the value is greater than 'hi', we should get hi back. + Tag x{2, "Two-x"}; + Tag y{0, "Zero-y"}; + Tag z{1, "One-z"}; + assert(eq(std::clamp(x, y, z), z)); + assert(eq(std::clamp(y, z, x), z)); + } + + { + typedef int T; + constexpr T x = 1; + constexpr T y = 0; + constexpr T z = 1; + static_assert(std::clamp(x, y, z) == x, "" ); + static_assert(std::clamp(y, x, z) == x, "" ); + } +} diff --git a/test/std/algorithms/alg.sorting/alg.heap.operations/make.heap/make_heap_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.heap.operations/make.heap/make_heap_comp.pass.cpp index 4cde1a7d32ebb..0e16d9bd17c71 100644 --- a/test/std/algorithms/alg.sorting/alg.heap.operations/make.heap/make_heap_comp.pass.cpp +++ b/test/std/algorithms/alg.sorting/alg.heap.operations/make.heap/make_heap_comp.pass.cpp @@ -69,7 +69,7 @@ void test(unsigned N) std::random_shuffle(ia, ia+N); std::make_heap(ia, ia+N, std::ref(pred)); assert(pred.count() <= 3*N); - assert(std::is_heap(ia, ia+N, pred)); + assert(std::is_heap(ia, ia+N, pred)); } delete [] ia; 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 829157353fb3f..9c411730196c8 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 @@ -24,20 +24,20 @@ 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 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 ca6f8e40cbd34..b4d25a93e50e5 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 @@ -34,21 +34,21 @@ struct indirect_less 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_; }; 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 2197b97d7f2a1..3ecc250a9c8f7 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,13 +57,13 @@ test() test<Iter>(1000); } -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 }; #endif void constexpr_test() { -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 constexpr auto p = std::max_element(il,il+8); static_assert ( *p == 8, "" ); #endif @@ -75,6 +75,6 @@ int main() 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 37c181393aa61..fc88268aa84bf 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,14 +75,14 @@ void test_eq() delete [] a; } -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 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 +#if TEST_STD_VER >= 14 constexpr auto p = std::max_element(il, il+8, less()); static_assert ( *p == 8, "" ); #endif @@ -95,6 +95,6 @@ int main() 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 a9a9d61340f91..45dd54b1ee406 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,13 +57,13 @@ test() test<Iter>(1000); } -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 }; #endif void constexpr_test() { -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 constexpr auto p = std::min_element(il, il+8); static_assert ( *p == 1, "" ); #endif 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 9517f7eac945a..94ef482ddbdec 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,14 +75,14 @@ void test_eq() delete [] a; } -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 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 +#if TEST_STD_VER >= 14 constexpr auto p = std::min_element(il, il+8, less()); static_assert(*p == 1, ""); #endif @@ -95,6 +95,6 @@ int main() 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.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/minmax.pass.cpp index 6ac972a2547bf..8276c3a5dfd5a 100644 --- a/test/std/algorithms/alg.sorting/alg.min.max/minmax.pass.cpp +++ b/test/std/algorithms/alg.sorting/alg.min.max/minmax.pass.cpp @@ -47,7 +47,7 @@ int main() } #if _LIBCPP_STD_VER > 11 { -// Note that you can't take a reference to a local var, since +// Note that you can't take a reference to a local var, since // its address is not a compile-time constant. constexpr static int x = 1; constexpr static int y = 0; diff --git a/test/std/algorithms/alg.sorting/alg.min.max/minmax_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/minmax_comp.pass.cpp index 771c8f84a7400..3289f8a7582c9 100644 --- a/test/std/algorithms/alg.sorting/alg.min.max/minmax_comp.pass.cpp +++ b/test/std/algorithms/alg.sorting/alg.min.max/minmax_comp.pass.cpp @@ -50,7 +50,7 @@ int main() } #if _LIBCPP_STD_VER > 11 { -// Note that you can't take a reference to a local var, since +// Note that you can't take a reference to a local var, since // its address is not a compile-time constant. constexpr static int x = 1; constexpr static int y = 0; 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 915b1d176ab43..ef5474091db59 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,13 +74,13 @@ test() } } -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 }; #endif void constexpr_test() { -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 constexpr auto p = std::minmax_element(il, il+8); static_assert ( *(p.first) == 1, "" ); static_assert ( *(p.second) == 8, "" ); @@ -93,6 +93,6 @@ int main() 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 d3a067fda3c5c..3a0c2dbbba1ba 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,14 +79,14 @@ test() } } -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 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 +#if TEST_STD_VER >= 14 constexpr auto p = std::minmax_element(il, il+8, less()); static_assert ( *(p.first) == 1, "" ); static_assert ( *(p.second) == 8, "" ); @@ -99,6 +99,6 @@ int main() 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_init_list_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/minmax_init_list_comp.pass.cpp index a66b2ff27cb0e..789ccef0fca49 100644 --- a/test/std/algorithms/alg.sorting/alg.min.max/minmax_init_list_comp.pass.cpp +++ b/test/std/algorithms/alg.sorting/alg.min.max/minmax_init_list_comp.pass.cpp @@ -21,7 +21,7 @@ #include "counting_predicates.hpp" -bool all_equal(int a, int b) { return false; } // everything is equal +bool all_equal(int, int) { return false; } // everything is equal #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS void test_all_equal(std::initializer_list<int> il) diff --git a/test/std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort.pass.cpp b/test/std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort.pass.cpp index 7bb43461cba4c..62458eca93027 100644 --- a/test/std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort.pass.cpp +++ b/test/std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort.pass.cpp @@ -22,13 +22,17 @@ void test_larger_sorts(unsigned N, unsigned M) { assert(N != 0); + assert(N >= M); int* array = new int[N]; for (int i = 0; i < N; ++i) array[i] = i; std::random_shuffle(array, array+N); std::partial_sort(array, array+M, array+N); for (int i = 0; i < M; ++i) + { + assert(i < N); // quiet analysis warnings assert(array[i] == i); + } delete [] array; } diff --git a/test/std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort_comp.pass.cpp index d822f6c388c1a..0289cf8391f97 100644 --- a/test/std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort_comp.pass.cpp +++ b/test/std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort_comp.pass.cpp @@ -35,13 +35,17 @@ void test_larger_sorts(unsigned N, unsigned M) { assert(N != 0); + assert(N >= M); int* array = new int[N]; for (int i = 0; i < N; ++i) array[i] = i; std::random_shuffle(array, array+N); std::partial_sort(array, array+M, array+N, std::greater<int>()); for (int i = 0; i < M; ++i) + { + assert(i < N); // quiet analysis warnings assert(array[i] == N-i-1); + } delete [] array; } @@ -62,6 +66,7 @@ test_larger_sorts(unsigned N) int main() { + { int i = 0; std::partial_sort(&i, &i, &i); assert(i == 0); @@ -73,6 +78,7 @@ int main() test_larger_sorts(997); test_larger_sorts(1000); test_larger_sorts(1009); + } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { 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 3a74e13faf19d..22bbbd6af5359 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,15 @@ int main() { { - std::atomic_flag f(false); + std::atomic_flag f; + f.clear(); f.test_and_set(); atomic_flag_clear(&f); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f(false); + volatile std::atomic_flag f; + f.clear(); 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 0467384455ccc..1a212c6f352a1 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,38 +22,44 @@ int main() { { - std::atomic_flag f(false); - f.test_and_set(); + std::atomic_flag f; // uninitialized first + atomic_flag_clear_explicit(&f, std::memory_order_relaxed); + assert(f.test_and_set() == 0); atomic_flag_clear_explicit(&f, std::memory_order_relaxed); assert(f.test_and_set() == 0); } { - std::atomic_flag f(false); - f.test_and_set(); + std::atomic_flag f; + atomic_flag_clear_explicit(&f, std::memory_order_release); + assert(f.test_and_set() == 0); atomic_flag_clear_explicit(&f, std::memory_order_release); assert(f.test_and_set() == 0); } { - std::atomic_flag f(false); - f.test_and_set(); + std::atomic_flag f; + atomic_flag_clear_explicit(&f, std::memory_order_seq_cst); + assert(f.test_and_set() == 0); atomic_flag_clear_explicit(&f, std::memory_order_seq_cst); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f(false); - f.test_and_set(); + volatile std::atomic_flag f; + atomic_flag_clear_explicit(&f, std::memory_order_relaxed); + assert(f.test_and_set() == 0); atomic_flag_clear_explicit(&f, std::memory_order_relaxed); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f(false); - f.test_and_set(); + volatile std::atomic_flag f; + atomic_flag_clear_explicit(&f, std::memory_order_release); + assert(f.test_and_set() == 0); atomic_flag_clear_explicit(&f, std::memory_order_release); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f(false); - f.test_and_set(); + volatile std::atomic_flag f; + atomic_flag_clear_explicit(&f, std::memory_order_seq_cst); + assert(f.test_and_set() == 0); 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 ea5ae45ae99a0..255af8f176ea6 100644 --- a/test/std/atomics/atomics.flag/clear.pass.cpp +++ b/test/std/atomics/atomics.flag/clear.pass.cpp @@ -22,50 +22,58 @@ int main() { { - std::atomic_flag f(false); - f.test_and_set(); + std::atomic_flag f; // uninitialized + f.clear(); + assert(f.test_and_set() == 0); f.clear(); assert(f.test_and_set() == 0); } { - std::atomic_flag f(false); - f.test_and_set(); + std::atomic_flag f; + f.clear(std::memory_order_relaxed); + assert(f.test_and_set() == 0); f.clear(std::memory_order_relaxed); assert(f.test_and_set() == 0); } { - std::atomic_flag f(false); - f.test_and_set(); + std::atomic_flag f; + f.clear(std::memory_order_release); + assert(f.test_and_set() == 0); f.clear(std::memory_order_release); assert(f.test_and_set() == 0); } { - std::atomic_flag f(false); - f.test_and_set(); + std::atomic_flag f; + f.clear(std::memory_order_seq_cst); + assert(f.test_and_set() == 0); f.clear(std::memory_order_seq_cst); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f(false); - f.test_and_set(); + volatile std::atomic_flag f; + f.clear(); + assert(f.test_and_set() == 0); f.clear(); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f(false); - f.test_and_set(); + volatile std::atomic_flag f; + f.clear(std::memory_order_relaxed); + assert(f.test_and_set() == 0); f.clear(std::memory_order_relaxed); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f(false); - f.test_and_set(); + volatile std::atomic_flag f; + f.clear(std::memory_order_release); + assert(f.test_and_set() == 0); f.clear(std::memory_order_release); assert(f.test_and_set() == 0); } { - volatile std::atomic_flag f(false); - f.test_and_set(); + volatile std::atomic_flag f; + f.clear(std::memory_order_seq_cst); + assert(f.test_and_set() == 0); f.clear(std::memory_order_seq_cst); assert(f.test_and_set() == 0); } diff --git a/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp b/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp new file mode 100644 index 0000000000000..e42e9f28448a6 --- /dev/null +++ b/test/std/atomics/atomics.lockfree/isalwayslockfree.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: libcpp-has-no-threads, c++98, c++03, c++11, c++14 + +// <atomic> + +// static constexpr bool is_always_lock_free; + +#include <atomic> +#include <cassert> + +#if !defined(__cpp_lib_atomic_is_always_lock_free) +# error Feature test macro missing. +#endif + +template <typename T> void checkAlwaysLockFree() { + if (std::atomic<T>::is_always_lock_free) + assert(std::atomic<T>().is_lock_free()); +} + +int main() +{ +// structs and unions can't be defined in the template invocation. +// Work around this with a typedef. +#define CHECK_ALWAYS_LOCK_FREE(T) \ + do { \ + typedef T type; \ + checkAlwaysLockFree<type>(); \ + } while (0) + + CHECK_ALWAYS_LOCK_FREE(bool); + CHECK_ALWAYS_LOCK_FREE(char); + CHECK_ALWAYS_LOCK_FREE(signed char); + CHECK_ALWAYS_LOCK_FREE(unsigned char); + CHECK_ALWAYS_LOCK_FREE(char16_t); + CHECK_ALWAYS_LOCK_FREE(char32_t); + CHECK_ALWAYS_LOCK_FREE(wchar_t); + CHECK_ALWAYS_LOCK_FREE(short); + CHECK_ALWAYS_LOCK_FREE(unsigned short); + CHECK_ALWAYS_LOCK_FREE(int); + CHECK_ALWAYS_LOCK_FREE(unsigned int); + CHECK_ALWAYS_LOCK_FREE(long); + CHECK_ALWAYS_LOCK_FREE(unsigned long); + CHECK_ALWAYS_LOCK_FREE(long long); + CHECK_ALWAYS_LOCK_FREE(unsigned long long); + CHECK_ALWAYS_LOCK_FREE(std::nullptr_t); + CHECK_ALWAYS_LOCK_FREE(void*); + CHECK_ALWAYS_LOCK_FREE(float); + CHECK_ALWAYS_LOCK_FREE(double); + CHECK_ALWAYS_LOCK_FREE(long double); + CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(1 * sizeof(int))))); + CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(2 * sizeof(int))))); + CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(4 * sizeof(int))))); + CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(16 * sizeof(int))))); + CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(32 * sizeof(int))))); + CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(1 * sizeof(float))))); + CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(2 * sizeof(float))))); + CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(4 * sizeof(float))))); + CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(16 * sizeof(float))))); + CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(32 * sizeof(float))))); + CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(1 * sizeof(double))))); + CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(2 * sizeof(double))))); + CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(4 * sizeof(double))))); + CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(16 * sizeof(double))))); + CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(32 * sizeof(double))))); + CHECK_ALWAYS_LOCK_FREE(struct Empty {}); + CHECK_ALWAYS_LOCK_FREE(struct OneInt { int i; }); + CHECK_ALWAYS_LOCK_FREE(struct IntArr2 { int i[2]; }); + CHECK_ALWAYS_LOCK_FREE(struct LLIArr2 { long long int i[2]; }); + CHECK_ALWAYS_LOCK_FREE(struct LLIArr4 { long long int i[4]; }); + CHECK_ALWAYS_LOCK_FREE(struct LLIArr8 { long long int i[8]; }); + CHECK_ALWAYS_LOCK_FREE(struct LLIArr16 { long long int i[16]; }); + CHECK_ALWAYS_LOCK_FREE(struct Padding { char c; /* padding */ long long int i; }); + CHECK_ALWAYS_LOCK_FREE(union IntFloat { int i; float f; }); + + // C macro and static constexpr must be consistent. + static_assert(std::atomic<bool>::is_always_lock_free == (2 == ATOMIC_BOOL_LOCK_FREE)); + static_assert(std::atomic<char>::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE)); + static_assert(std::atomic<signed char>::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE)); + static_assert(std::atomic<unsigned char>::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE)); + static_assert(std::atomic<char16_t>::is_always_lock_free == (2 == ATOMIC_CHAR16_T_LOCK_FREE)); + static_assert(std::atomic<char32_t>::is_always_lock_free == (2 == ATOMIC_CHAR32_T_LOCK_FREE)); + static_assert(std::atomic<wchar_t>::is_always_lock_free == (2 == ATOMIC_WCHAR_T_LOCK_FREE)); + static_assert(std::atomic<short>::is_always_lock_free == (2 == ATOMIC_SHORT_LOCK_FREE)); + static_assert(std::atomic<unsigned short>::is_always_lock_free == (2 == ATOMIC_SHORT_LOCK_FREE)); + static_assert(std::atomic<int>::is_always_lock_free == (2 == ATOMIC_INT_LOCK_FREE)); + static_assert(std::atomic<unsigned int>::is_always_lock_free == (2 == ATOMIC_INT_LOCK_FREE)); + static_assert(std::atomic<long>::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE)); + static_assert(std::atomic<unsigned long>::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE)); + static_assert(std::atomic<long long>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE)); + static_assert(std::atomic<unsigned long long>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE)); + static_assert(std::atomic<void*>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE)); + static_assert(std::atomic<std::nullptr_t>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE)); +} diff --git a/test/std/atomics/atomics.lockfree/lockfree.pass.cpp b/test/std/atomics/atomics.lockfree/lockfree.pass.cpp index a975a69a66ff7..0ace9cfe7ba37 100644 --- a/test/std/atomics/atomics.lockfree/lockfree.pass.cpp +++ b/test/std/atomics/atomics.lockfree/lockfree.pass.cpp @@ -11,6 +11,7 @@ // <atomic> +// #define ATOMIC_BOOL_LOCK_FREE unspecified // #define ATOMIC_CHAR_LOCK_FREE unspecified // #define ATOMIC_CHAR16_T_LOCK_FREE unspecified // #define ATOMIC_CHAR32_T_LOCK_FREE unspecified @@ -19,12 +20,16 @@ // #define ATOMIC_INT_LOCK_FREE unspecified // #define ATOMIC_LONG_LOCK_FREE unspecified // #define ATOMIC_LLONG_LOCK_FREE unspecified +// #define ATOMIC_POINTER_LOCK_FREE unspecified #include <atomic> #include <cassert> int main() { + assert(ATOMIC_BOOL_LOCK_FREE == 0 || + ATOMIC_BOOL_LOCK_FREE == 1 || + ATOMIC_BOOL_LOCK_FREE == 2); assert(ATOMIC_CHAR_LOCK_FREE == 0 || ATOMIC_CHAR_LOCK_FREE == 1 || ATOMIC_CHAR_LOCK_FREE == 2); @@ -49,4 +54,7 @@ int main() assert(ATOMIC_LLONG_LOCK_FREE == 0 || ATOMIC_LLONG_LOCK_FREE == 1 || ATOMIC_LLONG_LOCK_FREE == 2); + assert(ATOMIC_POINTER_LOCK_FREE == 0 || + ATOMIC_POINTER_LOCK_FREE == 1 || + ATOMIC_POINTER_LOCK_FREE == 2); } diff --git a/test/std/atomics/atomics.types.generic/address.pass.cpp b/test/std/atomics/atomics.types.generic/address.pass.cpp index eceac25c9d94c..137e46b6a1555 100644 --- a/test/std/atomics/atomics.types.generic/address.pass.cpp +++ b/test/std/atomics/atomics.types.generic/address.pass.cpp @@ -45,13 +45,13 @@ // T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst); // T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile; // T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst); -// +// // atomic() = default; // constexpr atomic(T* desr); // atomic(const atomic&) = delete; // atomic& operator=(const atomic&) = delete; // atomic& operator=(const atomic&) volatile = delete; -// +// // T* operator=(T*) volatile; // T* operator=(T*); // T* operator++(int) volatile; @@ -122,8 +122,8 @@ do_test() { _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {23}; - A& zero = *new (storage) A(); - assert(zero == 0); + A& zero = *new (storage) A(); + assert(zero == T(0)); zero.~A(); } } diff --git a/test/std/atomics/atomics.types.generic/bool.pass.cpp b/test/std/atomics/atomics.types.generic/bool.pass.cpp index 8eb04ee577cfc..e85893d12b8dd 100644 --- a/test/std/atomics/atomics.types.generic/bool.pass.cpp +++ b/test/std/atomics/atomics.types.generic/bool.pass.cpp @@ -39,7 +39,7 @@ // memory_order m = memory_order_seq_cst) volatile; // bool compare_exchange_strong(T& expc, T desr, // memory_order m = memory_order_seq_cst); -// +// // atomic() = default; // constexpr atomic(T desr); // atomic(const atomic&) = delete; @@ -227,7 +227,7 @@ int main() { typedef std::atomic<bool> A; _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {1}; - A& zero = *new (storage) A(); + A& zero = *new (storage) A(); assert(zero == false); zero.~A(); } diff --git a/test/std/atomics/atomics.types.generic/cstdint_typedefs.pass.cpp b/test/std/atomics/atomics.types.generic/cstdint_typedefs.pass.cpp index a7874b9f5af42..714fbdc3926b6 100644 --- a/test/std/atomics/atomics.types.generic/cstdint_typedefs.pass.cpp +++ b/test/std/atomics/atomics.types.generic/cstdint_typedefs.pass.cpp @@ -19,7 +19,7 @@ // typedef atomic<uint_least32_t> atomic_uint_least32_t; // typedef atomic<int_least64_t> atomic_int_least64_t; // typedef atomic<uint_least64_t> atomic_uint_least64_t; -// +// // typedef atomic<int_fast8_t> atomic_int_fast8_t; // typedef atomic<uint_fast8_t> atomic_uint_fast8_t; // typedef atomic<int_fast16_t> atomic_int_fast16_t; @@ -28,7 +28,7 @@ // typedef atomic<uint_fast32_t> atomic_uint_fast32_t; // typedef atomic<int_fast64_t> atomic_int_fast64_t; // typedef atomic<uint_fast64_t> atomic_uint_fast64_t; -// +// // typedef atomic<intptr_t> atomic_intptr_t; // typedef atomic<uintptr_t> atomic_uintptr_t; // typedef atomic<size_t> atomic_size_t; diff --git a/test/std/atomics/atomics.types.generic/integral.pass.cpp b/test/std/atomics/atomics.types.generic/integral.pass.cpp index 802a37c30a935..a449dc6d5f57b 100644 --- a/test/std/atomics/atomics.types.generic/integral.pass.cpp +++ b/test/std/atomics/atomics.types.generic/integral.pass.cpp @@ -41,7 +41,7 @@ // memory_order m = memory_order_seq_cst) volatile; // bool compare_exchange_strong(integral& expc, integral desr, // memory_order m = memory_order_seq_cst); -// +// // integral // fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile; // integral fetch_add(integral op, memory_order m = memory_order_seq_cst); @@ -57,7 +57,7 @@ // integral // fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile; // integral fetch_xor(integral op, memory_order m = memory_order_seq_cst); -// +// // atomic() = default; // constexpr atomic(integral desr); // atomic(const atomic&) = delete; @@ -65,7 +65,7 @@ // atomic& operator=(const atomic&) volatile = delete; // integral operator=(integral desr) volatile; // integral operator=(integral desr); -// +// // integral operator++(int) volatile; // integral operator++(int); // integral operator--(int) volatile; @@ -152,7 +152,7 @@ do_test() { _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {23}; - A& zero = *new (storage) A(); + A& zero = *new (storage) A(); assert(zero == 0); zero.~A(); } @@ -185,6 +185,15 @@ int main() #endif // _LIBCPP_HAS_NO_UNICODE_CHARS test<std::atomic_wchar_t, wchar_t>(); + test<std::atomic_int8_t, int8_t>(); + test<std::atomic_uint8_t, uint8_t>(); + test<std::atomic_int16_t, int16_t>(); + test<std::atomic_uint16_t, uint16_t>(); + test<std::atomic_int32_t, int32_t>(); + test<std::atomic_uint32_t, uint32_t>(); + test<std::atomic_int64_t, int64_t>(); + test<std::atomic_uint64_t, uint64_t>(); + test<volatile std::atomic_char, char>(); test<volatile std::atomic_schar, signed char>(); test<volatile std::atomic_uchar, unsigned char>(); @@ -201,4 +210,13 @@ int main() test<volatile std::atomic_char32_t, char32_t>(); #endif // _LIBCPP_HAS_NO_UNICODE_CHARS test<volatile std::atomic_wchar_t, wchar_t>(); + + test<volatile std::atomic_int8_t, int8_t>(); + test<volatile std::atomic_uint8_t, uint8_t>(); + test<volatile std::atomic_int16_t, int16_t>(); + test<volatile std::atomic_uint16_t, uint16_t>(); + test<volatile std::atomic_int32_t, int32_t>(); + test<volatile std::atomic_uint32_t, uint32_t>(); + test<volatile std::atomic_int64_t, int64_t>(); + test<volatile std::atomic_uint64_t, uint64_t>(); } diff --git a/test/std/atomics/atomics.types.generic/integral_typedefs.pass.cpp b/test/std/atomics/atomics.types.generic/integral_typedefs.pass.cpp index e8fae85fb4b3b..e4deae1bf0d57 100644 --- a/test/std/atomics/atomics.types.generic/integral_typedefs.pass.cpp +++ b/test/std/atomics/atomics.types.generic/integral_typedefs.pass.cpp @@ -25,6 +25,18 @@ // typedef atomic<char16_t> atomic_char16_t; // typedef atomic<char32_t> atomic_char32_t; // typedef atomic<wchar_t> atomic_wchar_t; +// +// typedef atomic<intptr_t> atomic_intptr_t; +// typedef atomic<uintptr_t> atomic_uintptr_t; +// +// typedef atomic<int8_t> atomic_int8_t; +// typedef atomic<uint8_t> atomic_uint8_t; +// typedef atomic<int16_t> atomic_int16_t; +// typedef atomic<uint16_t> atomic_uint16_t; +// typedef atomic<int32_t> atomic_int32_t; +// typedef atomic<uint32_t> atomic_uint32_t; +// typedef atomic<int64_t> atomic_int64_t; +// typedef atomic<uint64_t> atomic_uint64_t; #include <atomic> #include <type_traits> @@ -47,4 +59,17 @@ int main() static_assert((std::is_same<std::atomic<char16_t>, std::atomic_char16_t>::value), ""); static_assert((std::is_same<std::atomic<char32_t>, std::atomic_char32_t>::value), ""); #endif // _LIBCPP_HAS_NO_UNICODE_CHARS + +// Added by LWG 2441 + static_assert((std::is_same<std::atomic<intptr_t>, std::atomic_intptr_t>::value), ""); + static_assert((std::is_same<std::atomic<uintptr_t>, std::atomic_uintptr_t>::value), ""); + + static_assert((std::is_same<std::atomic<int8_t>, std::atomic_int8_t>::value), ""); + static_assert((std::is_same<std::atomic<uint8_t>, std::atomic_uint8_t>::value), ""); + static_assert((std::is_same<std::atomic<int16_t>, std::atomic_int16_t>::value), ""); + static_assert((std::is_same<std::atomic<uint16_t>, std::atomic_uint16_t>::value), ""); + static_assert((std::is_same<std::atomic<int32_t>, std::atomic_int32_t>::value), ""); + static_assert((std::is_same<std::atomic<uint32_t>, std::atomic_uint32_t>::value), ""); + static_assert((std::is_same<std::atomic<int64_t>, std::atomic_int64_t>::value), ""); + static_assert((std::is_same<std::atomic<uint64_t>, std::atomic_uint64_t>::value), ""); } diff --git a/test/std/atomics/atomics.types.generic/trivially_copyable.fail.cpp b/test/std/atomics/atomics.types.generic/trivially_copyable.fail.cpp index d940980e32f06..1309f3f1b78b6 100644 --- a/test/std/atomics/atomics.types.generic/trivially_copyable.fail.cpp +++ b/test/std/atomics/atomics.types.generic/trivially_copyable.fail.cpp @@ -37,7 +37,7 @@ // memory_order m = memory_order_seq_cst) volatile noexcept; // bool compare_exchange_strong(T& expc, T desr, // memory_order m = memory_order_seq_cst) noexcept; -// +// // atomic() noexcept = default; // constexpr atomic(T desr) noexcept; // atomic(const atomic&) = delete; diff --git a/test/std/atomics/atomics.types.generic/trivially_copyable.pass.cpp b/test/std/atomics/atomics.types.generic/trivially_copyable.pass.cpp index 5b094f0a89c1d..622643f216bdb 100644 --- a/test/std/atomics/atomics.types.generic/trivially_copyable.pass.cpp +++ b/test/std/atomics/atomics.types.generic/trivially_copyable.pass.cpp @@ -43,7 +43,7 @@ // memory_order m = memory_order_seq_cst) volatile noexcept; // bool compare_exchange_strong(T& expc, T desr, // memory_order m = memory_order_seq_cst) noexcept; -// +// // atomic() noexcept = default; // constexpr atomic(T desr) noexcept; // atomic(const atomic&) = delete; diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp index 7b221dc6eff80..e40979f45a8f2 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp @@ -15,7 +15,7 @@ // template <class T> // bool // atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr); -// +// // template <class T> // bool // atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp index 27de5bec49287..8ac8fc0c2d0f2 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp @@ -17,7 +17,7 @@ // atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj, T* expc, // T desr, // memory_order s, memory_order f); -// +// // template <class T> // bool // atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc, T desr, diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp index 8c12715647e8d..da0f5c3de43bf 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp @@ -15,7 +15,7 @@ // template <class T> // bool // atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr); -// +// // template <class T> // bool // atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp index 90a93f02b978d..b70446bdf7f28 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp @@ -17,7 +17,7 @@ // atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc, // T desr, // memory_order s, memory_order f); -// +// // template <class T> // bool // atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr, diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp index 035d974427a4a..680fe8f8287b0 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp @@ -15,7 +15,7 @@ // template <class T> // T // atomic_exchange(volatile atomic<T>* obj, T desr); -// +// // template <class T> // T // atomic_exchange(atomic<T>* obj, T desr); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp index 4d66bb5f3b812..0df4033c8ba73 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp @@ -15,7 +15,7 @@ // template <class T> // T // atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m); -// +// // template <class T> // T // atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp index 48ff601539cf7..e30543bdbf45a 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp @@ -15,15 +15,15 @@ // template <class Integral> // Integral // atomic_fetch_add(volatile atomic<Integral>* obj, Integral op); -// +// // template <class Integral> // Integral // atomic_fetch_add(atomic<Integral>* obj, Integral op); -// +// // template <class T> // T* // atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op); -// +// // template <class T> // T* // atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp index 57355d30411e9..e101029bdaccb 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp @@ -14,7 +14,7 @@ // template <class Integral> // Integral // atomic_fetch_and(volatile atomic<Integral>* obj, Integral op); -// +// // template <class Integral> // Integral // atomic_fetch_and(atomic<Integral>* obj, Integral op); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp index 26ff5f65e7dbf..7180c14d4ba2b 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp @@ -14,7 +14,7 @@ // template <class Integral> // Integral // atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op); -// +// // template <class Integral> // Integral // atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp index ca44fdc3217d2..241026bcf68cb 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp @@ -14,7 +14,7 @@ // template <class Integral> // Integral // atomic_fetch_or(volatile atomic<Integral>* obj, Integral op); -// +// // template <class Integral> // Integral // atomic_fetch_or(atomic<Integral>* obj, Integral op); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp index 72bbde798cb92..c7e0b1232cf2f 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp @@ -14,7 +14,7 @@ // template <class Integral> // Integral // atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op); -// +// // template <class Integral> // Integral // atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp index 2743040428c5d..e1b12647452be 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp @@ -15,15 +15,15 @@ // template <class Integral> // Integral // atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op); -// +// // template <class Integral> // Integral // atomic_fetch_sub(atomic<Integral>* obj, Integral op); -// +// // template <class T> // T* // atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op); -// +// // template <class T> // T* // atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp index 6e94c505fd8cd..882a1f2c43b00 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp @@ -20,7 +20,7 @@ // Integral // atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op, // memory_order m); -// +// // template <class T> // T* // atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op, diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp index 42d57dedbd117..9306abfd06c53 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp @@ -14,7 +14,7 @@ // template <class Integral> // Integral // atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op); -// +// // template <class Integral> // Integral // atomic_fetch_xor(atomic<Integral>* obj, Integral op); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp index 8f388fee63250..c6a80a17eef69 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp @@ -14,7 +14,7 @@ // template <class Integral> // Integral // atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op); -// +// // template <class Integral> // Integral // atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h index 6cbc0c35c0f5b..482b7319dab25 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h @@ -24,10 +24,10 @@ struct UserAtomicType { return x.i == y.i; } }; -template < template <class TestArg> class TestFunctor > +template < template <class TestArg> class TestFunctor > struct TestEachIntegralType { void operator()() const { - TestFunctor<char>()(); + TestFunctor<char>()(); TestFunctor<signed char>()(); TestFunctor<unsigned char>()(); TestFunctor<short>()(); @@ -43,10 +43,18 @@ struct TestEachIntegralType { TestFunctor<char16_t>()(); TestFunctor<char32_t>()(); #endif + TestFunctor< int8_t>()(); + TestFunctor< uint8_t>()(); + TestFunctor< int16_t>()(); + TestFunctor<uint16_t>()(); + TestFunctor< int32_t>()(); + TestFunctor<uint32_t>()(); + TestFunctor< int64_t>()(); + TestFunctor<uint64_t>()(); } }; -template < template <class TestArg> class TestFunctor > +template < template <class TestArg> class TestFunctor > struct TestEachAtomicType { void operator()() const { TestEachIntegralType<TestFunctor>()(); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp index 884c02dfe7ea0..2cac65a8348aa 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp @@ -15,7 +15,7 @@ // template <class T> // void // atomic_init(volatile atomic<T>* obj, T desr); -// +// // template <class T> // void // atomic_init(atomic<T>* obj, T desr); 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 5d50016ed32c0..27e398736b6bd 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 @@ -14,7 +14,7 @@ // template <class T> // bool // atomic_is_lock_free(const volatile atomic<T>* obj); -// +// // template <class T> // bool // atomic_is_lock_free(const atomic<T>* obj); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp index e7b8e64b434f3..b6d330cef9d80 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp @@ -15,7 +15,7 @@ // template <class T> // T // atomic_load(const volatile atomic<T>* obj); -// +// // template <class T> // T // atomic_load(const atomic<T>* obj); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp index 56533fa871e59..1208b79026eab 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp @@ -15,7 +15,7 @@ // template <class T> // T // atomic_load_explicit(const volatile atomic<T>* obj, memory_order m); -// +// // template <class T> // T // atomic_load_explicit(const atomic<T>* obj, memory_order m); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp index e61dae9041166..3f8245bff6cd3 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp @@ -14,7 +14,7 @@ // template <class T> // void // atomic_store(volatile atomic<T>* obj, T desr); -// +// // template <class T> // void // atomic_store(atomic<T>* obj, T desr); diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp index e57cf8b1b3230..627a04b740775 100644 --- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp @@ -14,7 +14,7 @@ // template <class T> // void // atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m); -// +// // template <class T> // void // atomic_store_explicit(atomic<T>* obj, T desr, memory_order m); diff --git a/test/std/containers/associative/iterator_types.pass.cpp b/test/std/containers/associative/iterator_types.pass.cpp new file mode 100644 index 0000000000000..2026219d86cb8 --- /dev/null +++ b/test/std/containers/associative/iterator_types.pass.cpp @@ -0,0 +1,131 @@ +//===----------------------------------------------------------------------===// +// +// 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 <map> +#include <set> +#include <type_traits> + +#include "test_macros.h" +#include "min_allocator.h" +#include "test_allocator.h" + + +template <class Map, class ValueTp, class PtrT, class CPtrT> +void testMap() { + typedef typename Map::difference_type Diff; + { + typedef typename Map::iterator It; + static_assert((std::is_same<typename It::value_type, ValueTp>::value), ""); + static_assert((std::is_same<typename It::reference, ValueTp&>::value), ""); + static_assert((std::is_same<typename It::pointer, PtrT>::value), ""); + static_assert((std::is_same<typename It::difference_type, Diff>::value), ""); + } + { + typedef typename Map::const_iterator It; + static_assert((std::is_same<typename It::value_type, ValueTp>::value), ""); + static_assert((std::is_same<typename It::reference, ValueTp const&>::value), ""); + static_assert((std::is_same<typename It::pointer, CPtrT>::value), ""); + static_assert((std::is_same<typename It::difference_type, Diff>::value), ""); + } +} + + +template <class Set, class ValueTp, class CPtrT> +void testSet() { + static_assert((std::is_same<typename Set::iterator, + typename Set::const_iterator>::value), ""); + typedef typename Set::difference_type Diff; + { + typedef typename Set::iterator It; + static_assert((std::is_same<typename It::value_type, ValueTp>::value), ""); + static_assert((std::is_same<typename It::reference, ValueTp const&>::value), ""); + static_assert((std::is_same<typename It::pointer, CPtrT>::value), ""); + static_assert((std::is_same<typename It::difference_type, Diff>::value), ""); + + } +} + +int main() { + { + typedef std::map<int, int> Map; + typedef std::pair<const int, int> ValueTp; + testMap<Map, ValueTp, ValueTp*, ValueTp const*>(); + } + { + typedef std::pair<const int, int> ValueTp; + typedef test_allocator<ValueTp> Alloc; + typedef std::map<int, int, std::less<int>, Alloc> Map; + testMap<Map, ValueTp, ValueTp*, ValueTp const*>(); + } +#if TEST_STD_VER >= 11 + { + typedef std::pair<const int, int> ValueTp; + typedef min_allocator<ValueTp> Alloc; + typedef std::map<int, int, std::less<int>, Alloc> Map; + testMap<Map, ValueTp, min_pointer<ValueTp>, min_pointer<const ValueTp>>(); + } +#endif + { + typedef std::multimap<int, int> Map; + typedef std::pair<const int, int> ValueTp; + testMap<Map, ValueTp, ValueTp*, ValueTp const*>(); + } + { + typedef std::pair<const int, int> ValueTp; + typedef test_allocator<ValueTp> Alloc; + typedef std::multimap<int, int, std::less<int>, Alloc> Map; + testMap<Map, ValueTp, ValueTp*, ValueTp const*>(); + } +#if TEST_STD_VER >= 11 + { + typedef std::pair<const int, int> ValueTp; + typedef min_allocator<ValueTp> Alloc; + typedef std::multimap<int, int, std::less<int>, Alloc> Map; + testMap<Map, ValueTp, min_pointer<ValueTp>, min_pointer<const ValueTp>>(); + } +#endif + { + typedef int ValueTp; + typedef std::set<ValueTp> Set; + testSet<Set, ValueTp, ValueTp const*>(); + } + { + typedef int ValueTp; + typedef test_allocator<ValueTp> Alloc; + typedef std::set<ValueTp, std::less<ValueTp>, Alloc> Set; + testSet<Set, ValueTp, ValueTp const*>(); + } +#if TEST_STD_VER >= 11 + { + typedef int ValueTp; + typedef min_allocator<ValueTp> Alloc; + typedef std::set<ValueTp, std::less<ValueTp>, Alloc> Set; + testSet<Set, ValueTp, min_pointer<const ValueTp>>(); + } +#endif + { + typedef int ValueTp; + typedef std::multiset<ValueTp> Set; + testSet<Set, ValueTp, ValueTp const*>(); + } + { + typedef int ValueTp; + typedef test_allocator<ValueTp> Alloc; + typedef std::multiset<ValueTp, std::less<ValueTp>, Alloc> Set; + testSet<Set, ValueTp, ValueTp const*>(); + } +#if TEST_STD_VER >= 11 + { + typedef int ValueTp; + typedef min_allocator<ValueTp> Alloc; + typedef std::multiset<ValueTp, std::less<ValueTp>, Alloc> Set; + testSet<Set, ValueTp, min_pointer<const ValueTp>>(); + } +#endif +} diff --git a/test/std/containers/associative/map/PR28469_undefined_behavior_segfault.sh.cpp b/test/std/containers/associative/map/PR28469_undefined_behavior_segfault.sh.cpp new file mode 100644 index 0000000000000..32d34d90d7f80 --- /dev/null +++ b/test/std/containers/associative/map/PR28469_undefined_behavior_segfault.sh.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. +// +//===----------------------------------------------------------------------===// + +// RUN: %build -O2 +// RUN: %run + +// <map> + +// Previously this code caused a segfault when compiled at -O2 due to undefined +// behavior in __tree. See https://llvm.org/bugs/show_bug.cgi?id=28469 + +#include <functional> +#include <map> + +void dummy() {} + +struct F { + std::map<int, std::function<void()> > m; + F() { m[42] = &dummy; } +}; + +int main() { + F f; + f = F(); +} diff --git a/test/std/containers/associative/map/compare.pass.cpp b/test/std/containers/associative/map/compare.pass.cpp index 26ac7af7d908d..9d1c13d7b8e63 100644 --- a/test/std/containers/associative/map/compare.pass.cpp +++ b/test/std/containers/associative/map/compare.pass.cpp @@ -44,7 +44,7 @@ int main() MapT map; IterBool result = map.insert(std::make_pair(Key(0), 42)); assert(result.second); - assert(result.first->second = 42); + 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/incomplete_type.pass.cpp b/test/std/containers/associative/map/incomplete_type.pass.cpp new file mode 100644 index 0000000000000..84c2451ce0872 --- /dev/null +++ b/test/std/containers/associative/map/incomplete_type.pass.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. +// +//===----------------------------------------------------------------------===// + +// <map> + +// Check that std::map and it's iterators can be instantiated with an incomplete +// type. + +#include <map> + +struct A { + typedef std::map<A, A> Map; + int data; + Map m; + Map::iterator it; + Map::const_iterator cit; +}; + +inline bool operator==(A const& L, A const& R) { return &L == &R; } +inline bool operator<(A const& L, A const& R) { return L.data < R.data; } +int main() { + A a; +} diff --git a/test/std/containers/associative/map/map.access/at.pass.cpp b/test/std/containers/associative/map/map.access/at.pass.cpp index 0da28507fce39..c5f77bf5f0fb6 100644 --- a/test/std/containers/associative/map/map.access/at.pass.cpp +++ b/test/std/containers/associative/map/map.access/at.pass.cpp @@ -86,7 +86,7 @@ int main() assert(m.at(8) == 8.5); assert(m.size() == 7); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/map/map.access/empty.pass.cpp b/test/std/containers/associative/map/map.access/empty.pass.cpp index b11e94c8042ca..17b9cfd4ec110 100644 --- a/test/std/containers/associative/map/map.access/empty.pass.cpp +++ b/test/std/containers/associative/map/map.access/empty.pass.cpp @@ -29,7 +29,7 @@ int main() m.clear(); assert(m.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; M m; diff --git a/test/std/containers/associative/map/map.access/index_key.pass.cpp b/test/std/containers/associative/map/map.access/index_key.pass.cpp index ab1144c60afda..3b1c21fd5da44 100644 --- a/test/std/containers/associative/map/map.access/index_key.pass.cpp +++ b/test/std/containers/associative/map/map.access/index_key.pass.cpp @@ -16,8 +16,13 @@ #include <map> #include <cassert> +#include "test_macros.h" +#include "count_new.hpp" #include "min_allocator.h" #include "private_constructor.hpp" +#if TEST_STD_VER >= 11 +#include "container_test_types.h" +#endif int main() { @@ -46,7 +51,7 @@ int main() assert(m[6] == 6.5); assert(m.size() == 8); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = @@ -73,8 +78,42 @@ int main() assert(m[6] == 6.5); assert(m.size() == 8); } + { + // Use "container_test_types.h" to check what arguments get passed + // to the allocator for operator[] + using Container = TCT::map<>; + using Key = Container::key_type; + using MappedType = Container::mapped_type; + using ValueTp = Container::value_type; + ConstructController* cc = getConstructController(); + cc->reset(); + { + Container c; + const Key k(1); + cc->expect<std::piecewise_construct_t const&, std::tuple<Key const&>&&, std::tuple<>&&>(); + MappedType& mref = c[k]; + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + MappedType& mref2 = c[k]; + assert(&mref == &mref2); + } + } + { + Container c; + Key k(1); + cc->expect<std::piecewise_construct_t const&, std::tuple<Key const&>&&, std::tuple<>&&>(); + MappedType& mref = c[k]; + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + MappedType& mref2 = c[k]; + assert(&mref == &mref2); + } + } + } #endif -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 { typedef std::pair<const int, double> V; V ar[] = 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 6511dcc85f531..e5580bca3955d 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <map> // class map @@ -17,12 +19,13 @@ #include <cassert> #include "test_macros.h" +#include "count_new.hpp" #include "MoveOnly.h" #include "min_allocator.h" +#include "container_test_types.h" int main() { -#if TEST_STD_VER >= 11 { std::map<MoveOnly, double> m; assert(m.size() == 0); @@ -52,5 +55,27 @@ int main() assert(m[6] == 6.5); assert(m.size() == 2); } -#endif + { + // Use "container_test_types.h" to check what arguments get passed + // to the allocator for operator[] + using Container = TCT::map<>; + using Key = Container::key_type; + using MappedType = Container::mapped_type; + using ValueTp = Container::value_type; + ConstructController* cc = getConstructController(); + cc->reset(); + { + Container c; + Key k(1); + cc->expect<std::piecewise_construct_t const&, std::tuple<Key &&>&&, std::tuple<>&&>(); + MappedType& mref = c[std::move(k)]; + assert(!cc->unchecked()); + { + Key k2(1); + DisableAllocationGuard g; + MappedType& mref2 = c[std::move(k2)]; + assert(&mref == &mref2); + } + } + } } diff --git a/test/std/containers/associative/map/map.access/iterator.pass.cpp b/test/std/containers/associative/map/map.access/iterator.pass.cpp index 552e87d8fc8d3..4f66eb6a8e310 100644 --- a/test/std/containers/associative/map/map.access/iterator.pass.cpp +++ b/test/std/containers/associative/map/map.access/iterator.pass.cpp @@ -119,7 +119,7 @@ int main() assert(i->second == 1); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/map/map.access/max_size.pass.cpp b/test/std/containers/associative/map/map.access/max_size.pass.cpp index 551120d331e17..c67d8b1f674db 100644 --- a/test/std/containers/associative/map/map.access/max_size.pass.cpp +++ b/test/std/containers/associative/map/map.access/max_size.pass.cpp @@ -25,7 +25,7 @@ int main() M m; assert(m.max_size() != 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; M m; diff --git a/test/std/containers/associative/map/map.access/size.pass.cpp b/test/std/containers/associative/map/map.access/size.pass.cpp index 07c12322a460b..b9d56167a4b04 100644 --- a/test/std/containers/associative/map/map.access/size.pass.cpp +++ b/test/std/containers/associative/map/map.access/size.pass.cpp @@ -37,7 +37,7 @@ int main() m.erase(m.begin()); assert(m.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; M m; diff --git a/test/std/containers/associative/map/map.cons/alloc.pass.cpp b/test/std/containers/associative/map/map.cons/alloc.pass.cpp index 2292c47ef74ba..6ff102e6873c9 100644 --- a/test/std/containers/associative/map/map.cons/alloc.pass.cpp +++ b/test/std/containers/associative/map/map.cons/alloc.pass.cpp @@ -29,7 +29,7 @@ int main() assert(m.begin() == m.end()); assert(m.get_allocator() == A(5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::less<int> C; typedef min_allocator<std::pair<const int, double> > A; diff --git a/test/std/containers/associative/map/map.cons/assign_initializer_list.pass.cpp b/test/std/containers/associative/map/map.cons/assign_initializer_list.pass.cpp index 482d1acff840c..679600662fda4 100644 --- a/test/std/containers/associative/map/map.cons/assign_initializer_list.pass.cpp +++ b/test/std/containers/associative/map/map.cons/assign_initializer_list.pass.cpp @@ -45,7 +45,7 @@ int main() assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; std::map<int, double, std::less<int>, min_allocator<V>> m = diff --git a/test/std/containers/associative/map/map.cons/compare.pass.cpp b/test/std/containers/associative/map/map.cons/compare.pass.cpp index 5a213c8e8b8f6..5d8d5e2525074 100644 --- a/test/std/containers/associative/map/map.cons/compare.pass.cpp +++ b/test/std/containers/associative/map/map.cons/compare.pass.cpp @@ -28,7 +28,7 @@ int main() assert(m.begin() == m.end()); assert(m.key_comp() == C(3)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef test_compare<std::less<int> > C; std::map<int, double, C, min_allocator<std::pair<const int, double>>> m(C(3)); diff --git a/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp b/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp index 56b3c3315e084..ea1374a53dac3 100644 --- a/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp +++ b/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp @@ -31,7 +31,7 @@ int main() assert(m.key_comp() == C(4)); assert(m.get_allocator() == A(5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef test_compare<std::less<int> > C; typedef min_allocator<std::pair<const int, double> > A; diff --git a/test/std/containers/associative/map/map.cons/compare_copy_constructible.fail.cpp b/test/std/containers/associative/map/map.cons/compare_copy_constructible.fail.cpp new file mode 100644 index 0000000000000..81ccba3bbc968 --- /dev/null +++ b/test/std/containers/associative/map/map.cons/compare_copy_constructible.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. +// +//===----------------------------------------------------------------------===// + +// <map> + +// Check that std::map fails to instantiate if the comparison predicate is +// not copy-constructible. This is LWG issue 2436 + +#include <map> + +template <class T> +struct Comp { + bool operator () (const T& lhs, const T& rhs) const { return lhs < rhs; } + + Comp () {} +private: + Comp (const Comp &); // declared but not defined + }; + + +int main() { + std::map<int, int, Comp<int> > m; +} diff --git a/test/std/containers/associative/map/map.cons/copy.pass.cpp b/test/std/containers/associative/map/map.cons/copy.pass.cpp index be52741330821..a1de1b13aed27 100644 --- a/test/std/containers/associative/map/map.cons/copy.pass.cpp +++ b/test/std/containers/associative/map/map.cons/copy.pass.cpp @@ -92,7 +92,7 @@ int main() assert(*next(mo.begin(), 2) == V(3, 1)); } #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp b/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp index fcbe5976d6da4..8a9f7c86a2c79 100644 --- a/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp +++ b/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp @@ -56,7 +56,7 @@ int main() assert(*next(mo.begin()) == V(2, 1)); assert(*next(mo.begin(), 2) == V(3, 1)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/map/map.cons/copy_assign.pass.cpp b/test/std/containers/associative/map/map.cons/copy_assign.pass.cpp index a1bcb30f42949..fc6641ae34b91 100644 --- a/test/std/containers/associative/map/map.cons/copy_assign.pass.cpp +++ b/test/std/containers/associative/map/map.cons/copy_assign.pass.cpp @@ -107,7 +107,7 @@ int main() assert(*next(mo.begin()) == V(2, 1)); assert(*next(mo.begin(), 2) == V(3, 1)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/map/map.cons/default.pass.cpp b/test/std/containers/associative/map/map.cons/default.pass.cpp index 1832a32fffb3a..265c59ef24cde 100644 --- a/test/std/containers/associative/map/map.cons/default.pass.cpp +++ b/test/std/containers/associative/map/map.cons/default.pass.cpp @@ -25,7 +25,7 @@ int main() assert(m.empty()); assert(m.begin() == m.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> m; assert(m.empty()); diff --git a/test/std/containers/associative/map/map.cons/default_noexcept.pass.cpp b/test/std/containers/associative/map/map.cons/default_noexcept.pass.cpp index dedc89bd435ed..817f1207ac949 100644 --- a/test/std/containers/associative/map/map.cons/default_noexcept.pass.cpp +++ b/test/std/containers/associative/map/map.cons/default_noexcept.pass.cpp @@ -17,9 +17,12 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <map> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -28,19 +31,19 @@ struct some_comp { typedef T value_type; some_comp(); + bool operator()(const T&, const T&) const { return false; } }; int main() { -#if __has_feature(cxx_noexcept) typedef std::pair<const MoveOnly, MoveOnly> V; { typedef std::map<MoveOnly, MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C; @@ -50,5 +53,4 @@ int main() typedef std::map<MoveOnly, MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp b/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp index 9baa19b53d055..efdf5a2ed184e 100644 --- a/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp +++ b/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp @@ -11,26 +11,24 @@ // ~map() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <map> #include <cassert> #include "MoveOnly.h" #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_comp { typedef T value_type; ~some_comp() noexcept(false); + bool operator()(const T&, const T&) const noexcept { return false; } }; -#endif - int main() { -#if __has_feature(cxx_noexcept) typedef std::pair<const MoveOnly, MoveOnly> V; { typedef std::map<MoveOnly, MoveOnly> C; @@ -48,5 +46,4 @@ int main() typedef std::map<MoveOnly, MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/map/map.cons/initializer_list.pass.cpp b/test/std/containers/associative/map/map.cons/initializer_list.pass.cpp index 196943653a145..c55d18f540946 100644 --- a/test/std/containers/associative/map/map.cons/initializer_list.pass.cpp +++ b/test/std/containers/associative/map/map.cons/initializer_list.pass.cpp @@ -41,7 +41,7 @@ int main() assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; std::map<int, double, std::less<int>, min_allocator<V>> m = diff --git a/test/std/containers/associative/map/map.cons/initializer_list_compare.pass.cpp b/test/std/containers/associative/map/map.cons/initializer_list_compare.pass.cpp index 08f8a529f030a..3133eb2e0dd6d 100644 --- a/test/std/containers/associative/map/map.cons/initializer_list_compare.pass.cpp +++ b/test/std/containers/associative/map/map.cons/initializer_list_compare.pass.cpp @@ -42,7 +42,7 @@ int main() assert(*next(m.begin(), 2) == V(3, 1)); assert(m.key_comp() == C(3)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; typedef test_compare<std::less<int> > C; diff --git a/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp b/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp index 765428a631e5b..1210fe0e49e1a 100644 --- a/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp +++ b/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp @@ -45,7 +45,7 @@ int main() assert(m.key_comp() == C(3)); assert(m.get_allocator() == A(6)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; typedef test_compare<std::less<int> > C; diff --git a/test/std/containers/associative/map/map.cons/iter_iter.pass.cpp b/test/std/containers/associative/map/map.cons/iter_iter.pass.cpp index c1029af6889e3..48610f3b3e587 100644 --- a/test/std/containers/associative/map/map.cons/iter_iter.pass.cpp +++ b/test/std/containers/associative/map/map.cons/iter_iter.pass.cpp @@ -42,7 +42,7 @@ int main() assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/map/map.cons/iter_iter_comp.pass.cpp b/test/std/containers/associative/map/map.cons/iter_iter_comp.pass.cpp index 837fa8c6cdeaa..1389f71449c8f 100644 --- a/test/std/containers/associative/map/map.cons/iter_iter_comp.pass.cpp +++ b/test/std/containers/associative/map/map.cons/iter_iter_comp.pass.cpp @@ -45,7 +45,7 @@ int main() assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp b/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp index 67fb5d6447623..42376e2683325 100644 --- a/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp +++ b/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp @@ -49,7 +49,7 @@ int main() assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/map/map.cons/move.pass.cpp b/test/std/containers/associative/map/map.cons/move.pass.cpp index c06f2ee5021bc..2d19b88bdda84 100644 --- a/test/std/containers/associative/map/map.cons/move.pass.cpp +++ b/test/std/containers/associative/map/map.cons/move.pass.cpp @@ -69,7 +69,7 @@ int main() assert(mo.size() == 0); assert(distance(mo.begin(), mo.end()) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef test_compare<std::less<int> > C; typedef min_allocator<V> A; diff --git a/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp b/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp index e5d43f266c08c..4ccf56118aec5 100644 --- a/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp +++ b/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp @@ -169,7 +169,7 @@ int main() M m1(I(a1), I(a1+num), C(), A()); assert(Counter_base::gConstructed == num+3); - + M m2(m1); assert(m2 == m1); assert(Counter_base::gConstructed == num+6); @@ -187,9 +187,9 @@ int main() } assert(Counter_base::gConstructed == num+3); } - assert(Counter_base::gConstructed == 0); + assert(Counter_base::gConstructed == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<MoveOnly, MoveOnly> V; typedef std::pair<const MoveOnly, MoveOnly> VC; diff --git a/test/std/containers/associative/map/map.cons/move_assign.pass.cpp b/test/std/containers/associative/map/map.cons/move_assign.pass.cpp index 8ae8265cdc123..09b41d3b130b3 100644 --- a/test/std/containers/associative/map/map.cons/move_assign.pass.cpp +++ b/test/std/containers/associative/map/map.cons/move_assign.pass.cpp @@ -144,7 +144,7 @@ int main() assert(m3.key_comp() == C(5)); assert(m1.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<MoveOnly, MoveOnly> V; typedef std::pair<const MoveOnly, MoveOnly> VC; diff --git a/test/std/containers/associative/map/map.cons/move_assign_noexcept.pass.cpp b/test/std/containers/associative/map/map.cons/move_assign_noexcept.pass.cpp index 3b28118b5b1e2..95ddf6dcb82f9 100644 --- a/test/std/containers/associative/map/map.cons/move_assign_noexcept.pass.cpp +++ b/test/std/containers/associative/map/map.cons/move_assign_noexcept.pass.cpp @@ -17,6 +17,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <map> #include <cassert> @@ -28,11 +30,11 @@ struct some_comp { typedef T value_type; some_comp& operator=(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; int main() { -#if __has_feature(cxx_noexcept) typedef std::pair<const MoveOnly, MoveOnly> V; { typedef std::map<MoveOnly, MoveOnly> C; @@ -50,5 +52,4 @@ int main() typedef std::map<MoveOnly, MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/map/map.cons/move_noexcept.pass.cpp b/test/std/containers/associative/map/map.cons/move_noexcept.pass.cpp index 0f1fd396639e1..1c2a242edf43e 100644 --- a/test/std/containers/associative/map/map.cons/move_noexcept.pass.cpp +++ b/test/std/containers/associative/map/map.cons/move_noexcept.pass.cpp @@ -15,6 +15,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <map> #include <cassert> @@ -26,11 +28,11 @@ struct some_comp { typedef T value_type; some_comp(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; int main() { -#if __has_feature(cxx_noexcept) typedef std::pair<const MoveOnly, MoveOnly> V; { typedef std::map<MoveOnly, MoveOnly> C; @@ -48,5 +50,4 @@ int main() typedef std::map<MoveOnly, MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/map/map.modifiers/clear.pass.cpp b/test/std/containers/associative/map/map.modifiers/clear.pass.cpp index c37499df307a3..1f36a6f10cb0b 100644 --- a/test/std/containers/associative/map/map.modifiers/clear.pass.cpp +++ b/test/std/containers/associative/map/map.modifiers/clear.pass.cpp @@ -39,7 +39,7 @@ int main() m.clear(); assert(m.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::pair<int, double> P; diff --git a/test/std/containers/associative/map/map.modifiers/emplace.pass.cpp b/test/std/containers/associative/map/map.modifiers/emplace.pass.cpp index 81846c6647c6b..63d014fe8cc53 100644 --- a/test/std/containers/associative/map/map.modifiers/emplace.pass.cpp +++ b/test/std/containers/associative/map/map.modifiers/emplace.pass.cpp @@ -92,7 +92,7 @@ int main() assert(m.begin()->first == 2); assert(m.begin()->second == 3.5); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::map<int, DefaultOnly, std::less<int>, min_allocator<std::pair<const int, DefaultOnly>>> M; typedef std::pair<M::iterator, bool> R; diff --git a/test/std/containers/associative/map/map.modifiers/emplace_hint.pass.cpp b/test/std/containers/associative/map/map.modifiers/emplace_hint.pass.cpp index 15f74b17e7864..319a239525ad0 100644 --- a/test/std/containers/associative/map/map.modifiers/emplace_hint.pass.cpp +++ b/test/std/containers/associative/map/map.modifiers/emplace_hint.pass.cpp @@ -64,7 +64,7 @@ int main() assert(m.size() == 1); assert(m.begin()->first == 2); assert(m.begin()->second == Emplaceable()); - r = m.emplace_hint(m.end(), std::piecewise_construct, + r = m.emplace_hint(m.end(), std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple(2, 3.5)); assert(r == m.begin()); @@ -89,7 +89,7 @@ int main() assert(m.begin()->first == 2); assert(m.begin()->second == 3.5); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::map<int, DefaultOnly, std::less<int>, min_allocator<std::pair<const int, DefaultOnly>>> M; typedef M::iterator R; @@ -130,7 +130,7 @@ int main() assert(m.size() == 1); assert(m.begin()->first == 2); assert(m.begin()->second == Emplaceable()); - r = m.emplace_hint(m.end(), std::piecewise_construct, + r = m.emplace_hint(m.end(), std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple(2, 3.5)); assert(r == m.begin()); 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 15c5ce041b688..cd65c4302af7f 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 @@ -134,7 +134,7 @@ int main() assert(i == m.begin()); assert(i == m.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::pair<int, double> P; @@ -242,7 +242,7 @@ int main() assert(i == m.end()); } #endif -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 { // This is LWG #2059 typedef TemplateConstructor T; diff --git a/test/std/containers/associative/map/map.modifiers/erase_iter_iter.pass.cpp b/test/std/containers/associative/map/map.modifiers/erase_iter_iter.pass.cpp index 1b49956d8a5ad..144cfac2ccb5a 100644 --- a/test/std/containers/associative/map/map.modifiers/erase_iter_iter.pass.cpp +++ b/test/std/containers/associative/map/map.modifiers/erase_iter_iter.pass.cpp @@ -86,7 +86,7 @@ int main() assert(i == m.begin()); assert(i == m.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::pair<int, double> P; diff --git a/test/std/containers/associative/map/map.modifiers/erase_key.pass.cpp b/test/std/containers/associative/map/map.modifiers/erase_key.pass.cpp index e41f5129140e6..c1b31e78d3ef8 100644 --- a/test/std/containers/associative/map/map.modifiers/erase_key.pass.cpp +++ b/test/std/containers/associative/map/map.modifiers/erase_key.pass.cpp @@ -145,7 +145,7 @@ int main() assert(m.size() == 0); assert(s == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::pair<int, double> P; diff --git a/test/std/containers/associative/map/map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp b/test/std/containers/associative/map/map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp new file mode 100644 index 0000000000000..d98047d02e7dd --- /dev/null +++ b/test/std/containers/associative/map/map.modifiers/insert_and_emplace_allocator_requirements.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. +// +//===----------------------------------------------------------------------===// + +// <map> + +// class map + +// insert(...); +// emplace(...); +// emplace_hint(...); + +// UNSUPPORTED: c++98, c++03 + +#include <map> + +#include "container_test_types.h" +#include "../../../map_allocator_requirement_test_templates.h" + +int main() +{ + testMapInsert<TCT::map<> >(); + testMapInsertHint<TCT::map<> >(); + testMapEmplace<TCT::map<> >(); + testMapEmplaceHint<TCT::map<> >(); +} diff --git a/test/std/containers/associative/map/map.modifiers/insert_cv.pass.cpp b/test/std/containers/associative/map/map.modifiers/insert_cv.pass.cpp index 3d28242fd3228..e2ffcba375fa6 100644 --- a/test/std/containers/associative/map/map.modifiers/insert_cv.pass.cpp +++ b/test/std/containers/associative/map/map.modifiers/insert_cv.pass.cpp @@ -16,74 +16,57 @@ #include <map> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" -int main() +template <class Container> +void do_insert_cv_test() { - { - typedef std::map<int, double> M; - typedef std::pair<M::iterator, bool> R; - M m; - R r = m.insert(M::value_type(2, 2.5)); - assert(r.second); - assert(r.first == m.begin()); - assert(m.size() == 1); - assert(r.first->first == 2); - assert(r.first->second == 2.5); - - r = m.insert(M::value_type(1, 1.5)); - assert(r.second); - assert(r.first == m.begin()); - assert(m.size() == 2); - assert(r.first->first == 1); - assert(r.first->second == 1.5); + typedef Container M; + typedef std::pair<typename M::iterator, bool> R; + typedef typename M::value_type VT; + M m; - r = m.insert(M::value_type(3, 3.5)); - assert(r.second); - assert(r.first == prev(m.end())); - assert(m.size() == 3); - assert(r.first->first == 3); - assert(r.first->second == 3.5); + const VT v1(2, 2.5); + R r = m.insert(v1); + assert(r.second); + assert(r.first == m.begin()); + assert(m.size() == 1); + assert(r.first->first == 2); + assert(r.first->second == 2.5); - r = m.insert(M::value_type(3, 3.5)); - assert(!r.second); - assert(r.first == prev(m.end())); - assert(m.size() == 3); - assert(r.first->first == 3); - assert(r.first->second == 3.5); - } -#if __cplusplus >= 201103L - { - typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; - typedef std::pair<M::iterator, bool> R; - M m; - R r = m.insert(M::value_type(2, 2.5)); - assert(r.second); - assert(r.first == m.begin()); - assert(m.size() == 1); - assert(r.first->first == 2); - assert(r.first->second == 2.5); + const VT v2(1, 1.5); + r = m.insert(v2); + assert(r.second); + assert(r.first == m.begin()); + assert(m.size() == 2); + assert(r.first->first == 1); + assert(r.first->second == 1.5); - r = m.insert(M::value_type(1, 1.5)); - assert(r.second); - assert(r.first == m.begin()); - assert(m.size() == 2); - assert(r.first->first == 1); - assert(r.first->second == 1.5); + const VT v3(3, 3.5); + r = m.insert(v3); + assert(r.second); + assert(r.first == prev(m.end())); + assert(m.size() == 3); + assert(r.first->first == 3); + assert(r.first->second == 3.5); - r = m.insert(M::value_type(3, 3.5)); - assert(r.second); - assert(r.first == prev(m.end())); - assert(m.size() == 3); - assert(r.first->first == 3); - assert(r.first->second == 3.5); + const VT v4(3, 4.5); + r = m.insert(v4); + assert(!r.second); + assert(r.first == prev(m.end())); + assert(m.size() == 3); + assert(r.first->first == 3); + assert(r.first->second == 3.5); +} - r = m.insert(M::value_type(3, 3.5)); - assert(!r.second); - assert(r.first == prev(m.end())); - assert(m.size() == 3); - assert(r.first->first == 3); - assert(r.first->second == 3.5); +int main() +{ + do_insert_cv_test<std::map<int, double> >(); +#if TEST_STD_VER >= 11 + { + typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; + do_insert_cv_test<M>(); } #endif } diff --git a/test/std/containers/associative/map/map.modifiers/insert_initializer_list.pass.cpp b/test/std/containers/associative/map/map.modifiers/insert_initializer_list.pass.cpp index ab325ed45bfcc..9cf3f3dcf74fa 100644 --- a/test/std/containers/associative/map/map.modifiers/insert_initializer_list.pass.cpp +++ b/test/std/containers/associative/map/map.modifiers/insert_initializer_list.pass.cpp @@ -43,7 +43,7 @@ int main() assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; std::map<int, double, std::less<int>, min_allocator<V>> m = diff --git a/test/std/containers/associative/map/map.modifiers/insert_iter_cv.pass.cpp b/test/std/containers/associative/map/map.modifiers/insert_iter_cv.pass.cpp index 278db4631a8ca..0c7e124e0d1c9 100644 --- a/test/std/containers/associative/map/map.modifiers/insert_iter_cv.pass.cpp +++ b/test/std/containers/associative/map/map.modifiers/insert_iter_cv.pass.cpp @@ -16,66 +16,53 @@ #include <map> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" -int main() +template <class Container> +void do_insert_iter_cv_test() { - { - typedef std::map<int, double> M; - typedef M::iterator R; - M m; - R r = m.insert(m.end(), M::value_type(2, 2.5)); - assert(r == m.begin()); - assert(m.size() == 1); - assert(r->first == 2); - assert(r->second == 2.5); - - r = m.insert(m.end(), M::value_type(1, 1.5)); - assert(r == m.begin()); - assert(m.size() == 2); - assert(r->first == 1); - assert(r->second == 1.5); + typedef Container M; + typedef typename M::iterator R; + typedef typename M::value_type VT; - r = m.insert(m.end(), M::value_type(3, 3.5)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3.5); + M m; + const VT v1(2, 2.5); + R r = m.insert(m.end(), v1); + assert(r == m.begin()); + assert(m.size() == 1); + assert(r->first == 2); + assert(r->second == 2.5); - r = m.insert(m.end(), M::value_type(3, 3.5)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3.5); - } -#if __cplusplus >= 201103L - { - typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; - typedef M::iterator R; - M m; - R r = m.insert(m.end(), M::value_type(2, 2.5)); - assert(r == m.begin()); - assert(m.size() == 1); - assert(r->first == 2); - assert(r->second == 2.5); + const VT v2(1, 1.5); + r = m.insert(m.end(), v2); + assert(r == m.begin()); + assert(m.size() == 2); + assert(r->first == 1); + assert(r->second == 1.5); - r = m.insert(m.end(), M::value_type(1, 1.5)); - assert(r == m.begin()); - assert(m.size() == 2); - assert(r->first == 1); - assert(r->second == 1.5); + const VT v3(3, 3.5); + r = m.insert(m.end(), v3); + assert(r == prev(m.end())); + assert(m.size() == 3); + assert(r->first == 3); + assert(r->second == 3.5); - r = m.insert(m.end(), M::value_type(3, 3.5)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3.5); + const VT v4(3, 4.5); + r = m.insert(m.end(), v4); + assert(r == prev(m.end())); + assert(m.size() == 3); + assert(r->first == 3); + assert(r->second == 3.5); +} - r = m.insert(m.end(), M::value_type(3, 3.5)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3.5); +int main() +{ + do_insert_iter_cv_test<std::map<int, double> >(); +#if TEST_STD_VER >= 11 + { + typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; + do_insert_iter_cv_test<M>(); } #endif } diff --git a/test/std/containers/associative/map/map.modifiers/insert_iter_iter.pass.cpp b/test/std/containers/associative/map/map.modifiers/insert_iter_iter.pass.cpp index 964738b4a68aa..edc1a1e2c62bd 100644 --- a/test/std/containers/associative/map/map.modifiers/insert_iter_iter.pass.cpp +++ b/test/std/containers/associative/map/map.modifiers/insert_iter_iter.pass.cpp @@ -47,7 +47,7 @@ int main() assert(next(m.begin(), 2)->first == 3); assert(next(m.begin(), 2)->second == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::pair<int, double> P; diff --git a/test/std/containers/associative/map/map.modifiers/insert_iter_rv.pass.cpp b/test/std/containers/associative/map/map.modifiers/insert_iter_rv.pass.cpp index 9db1e5c707327..3edb9c06e7c0d 100644 --- a/test/std/containers/associative/map/map.modifiers/insert_iter_rv.pass.cpp +++ b/test/std/containers/associative/map/map.modifiers/insert_iter_rv.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <map> // class map @@ -21,70 +23,49 @@ #include "min_allocator.h" #include "test_macros.h" -int main() +template <class Container, class Pair> +void do_insert_iter_rv_test() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - { - typedef std::map<int, MoveOnly> M; - typedef std::pair<int, MoveOnly> P; - typedef M::iterator R; - M m; - R r = m.insert(m.end(), P(2, 2)); - assert(r == m.begin()); - assert(m.size() == 1); - assert(r->first == 2); - assert(r->second == 2); + typedef Container M; + typedef Pair P; + typedef typename M::iterator R; + M m; + R r = m.insert(m.end(), P(2, 2)); + assert(r == m.begin()); + assert(m.size() == 1); + assert(r->first == 2); + assert(r->second == 2); - r = m.insert(m.end(), P(1, 1)); - assert(r == m.begin()); - assert(m.size() == 2); - assert(r->first == 1); - assert(r->second == 1); + r = m.insert(m.end(), P(1, 1)); + assert(r == m.begin()); + assert(m.size() == 2); + assert(r->first == 1); + assert(r->second == 1); - r = m.insert(m.end(), P(3, 3)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3); + r = m.insert(m.end(), P(3, 3)); + assert(r == prev(m.end())); + assert(m.size() == 3); + assert(r->first == 3); + assert(r->second == 3); + + r = m.insert(m.end(), P(3, 4)); + assert(r == prev(m.end())); + assert(m.size() == 3); + assert(r->first == 3); + assert(r->second == 3); +} +int main() +{ + do_insert_iter_rv_test<std::map<int, MoveOnly>, std::pair<int, MoveOnly>>(); + do_insert_iter_rv_test<std::map<int, MoveOnly>, std::pair<const int, MoveOnly>>(); - r = m.insert(m.end(), P(3, 3)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3); - } -#if TEST_STD_VER >= 11 { typedef std::map<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M; typedef std::pair<int, MoveOnly> P; - typedef M::iterator R; - M m; - R r = m.insert(m.end(), P(2, 2)); - assert(r == m.begin()); - assert(m.size() == 1); - assert(r->first == 2); - assert(r->second == 2); - - r = m.insert(m.end(), P(1, 1)); - assert(r == m.begin()); - assert(m.size() == 2); - assert(r->first == 1); - assert(r->second == 1); - - r = m.insert(m.end(), P(3, 3)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3); - - r = m.insert(m.end(), P(3, 3)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3); + typedef std::pair<const int, MoveOnly> CP; + do_insert_iter_rv_test<M, P>(); + do_insert_iter_rv_test<M, CP>(); } -#endif -#if TEST_STD_VER > 14 { typedef std::map<int, MoveOnly> M; typedef M::iterator R; @@ -113,6 +94,5 @@ int main() assert(r->first == 3); assert(r->second == 3); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#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 index 484ed06247d17..8689dc7284d53 100644 --- 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 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <map> @@ -22,7 +22,6 @@ // 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> @@ -60,9 +59,6 @@ public: 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; @@ -186,7 +182,4 @@ int main() 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/insert_rv.pass.cpp b/test/std/containers/associative/map/map.modifiers/insert_rv.pass.cpp index 23eb84d687ff3..503d9291076da 100644 --- a/test/std/containers/associative/map/map.modifiers/insert_rv.pass.cpp +++ b/test/std/containers/associative/map/map.modifiers/insert_rv.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <map> // class map @@ -22,76 +24,54 @@ #include "min_allocator.h" #include "test_macros.h" -int main() +template <class Container, class Pair> +void do_insert_rv_test() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - { - typedef std::map<int, MoveOnly> M; - typedef std::pair<M::iterator, bool> R; - M m; - R r = m.insert(M::value_type(2, 2)); - assert(r.second); - assert(r.first == m.begin()); - assert(m.size() == 1); - assert(r.first->first == 2); - assert(r.first->second == 2); + typedef Container M; + typedef Pair P; + typedef std::pair<typename M::iterator, bool> R; + M m; + R r = m.insert(P(2, 2)); + assert(r.second); + assert(r.first == m.begin()); + assert(m.size() == 1); + assert(r.first->first == 2); + assert(r.first->second == 2); - r = m.insert(M::value_type(1, 1)); - assert(r.second); - assert(r.first == m.begin()); - assert(m.size() == 2); - assert(r.first->first == 1); - assert(r.first->second == 1); + r = m.insert(P(1, 1)); + assert(r.second); + assert(r.first == m.begin()); + assert(m.size() == 2); + assert(r.first->first == 1); + assert(r.first->second == 1); - r = m.insert(M::value_type(3, 3)); - assert(r.second); - assert(r.first == prev(m.end())); - assert(m.size() == 3); - assert(r.first->first == 3); - assert(r.first->second == 3); + r = m.insert(P(3, 3)); + assert(r.second); + assert(r.first == prev(m.end())); + assert(m.size() == 3); + assert(r.first->first == 3); + assert(r.first->second == 3); - r = m.insert(M::value_type(3, 3)); - assert(!r.second); - assert(r.first == prev(m.end())); - assert(m.size() == 3); - assert(r.first->first == 3); - assert(r.first->second == 3); - } -#if TEST_STD_VER >= 11 - { - typedef std::map<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M; - typedef std::pair<M::iterator, bool> R; - M m; - R r = m.insert(M::value_type(2, 2)); - assert(r.second); - assert(r.first == m.begin()); - assert(m.size() == 1); - assert(r.first->first == 2); - assert(r.first->second == 2); - - r = m.insert(M::value_type(1, 1)); - assert(r.second); - assert(r.first == m.begin()); - assert(m.size() == 2); - assert(r.first->first == 1); - assert(r.first->second == 1); + r = m.insert(P(3, 3)); + assert(!r.second); + assert(r.first == prev(m.end())); + assert(m.size() == 3); + assert(r.first->first == 3); + assert(r.first->second == 3); +} - r = m.insert(M::value_type(3, 3)); - assert(r.second); - assert(r.first == prev(m.end())); - assert(m.size() == 3); - assert(r.first->first == 3); - assert(r.first->second == 3); +int main() +{ + do_insert_rv_test<std::map<int, MoveOnly>, std::pair<int, MoveOnly>>(); + do_insert_rv_test<std::map<int, MoveOnly>, std::pair<const int, MoveOnly>>(); - r = m.insert(M::value_type(3, 3)); - assert(!r.second); - assert(r.first == prev(m.end())); - assert(m.size() == 3); - assert(r.first->first == 3); - assert(r.first->second == 3); + { + typedef std::map<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M; + typedef std::pair<int, MoveOnly> P; + typedef std::pair<const int, MoveOnly> CP; + do_insert_rv_test<M, P>(); + do_insert_rv_test<M, CP>(); } -#endif -#if TEST_STD_VER > 14 { typedef std::map<int, MoveOnly> M; typedef std::pair<M::iterator, bool> R; @@ -124,6 +104,4 @@ int main() assert(r.first->first == 3); assert(r.first->second == 3); } -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } 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 index 8e0dd7577bbd6..63704c91440e7 100644 --- a/test/std/containers/associative/map/map.modifiers/try.emplace.pass.cpp +++ b/test/std/containers/associative/map/map.modifiers/try.emplace.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <map> @@ -22,7 +22,6 @@ // template <class... Args> // iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17 -#include <__config> #include <map> #include <cassert> #include <tuple> @@ -58,9 +57,6 @@ public: 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; @@ -104,7 +100,7 @@ int main() assert(r.first->second.get() == -1); // value } - { // pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); + { // 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; @@ -140,7 +136,7 @@ int main() 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) { @@ -183,7 +179,4 @@ int main() 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 ae87ae8345e97..f3df31951c793 100644 --- a/test/std/containers/associative/map/map.ops/count.pass.cpp +++ b/test/std/containers/associative/map/map.ops/count.pass.cpp @@ -59,7 +59,7 @@ int main() assert(r == 0); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; typedef std::map<int, double, std::less<int>, min_allocator<V>> M; diff --git a/test/std/containers/associative/map/map.ops/count0.pass.cpp b/test/std/containers/associative/map/map.ops/count0.pass.cpp index ce549366e7ab0..0278343006a87 100644 --- a/test/std/containers/associative/map/map.ops/count0.pass.cpp +++ b/test/std/containers/associative/map/map.ops/count0.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: c++03, c++11 +// XFAIL: c++98, c++03, c++11 // <map> @@ -15,9 +15,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/map/map.ops/count1.fail.cpp b/test/std/containers/associative/map/map.ops/count1.fail.cpp index 9c15059d490eb..075a5ba2e0ab0 100644 --- a/test/std/containers/associative/map/map.ops/count1.fail.cpp +++ b/test/std/containers/associative/map/map.ops/count1.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/map/map.ops/count2.fail.cpp b/test/std/containers/associative/map/map.ops/count2.fail.cpp index 7aa1553ef47a9..de18990218059 100644 --- a/test/std/containers/associative/map/map.ops/count2.fail.cpp +++ b/test/std/containers/associative/map/map.ops/count2.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/map/map.ops/count3.fail.cpp b/test/std/containers/associative/map/map.ops/count3.fail.cpp index 7e7bb8f6d3709..b139689fec74c 100644 --- a/test/std/containers/associative/map/map.ops/count3.fail.cpp +++ b/test/std/containers/associative/map/map.ops/count3.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 a71149a472125..8beeb8b30f587 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 @@ -159,7 +159,7 @@ int main() assert(r.second == next(m.begin(), 8)); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; typedef std::map<int, double, std::less<int>, min_allocator<V>> M; 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 index c95c3dffa9a55..3b98426868e4b 100644 --- a/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp +++ b/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: c++03, c++11 +// XFAIL: c++98, c++03, c++11 // <map> @@ -15,9 +15,9 @@ // 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 +// +// 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 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 index 8f0da08eb3221..c66c2c512142d 100644 --- a/test/std/containers/associative/map/map.ops/equal_range1.fail.cpp +++ b/test/std/containers/associative/map/map.ops/equal_range1.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 index e73122d6533b9..85083d4f47965 100644 --- a/test/std/containers/associative/map/map.ops/equal_range2.fail.cpp +++ b/test/std/containers/associative/map/map.ops/equal_range2.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 index bb72e9e7a6d43..c9f1126e5baf4 100644 --- a/test/std/containers/associative/map/map.ops/equal_range3.fail.cpp +++ b/test/std/containers/associative/map/map.ops/equal_range3.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 17463b65740f2..225f0f406042b 100644 --- a/test/std/containers/associative/map/map.ops/find.pass.cpp +++ b/test/std/containers/associative/map/map.ops/find.pass.cpp @@ -93,7 +93,7 @@ int main() assert(r == next(m.begin(), 8)); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; typedef std::map<int, double, std::less<int>, min_allocator<V>> M; diff --git a/test/std/containers/associative/map/map.ops/find0.pass.cpp b/test/std/containers/associative/map/map.ops/find0.pass.cpp index 5f310b07c599d..d7de579d8b44f 100644 --- a/test/std/containers/associative/map/map.ops/find0.pass.cpp +++ b/test/std/containers/associative/map/map.ops/find0.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: c++03, c++11 +// XFAIL: c++98, c++03, c++11 // <map> @@ -15,9 +15,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/map/map.ops/find1.fail.cpp b/test/std/containers/associative/map/map.ops/find1.fail.cpp index c33b5a9a34cf8..4fe61117613c2 100644 --- a/test/std/containers/associative/map/map.ops/find1.fail.cpp +++ b/test/std/containers/associative/map/map.ops/find1.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/map/map.ops/find2.fail.cpp b/test/std/containers/associative/map/map.ops/find2.fail.cpp index 40bf323a45384..3532dc8765b34 100644 --- a/test/std/containers/associative/map/map.ops/find2.fail.cpp +++ b/test/std/containers/associative/map/map.ops/find2.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/map/map.ops/find3.fail.cpp b/test/std/containers/associative/map/map.ops/find3.fail.cpp index 9526c0e24d9ec..be77330a29c88 100644 --- a/test/std/containers/associative/map/map.ops/find3.fail.cpp +++ b/test/std/containers/associative/map/map.ops/find3.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 3cbfbf7d869f2..e4359fa548b96 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 @@ -125,7 +125,7 @@ int main() assert(r == next(m.begin(), 8)); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; typedef std::map<int, double, std::less<int>, min_allocator<V>> M; @@ -317,7 +317,7 @@ int main() r = m.lower_bound(C2Int(20)); assert(r == next(m.begin(), 8)); } - + { typedef PrivateConstructor PC; typedef std::map<PC, double, std::less<>> M; 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 index 2fc095a8f2c1d..ea121df730022 100644 --- a/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp +++ b/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: c++03, c++11 +// XFAIL: c++98, c++03, c++11 // <map> @@ -15,9 +15,9 @@ // 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 +// +// 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 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 index a4a986c1a7a43..97bbf553205f2 100644 --- a/test/std/containers/associative/map/map.ops/lower_bound1.fail.cpp +++ b/test/std/containers/associative/map/map.ops/lower_bound1.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 index 3f6380e5e25ff..eeae8e657387a 100644 --- a/test/std/containers/associative/map/map.ops/lower_bound2.fail.cpp +++ b/test/std/containers/associative/map/map.ops/lower_bound2.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 index 18f2c7b71fde6..ba27ae3c51723 100644 --- a/test/std/containers/associative/map/map.ops/lower_bound3.fail.cpp +++ b/test/std/containers/associative/map/map.ops/lower_bound3.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/map/map.ops/upper_bound.pass.cpp b/test/std/containers/associative/map/map.ops/upper_bound.pass.cpp index 037ceb962cd8d..8c721947a2c3b 100644 --- a/test/std/containers/associative/map/map.ops/upper_bound.pass.cpp +++ b/test/std/containers/associative/map/map.ops/upper_bound.pass.cpp @@ -124,7 +124,7 @@ int main() assert(r == next(m.begin(), 8)); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; typedef std::map<int, double, std::less<int>, min_allocator<V>> M; @@ -280,7 +280,7 @@ int main() r = m.upper_bound(20); assert(r == next(m.begin(), 8)); } - + { typedef PrivateConstructor PC; typedef std::map<PC, double, std::less<>> M; 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 index c58e55f297933..2e597b85cf0c5 100644 --- a/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp +++ b/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: c++03, c++11 +// XFAIL: c++98, c++03, c++11 // <map> @@ -15,9 +15,9 @@ // 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 +// +// 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 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 index 4647681b5cd19..6568e04bfad45 100644 --- a/test/std/containers/associative/map/map.ops/upper_bound1.fail.cpp +++ b/test/std/containers/associative/map/map.ops/upper_bound1.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 index 11852fe0cc9ff..bbb857e6f25ac 100644 --- a/test/std/containers/associative/map/map.ops/upper_bound2.fail.cpp +++ b/test/std/containers/associative/map/map.ops/upper_bound2.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 index 9cddeb8acbdc8..ed9a41e4f03f7 100644 --- a/test/std/containers/associative/map/map.ops/upper_bound3.fail.cpp +++ b/test/std/containers/associative/map/map.ops/upper_bound3.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/map/map.special/member_swap.pass.cpp b/test/std/containers/associative/map/map.special/member_swap.pass.cpp index 7c3ad9d50ae41..f0913a77c2eb9 100644 --- a/test/std/containers/associative/map/map.special/member_swap.pass.cpp +++ b/test/std/containers/associative/map/map.special/member_swap.pass.cpp @@ -96,7 +96,7 @@ int main() assert(m2 == m1_save); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::map<int, double, std::less<int>, min_allocator<V>> M; { diff --git a/test/std/containers/associative/map/map.special/non_member_swap.pass.cpp b/test/std/containers/associative/map/map.special/non_member_swap.pass.cpp index b042a4878f8a2..103a57b17e073 100644 --- a/test/std/containers/associative/map/map.special/non_member_swap.pass.cpp +++ b/test/std/containers/associative/map/map.special/non_member_swap.pass.cpp @@ -98,6 +98,7 @@ int main() assert(m1 == m2_save); assert(m2 == m1_save); } + } { typedef test_allocator<V> A; typedef test_compare<std::less<int> > C; @@ -166,8 +167,7 @@ int main() assert(m2.key_comp() == C(1)); assert(m2.get_allocator() == A(1)); } - } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::map<int, double, std::less<int>, min_allocator<V>> M; { @@ -242,6 +242,7 @@ int main() assert(m1 == m2_save); assert(m2 == m1_save); } + } { typedef min_allocator<V> A; typedef test_compare<std::less<int> > C; @@ -276,6 +277,5 @@ int main() assert(m2.key_comp() == C(1)); assert(m2.get_allocator() == A()); } - } #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 f25dff2c86daa..cbbf4577ce626 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <map> // void swap(map& c) @@ -15,13 +17,14 @@ // // In C++17, the standard says that swap shall have: // noexcept(allocator_traits<Allocator>::is_always_equal::value && -// noexcept(swap(declval<Compare&>(), declval<Compare&>()))); +// noexcept(swap(declval<Compare&>(), declval<Compare&>()))); // This tests a conforming extension #include <map> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -29,23 +32,20 @@ template <class T> struct some_comp { typedef T value_type; - + some_comp() {} some_comp(const some_comp&) {} - void deallocate(void*, unsigned) {} - - typedef std::true_type propagate_on_container_swap; + bool operator()(const T&, const T&) const { return false; } }; 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; + bool operator()(const T&, const T&) const { return false; } }; #if TEST_STD_VER >= 14 @@ -57,7 +57,7 @@ template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -69,7 +69,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -82,7 +82,7 @@ template <class T> struct some_alloc3 { typedef T value_type; - + some_alloc3() {} some_alloc3(const some_alloc3&); void deallocate(void*, unsigned) {} @@ -93,7 +93,6 @@ struct some_alloc3 int main() { -#if __has_feature(cxx_noexcept) typedef std::pair<const MoveOnly, MoveOnly> V; { typedef std::map<MoveOnly, MoveOnly> C; @@ -145,5 +144,4 @@ int main() } #endif -#endif } diff --git a/test/std/containers/associative/map/types.pass.cpp b/test/std/containers/associative/map/types.pass.cpp index d117deff693d1..67cd5acaae89a 100644 --- a/test/std/containers/associative/map/types.pass.cpp +++ b/test/std/containers/associative/map/types.pass.cpp @@ -50,7 +50,7 @@ int main() static_assert((std::is_same<C::size_type, std::size_t>::value), ""); static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), ""); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> C; static_assert((std::is_same<C::key_type, int>::value), ""); diff --git a/test/std/containers/associative/multimap/empty.pass.cpp b/test/std/containers/associative/multimap/empty.pass.cpp index 2384960d10dbd..f1388d8bfa5a2 100644 --- a/test/std/containers/associative/multimap/empty.pass.cpp +++ b/test/std/containers/associative/multimap/empty.pass.cpp @@ -29,7 +29,7 @@ int main() m.clear(); assert(m.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; M m; diff --git a/test/std/containers/associative/multimap/incomplete_type.pass.cpp b/test/std/containers/associative/multimap/incomplete_type.pass.cpp new file mode 100644 index 0000000000000..c461eb38139d5 --- /dev/null +++ b/test/std/containers/associative/multimap/incomplete_type.pass.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. +// +//===----------------------------------------------------------------------===// + +// <map> + +// Check that std::multimap and it's iterators can be instantiated with an incomplete +// type. + +#include <map> + +struct A { + typedef std::multimap<A, A> Map; + int data; + Map m; + Map::iterator it; + Map::const_iterator cit; +}; + +inline bool operator==(A const& L, A const& R) { return &L == &R; } +inline bool operator<(A const& L, A const& R) { return L.data < R.data; } +int main() { + A a; +} diff --git a/test/std/containers/associative/multimap/iterator.pass.cpp b/test/std/containers/associative/multimap/iterator.pass.cpp index 2763129acc2ab..ef7c5ef18af1f 100644 --- a/test/std/containers/associative/multimap/iterator.pass.cpp +++ b/test/std/containers/associative/multimap/iterator.pass.cpp @@ -121,7 +121,7 @@ int main() assert(i->second == d); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/multimap/max_size.pass.cpp b/test/std/containers/associative/multimap/max_size.pass.cpp index ccd8b10638c19..b7cf226d8f138 100644 --- a/test/std/containers/associative/multimap/max_size.pass.cpp +++ b/test/std/containers/associative/multimap/max_size.pass.cpp @@ -25,7 +25,7 @@ int main() M m; assert(m.max_size() != 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; M m; diff --git a/test/std/containers/associative/multimap/multimap.cons/alloc.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/alloc.pass.cpp index 87bf0447e5be5..69660fcd2772e 100644 --- a/test/std/containers/associative/multimap/multimap.cons/alloc.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/alloc.pass.cpp @@ -29,7 +29,7 @@ int main() assert(m.begin() == m.end()); assert(m.get_allocator() == A(5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::less<int> C; typedef min_allocator<std::pair<const int, double> > A; diff --git a/test/std/containers/associative/multimap/multimap.cons/assign_initializer_list.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/assign_initializer_list.pass.cpp index 0c89918325297..4c0326d90fe67 100644 --- a/test/std/containers/associative/multimap/multimap.cons/assign_initializer_list.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/assign_initializer_list.pass.cpp @@ -50,7 +50,7 @@ int main() assert(*++i == V(3, 1.5)); assert(*++i == V(3, 2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> C; typedef C::value_type V; diff --git a/test/std/containers/associative/multimap/multimap.cons/compare.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/compare.pass.cpp index 9a4e0f987fd00..59a972f456874 100644 --- a/test/std/containers/associative/multimap/multimap.cons/compare.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/compare.pass.cpp @@ -28,7 +28,7 @@ int main() assert(m.begin() == m.end()); assert(m.key_comp() == C(3)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef test_compare<std::less<int> > C; std::multimap<int, double, C, min_allocator<std::pair<const int, double>>> m(C(3)); diff --git a/test/std/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp index 1224884939cfa..836532892499a 100644 --- a/test/std/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp @@ -31,7 +31,7 @@ int main() assert(m.key_comp() == C(4)); assert(m.get_allocator() == A(5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef test_compare<std::less<int> > C; typedef min_allocator<std::pair<const int, double> > A; diff --git a/test/std/containers/associative/multimap/multimap.cons/compare_copy_constructible.fail.cpp b/test/std/containers/associative/multimap/multimap.cons/compare_copy_constructible.fail.cpp new file mode 100644 index 0000000000000..e6f6c3efee5bb --- /dev/null +++ b/test/std/containers/associative/multimap/multimap.cons/compare_copy_constructible.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. +// +//===----------------------------------------------------------------------===// + +// <map> + +// Check that std::multimap fails to instantiate if the comparison predicate is +// not copy-constructible. This is LWG issue 2436 + +#include <map> + +template <class T> +struct Comp { + bool operator () (const T& lhs, const T& rhs) const { return lhs < rhs; } + + Comp () {} +private: + Comp (const Comp &); // declared but not defined + }; + + +int main() { + std::multimap<int, int, Comp<int> > m; +} diff --git a/test/std/containers/associative/multimap/multimap.cons/copy.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/copy.pass.cpp index 3d6626eaadbb0..97dcf39e10c9c 100644 --- a/test/std/containers/associative/multimap/multimap.cons/copy.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/copy.pass.cpp @@ -74,7 +74,7 @@ int main() assert(mo.key_comp() == C(5)); } #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp index 22594e32d7188..46b9459cad28d 100644 --- a/test/std/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp @@ -47,7 +47,7 @@ int main() assert(mo.get_allocator() == A(7)); assert(mo.key_comp() == C(5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/multimap/multimap.cons/copy_assign.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/copy_assign.pass.cpp index 2bdc4d6a70ab5..b0bf8cc135f24 100644 --- a/test/std/containers/associative/multimap/multimap.cons/copy_assign.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/copy_assign.pass.cpp @@ -94,7 +94,7 @@ int main() assert(mo.get_allocator() == A(2)); assert(mo.key_comp() == C(5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/multimap/multimap.cons/default.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/default.pass.cpp index 1c3ab8ce6c4b0..d39cc1d0ee8af 100644 --- a/test/std/containers/associative/multimap/multimap.cons/default.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/default.pass.cpp @@ -25,7 +25,7 @@ int main() assert(m.empty()); assert(m.begin() == m.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> m; assert(m.empty()); diff --git a/test/std/containers/associative/multimap/multimap.cons/default_noexcept.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/default_noexcept.pass.cpp index 5f05a0dca28e1..6f97a5f3e7567 100644 --- a/test/std/containers/associative/multimap/multimap.cons/default_noexcept.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/default_noexcept.pass.cpp @@ -17,9 +17,12 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <map> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -28,19 +31,19 @@ struct some_comp { typedef T value_type; some_comp(); + bool operator()(const T&, const T&) const { return false; } }; int main() { -#if __has_feature(cxx_noexcept) typedef std::pair<const MoveOnly, MoveOnly> V; { typedef std::multimap<MoveOnly, MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C; @@ -50,5 +53,4 @@ int main() typedef std::multimap<MoveOnly, MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/multimap/multimap.cons/dtor_noexcept.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/dtor_noexcept.pass.cpp index dd1701240c630..3a240cd48af32 100644 --- a/test/std/containers/associative/multimap/multimap.cons/dtor_noexcept.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/dtor_noexcept.pass.cpp @@ -11,26 +11,24 @@ // ~multimap() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <map> #include <cassert> #include "MoveOnly.h" #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_comp { typedef T value_type; ~some_comp() noexcept(false); + bool operator()(const T&, const T&) const { return false; } }; -#endif - int main() { -#if __has_feature(cxx_noexcept) typedef std::pair<const MoveOnly, MoveOnly> V; { typedef std::multimap<MoveOnly, MoveOnly> C; @@ -48,5 +46,4 @@ int main() typedef std::multimap<MoveOnly, MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/multimap/multimap.cons/initializer_list.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/initializer_list.pass.cpp index 937a202a55ea0..6f645b63b44cc 100644 --- a/test/std/containers/associative/multimap/multimap.cons/initializer_list.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/initializer_list.pass.cpp @@ -49,7 +49,7 @@ int main() assert(*++i == V(3, 1.5)); assert(*++i == V(3, 2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> C; typedef C::value_type V; diff --git a/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare.pass.cpp index e6677039c90c8..6d20d14f42000 100644 --- a/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare.pass.cpp @@ -53,7 +53,7 @@ int main() assert(*++i == V(3, 2)); assert(m.key_comp() == Cmp(4)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef test_compare<std::less<int> > Cmp; typedef std::multimap<int, double, Cmp, min_allocator<std::pair<const int, double>>> C; diff --git a/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp index 0e73f72793e56..f5d3463aec427 100644 --- a/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp @@ -57,7 +57,7 @@ int main() assert(m.get_allocator() == A(5)); } #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef test_compare<std::less<int> > Cmp; typedef min_allocator<std::pair<const int, double> > A; diff --git a/test/std/containers/associative/multimap/multimap.cons/iter_iter.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/iter_iter.pass.cpp index fa062e2be0b8f..46c56aa0b3ff5 100644 --- a/test/std/containers/associative/multimap/multimap.cons/iter_iter.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/iter_iter.pass.cpp @@ -48,7 +48,7 @@ int main() assert(*next(m.begin(), 7) == V(3, 1.5)); assert(*next(m.begin(), 8) == V(3, 2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp.pass.cpp index d6de59428dd6a..614b3ed8a754e 100644 --- a/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp.pass.cpp @@ -52,7 +52,7 @@ int main() assert(*next(m.begin(), 7) == V(3, 1.5)); assert(*next(m.begin(), 8) == V(3, 2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp index 259fbd145ff6d..31bf72dac96f6 100644 --- a/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp @@ -55,7 +55,7 @@ int main() assert(*next(m.begin(), 7) == V(3, 1.5)); assert(*next(m.begin(), 8) == V(3, 2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<const int, double> V; V ar[] = diff --git a/test/std/containers/associative/multimap/multimap.cons/move.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/move.pass.cpp index aed08867c3ccf..7edec77365d8a 100644 --- a/test/std/containers/associative/multimap/multimap.cons/move.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/move.pass.cpp @@ -75,7 +75,7 @@ int main() assert(mo.size() == 0); assert(distance(mo.begin(), mo.end()) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef test_compare<std::less<int> > C; typedef min_allocator<V> A; diff --git a/test/std/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp index 3ec79eea3554f..41771f62aaeaa 100644 --- a/test/std/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp @@ -169,7 +169,7 @@ int main() M m1(I(a1), I(a1+num), C(), A()); assert(Counter_base::gConstructed == 2*num); - + M m2(m1); assert(m2 == m1); assert(Counter_base::gConstructed == 3*num); @@ -187,9 +187,9 @@ int main() } assert(Counter_base::gConstructed == 2*num); } - assert(Counter_base::gConstructed == 0); + assert(Counter_base::gConstructed == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<MoveOnly, MoveOnly> V; typedef std::pair<const MoveOnly, MoveOnly> VC; diff --git a/test/std/containers/associative/multimap/multimap.cons/move_assign.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/move_assign.pass.cpp index 48854e388e10a..924e9ddf1936b 100644 --- a/test/std/containers/associative/multimap/multimap.cons/move_assign.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/move_assign.pass.cpp @@ -144,7 +144,7 @@ int main() assert(m3.key_comp() == C(5)); assert(m1.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<MoveOnly, MoveOnly> V; typedef std::pair<const MoveOnly, MoveOnly> VC; diff --git a/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.pass.cpp index 635a8dca03574..890cac867f9e9 100644 --- a/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/move_assign_noexcept.pass.cpp @@ -17,6 +17,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <map> #include <cassert> @@ -28,11 +30,11 @@ struct some_comp { typedef T value_type; some_comp& operator=(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; int main() { -#if __has_feature(cxx_noexcept) typedef std::pair<const MoveOnly, MoveOnly> V; { typedef std::multimap<MoveOnly, MoveOnly> C; @@ -50,5 +52,4 @@ int main() typedef std::multimap<MoveOnly, MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/multimap/multimap.cons/move_noexcept.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/move_noexcept.pass.cpp index 0f31f04ff829d..8932b4f83d482 100644 --- a/test/std/containers/associative/multimap/multimap.cons/move_noexcept.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.cons/move_noexcept.pass.cpp @@ -15,6 +15,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <map> #include <cassert> @@ -26,11 +28,11 @@ struct some_comp { typedef T value_type; some_comp(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; int main() { -#if __has_feature(cxx_noexcept) typedef std::pair<const MoveOnly, MoveOnly> V; { typedef std::multimap<MoveOnly, MoveOnly> C; @@ -48,5 +50,4 @@ int main() typedef std::multimap<MoveOnly, MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/multimap/multimap.modifiers/clear.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/clear.pass.cpp index fe9b8c8ba1287..321f4d0bd000c 100644 --- a/test/std/containers/associative/multimap/multimap.modifiers/clear.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.modifiers/clear.pass.cpp @@ -39,7 +39,7 @@ int main() m.clear(); assert(m.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::pair<int, double> P; diff --git a/test/std/containers/associative/multimap/multimap.modifiers/emplace.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/emplace.pass.cpp index 03da4af593720..7f5b698fa0681 100644 --- a/test/std/containers/associative/multimap/multimap.modifiers/emplace.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.modifiers/emplace.pass.cpp @@ -84,7 +84,7 @@ int main() assert(m.begin()->first == 2); assert(m.begin()->second == 3.5); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, DefaultOnly, std::less<int>, min_allocator<std::pair<const int, DefaultOnly>>> M; typedef M::iterator R; diff --git a/test/std/containers/associative/multimap/multimap.modifiers/emplace_hint.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/emplace_hint.pass.cpp index 846d5999a17ee..a6ed318c75982 100644 --- a/test/std/containers/associative/multimap/multimap.modifiers/emplace_hint.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.modifiers/emplace_hint.pass.cpp @@ -89,7 +89,7 @@ int main() assert(m.begin()->first == 2); assert(m.begin()->second == 3.5); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, DefaultOnly, std::less<int>, min_allocator<std::pair<const int, DefaultOnly>>> M; typedef M::iterator R; 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 ba55351c0bde1..6729da41378bb 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 @@ -155,7 +155,7 @@ int main() assert(i == m.begin()); assert(i == m.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::pair<int, double> P; @@ -284,7 +284,7 @@ int main() assert(i == m.end()); } #endif -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 { // This is LWG #2059 typedef TemplateConstructor T; diff --git a/test/std/containers/associative/multimap/multimap.modifiers/erase_iter_iter.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/erase_iter_iter.pass.cpp index 4d3789493110b..1069542c5430e 100644 --- a/test/std/containers/associative/multimap/multimap.modifiers/erase_iter_iter.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.modifiers/erase_iter_iter.pass.cpp @@ -86,7 +86,7 @@ int main() assert(i == m.begin()); assert(i == m.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::pair<int, double> P; diff --git a/test/std/containers/associative/multimap/multimap.modifiers/erase_key.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/erase_key.pass.cpp index 33821d3e35962..44a6abef6ed00 100644 --- a/test/std/containers/associative/multimap/multimap.modifiers/erase_key.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.modifiers/erase_key.pass.cpp @@ -84,7 +84,7 @@ int main() assert(m.size() == 0); assert(i == 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::pair<int, double> P; diff --git a/test/std/containers/associative/multimap/multimap.modifiers/insert_allocator_requirements.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/insert_allocator_requirements.pass.cpp new file mode 100644 index 0000000000000..225bf67bb1f6e --- /dev/null +++ b/test/std/containers/associative/multimap/multimap.modifiers/insert_allocator_requirements.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// insert(...) + +// UNSUPPORTED: c++98, c++03 + +#include <map> + +#include "container_test_types.h" +#include "../../../map_allocator_requirement_test_templates.h" + + +int main() +{ + testMultimapInsert<TCT::multimap<> >(); + testMultimapInsertHint<TCT::multimap<> >(); +} diff --git a/test/std/containers/associative/multimap/multimap.modifiers/insert_cv.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/insert_cv.pass.cpp index d9afc9d0fdf0e..53874311c7826 100644 --- a/test/std/containers/associative/multimap/multimap.modifiers/insert_cv.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.modifiers/insert_cv.pass.cpp @@ -16,66 +16,54 @@ #include <map> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" -int main() -{ - { - typedef std::multimap<int, double> M; - typedef M::iterator R; - M m; - R r = m.insert(M::value_type(2, 2.5)); - assert(r == m.begin()); - assert(m.size() == 1); - assert(r->first == 2); - assert(r->second == 2.5); +template <class Container> +void do_insert_test() { + typedef Container M; + typedef typename M::iterator R; + typedef typename M::value_type VT; + M m; + const VT v1(2, 2.5); + R r = m.insert(v1); + assert(r == m.begin()); + assert(m.size() == 1); + assert(r->first == 2); + assert(r->second == 2.5); - r = m.insert(M::value_type(1, 1.5)); - assert(r == m.begin()); - assert(m.size() == 2); - assert(r->first == 1); - assert(r->second == 1.5); + const VT v2(1, 1.5); + r = m.insert(v2); + assert(r == m.begin()); + assert(m.size() == 2); + assert(r->first == 1); + assert(r->second == 1.5); - r = m.insert(M::value_type(3, 3.5)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3.5); + const VT v3(3, 3.5); + r = m.insert(v3); + assert(r == prev(m.end())); + assert(m.size() == 3); + assert(r->first == 3); + assert(r->second == 3.5); - r = m.insert(M::value_type(3, 3.5)); - assert(r == prev(m.end())); - assert(m.size() == 4); - assert(r->first == 3); - assert(r->second == 3.5); + const VT v4(3, 3.5); + r = m.insert(v4); + assert(r == prev(m.end())); + assert(m.size() == 4); + assert(r->first == 3); + assert(r->second == 3.5); +} + +int main() +{ + { + typedef std::multimap<int, double> Container; + do_insert_test<Container>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { - typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; - typedef M::iterator R; - M m; - R r = m.insert(M::value_type(2, 2.5)); - assert(r == m.begin()); - assert(m.size() == 1); - assert(r->first == 2); - assert(r->second == 2.5); - - r = m.insert(M::value_type(1, 1.5)); - assert(r == m.begin()); - assert(m.size() == 2); - assert(r->first == 1); - assert(r->second == 1.5); - - r = m.insert(M::value_type(3, 3.5)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3.5); - - r = m.insert(M::value_type(3, 3.5)); - assert(r == prev(m.end())); - assert(m.size() == 4); - assert(r->first == 3); - assert(r->second == 3.5); + typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> Container; + do_insert_test<Container>(); } #endif } diff --git a/test/std/containers/associative/multimap/multimap.modifiers/insert_initializer_list.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/insert_initializer_list.pass.cpp index 5e1a1d4125ef4..89befb3e99719 100644 --- a/test/std/containers/associative/multimap/multimap.modifiers/insert_initializer_list.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.modifiers/insert_initializer_list.pass.cpp @@ -53,7 +53,7 @@ int main() assert(*++i == V(3, 2)); assert(*++i == V(3, 1.5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> C; typedef C::value_type V; diff --git a/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_cv.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_cv.pass.cpp index b83c802c04cf6..05e1096cb547d 100644 --- a/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_cv.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_cv.pass.cpp @@ -16,66 +16,52 @@ #include <map> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" -int main() +template <class Container> +void do_insert_hint_test() { - { - typedef std::multimap<int, double> M; - typedef M::iterator R; - M m; - R r = m.insert(m.end(), M::value_type(2, 2.5)); - assert(r == m.begin()); - assert(m.size() == 1); - assert(r->first == 2); - assert(r->second == 2.5); + typedef Container M; + typedef typename M::iterator R; + typedef typename M::value_type VT; + M m; + const VT v1(2, 2.5); + R r = m.insert(m.end(), v1); + assert(r == m.begin()); + assert(m.size() == 1); + assert(r->first == 2); + assert(r->second == 2.5); - r = m.insert(m.end(), M::value_type(1, 1.5)); - assert(r == m.begin()); - assert(m.size() == 2); - assert(r->first == 1); - assert(r->second == 1.5); + const VT v2(1, 1.5); + r = m.insert(m.end(), v2); + assert(r == m.begin()); + assert(m.size() == 2); + assert(r->first == 1); + assert(r->second == 1.5); - r = m.insert(m.end(), M::value_type(3, 3.5)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3.5); + const VT v3(3, 3.5); + r = m.insert(m.end(), v3); + assert(r == prev(m.end())); + assert(m.size() == 3); + assert(r->first == 3); + assert(r->second == 3.5); - r = m.insert(prev(m.end()), M::value_type(3, 4.5)); - assert(r == prev(m.end(), 2)); - assert(m.size() == 4); - assert(r->first == 3); - assert(r->second == 4.5); - } -#if __cplusplus >= 201103L + const VT v4(3, 4.5); + r = m.insert(prev(m.end()), v4); + assert(r == prev(m.end(), 2)); + assert(m.size() == 4); + assert(r->first == 3); + assert(r->second == 4.5); +} + +int main() +{ + do_insert_hint_test<std::multimap<int, double> >(); +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; - typedef M::iterator R; - M m; - R r = m.insert(m.end(), M::value_type(2, 2.5)); - assert(r == m.begin()); - assert(m.size() == 1); - assert(r->first == 2); - assert(r->second == 2.5); - - r = m.insert(m.end(), M::value_type(1, 1.5)); - assert(r == m.begin()); - assert(m.size() == 2); - assert(r->first == 1); - assert(r->second == 1.5); - - r = m.insert(m.end(), M::value_type(3, 3.5)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3.5); - - r = m.insert(prev(m.end()), M::value_type(3, 4.5)); - assert(r == prev(m.end(), 2)); - assert(m.size() == 4); - assert(r->first == 3); - assert(r->second == 4.5); + do_insert_hint_test<M>(); } #endif } diff --git a/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_iter.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_iter.pass.cpp index 70ff7ef6d6b89..1bf437a934438 100644 --- a/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_iter.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_iter.pass.cpp @@ -59,7 +59,7 @@ int main() assert(next(m.begin(), 8)->first == 3); assert(next(m.begin(), 8)->second == 2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::pair<int, double> P; diff --git a/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_rv.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_rv.pass.cpp index 7035de83f9905..47e0d371bb485 100644 --- a/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_rv.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_rv.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <map> // class multimap @@ -21,73 +23,53 @@ #include "min_allocator.h" #include "test_macros.h" -int main() +template <class Container, class Pair> +void do_insert_rv_test() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - { - typedef std::multimap<int, MoveOnly> M; - typedef std::pair<int, MoveOnly> P; - typedef M::iterator R; - M m; - R r = m.insert(m.cend(), P(2, 2)); - assert(r == m.begin()); - assert(m.size() == 1); - assert(r->first == 2); - assert(r->second == 2); + typedef Container M; + typedef Pair P; + typedef typename M::iterator R; + M m; + R r = m.insert(m.cend(), P(2, 2)); + assert(r == m.begin()); + assert(m.size() == 1); + assert(r->first == 2); + assert(r->second == 2); - r = m.insert(m.cend(), P(1, 1)); - assert(r == m.begin()); - assert(m.size() == 2); - assert(r->first == 1); - assert(r->second == 1); + r = m.insert(m.cend(), P(1, 1)); + assert(r == m.begin()); + assert(m.size() == 2); + assert(r->first == 1); + assert(r->second == 1); - r = m.insert(m.cend(), P(3, 3)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3); + r = m.insert(m.cend(), P(3, 3)); + assert(r == prev(m.end())); + assert(m.size() == 3); + assert(r->first == 3); + assert(r->second == 3); + + r = m.insert(m.cend(), P(3, 2)); + assert(r == prev(m.end())); + assert(m.size() == 4); + assert(r->first == 3); + assert(r->second == 2); +} + +int main() +{ + do_insert_rv_test<std::multimap<int, MoveOnly>, std::pair<int, MoveOnly> >(); + do_insert_rv_test<std::multimap<int, MoveOnly>, std::pair<const int, MoveOnly> >(); - r = m.insert(m.cend(), P(3, 2)); - assert(r == prev(m.end())); - assert(m.size() == 4); - assert(r->first == 3); - assert(r->second == 2); - } -#if TEST_STD_VER >= 11 { typedef std::multimap<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M; typedef std::pair<int, MoveOnly> P; - typedef M::iterator R; - M m; - R r = m.insert(m.cend(), P(2, 2)); - assert(r == m.begin()); - assert(m.size() == 1); - assert(r->first == 2); - assert(r->second == 2); + typedef std::pair<const int, MoveOnly> CP; + do_insert_rv_test<M, P>(); + do_insert_rv_test<M, CP>(); - r = m.insert(m.cend(), P(1, 1)); - assert(r == m.begin()); - assert(m.size() == 2); - assert(r->first == 1); - assert(r->second == 1); - - r = m.insert(m.cend(), P(3, 3)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3); - - r = m.insert(m.cend(), P(3, 2)); - assert(r == prev(m.end())); - assert(m.size() == 4); - assert(r->first == 3); - assert(r->second == 2); } -#endif -#if TEST_STD_VER > 14 { typedef std::multimap<int, MoveOnly> M; - typedef std::pair<int, MoveOnly> P; typedef M::iterator R; M m; R r = m.insert(m.cend(), {2, MoveOnly(2)}); @@ -114,6 +96,4 @@ int main() assert(r->first == 3); assert(r->second == 2); } -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/std/containers/associative/multimap/multimap.modifiers/insert_rv.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/insert_rv.pass.cpp index 825e304f65a81..022de873f7f1f 100644 --- a/test/std/containers/associative/multimap/multimap.modifiers/insert_rv.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.modifiers/insert_rv.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <map> // class multimap @@ -21,68 +23,45 @@ #include "min_allocator.h" #include "test_macros.h" -int main() +template <class Container> +void do_insert_rv_test() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - { - typedef std::multimap<int, MoveOnly> M; - typedef M::iterator R; - M m; - R r = m.insert(M::value_type(2, 2)); - assert(r == m.begin()); - assert(m.size() == 1); - assert(r->first == 2); - assert(r->second == 2); + typedef std::multimap<int, MoveOnly> M; + typedef typename M::iterator R; + typedef typename M::value_type VT; + M m; + R r = m.insert(VT(2, 2)); + assert(r == m.begin()); + assert(m.size() == 1); + assert(r->first == 2); + assert(r->second == 2); - r = m.insert(M::value_type(1, 1)); - assert(r == m.begin()); - assert(m.size() == 2); - assert(r->first == 1); - assert(r->second == 1); + r = m.insert(VT(1, 1)); + assert(r == m.begin()); + assert(m.size() == 2); + assert(r->first == 1); + assert(r->second == 1); - r = m.insert(M::value_type(3, 3)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3); + r = m.insert(VT(3, 3)); + assert(r == prev(m.end())); + assert(m.size() == 3); + assert(r->first == 3); + assert(r->second == 3); - r = m.insert(M::value_type(3, 3)); - assert(r == prev(m.end())); - assert(m.size() == 4); - assert(r->first == 3); - assert(r->second == 3); - } -#if TEST_STD_VER >= 11 + r = m.insert(VT(3, 3)); + assert(r == prev(m.end())); + assert(m.size() == 4); + assert(r->first == 3); + assert(r->second == 3); +} + +int main() +{ + do_insert_rv_test<std::multimap<int, MoveOnly>>(); { typedef std::multimap<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M; - typedef M::iterator R; - M m; - R r = m.insert(M::value_type(2, 2)); - assert(r == m.begin()); - assert(m.size() == 1); - assert(r->first == 2); - assert(r->second == 2); - - r = m.insert(M::value_type(1, 1)); - assert(r == m.begin()); - assert(m.size() == 2); - assert(r->first == 1); - assert(r->second == 1); - - r = m.insert(M::value_type(3, 3)); - assert(r == prev(m.end())); - assert(m.size() == 3); - assert(r->first == 3); - assert(r->second == 3); - - r = m.insert(M::value_type(3, 3)); - assert(r == prev(m.end())); - assert(m.size() == 4); - assert(r->first == 3); - assert(r->second == 3); + do_insert_rv_test<M>(); } -#endif -#if TEST_STD_VER > 14 { typedef std::multimap<int, MoveOnly> M; typedef M::iterator R; @@ -111,6 +90,4 @@ int main() assert(r->first == 3); assert(r->second == 3); } -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } 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 c666c295f3a07..92f90f551d44f 100644 --- a/test/std/containers/associative/multimap/multimap.ops/count.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/count.pass.cpp @@ -56,7 +56,7 @@ int main() assert(r == 0); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; { diff --git a/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp index 7da13bb0d66dc..b993f4f89087d 100644 --- a/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: c++03, c++11 +// XFAIL: c++98, c++03, c++11 // <map> @@ -15,9 +15,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/multimap/multimap.ops/count1.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/count1.fail.cpp index f30d1bfd88d62..d0f3f1c0fdb70 100644 --- a/test/std/containers/associative/multimap/multimap.ops/count1.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/count1.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/multimap/multimap.ops/count2.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/count2.fail.cpp index ffb7eb6a559a6..86d492f7f5e08 100644 --- a/test/std/containers/associative/multimap/multimap.ops/count2.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/count2.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/multimap/multimap.ops/count3.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/count3.fail.cpp index 4bb9d14634f31..55095efb3d6a0 100644 --- a/test/std/containers/associative/multimap/multimap.ops/count3.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/count3.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 5a071042461a7..31eac26816ac3 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 @@ -101,7 +101,7 @@ int main() assert(r.second == m.end()); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; { 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 index c0f07468ec5ed..a3a51e6ccbf91 100644 --- a/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: c++03, c++11 +// XFAIL: c++98, c++03, c++11 // <map> @@ -15,9 +15,9 @@ // 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 +// +// 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 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 index f022e94324fd9..f793bf8859ba2 100644 --- a/test/std/containers/associative/multimap/multimap.ops/equal_range1.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/equal_range1.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 index 695e71703e3b9..d099a8c81a1b9 100644 --- a/test/std/containers/associative/multimap/multimap.ops/equal_range2.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/equal_range2.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 index 59c2855e8f695..e53fff9427931 100644 --- a/test/std/containers/associative/multimap/multimap.ops/equal_range3.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/equal_range3.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 a60e42cf8592d..2fd8c05b5f5e2 100644 --- a/test/std/containers/associative/multimap/multimap.ops/find.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/find.pass.cpp @@ -83,7 +83,7 @@ int main() assert(r == m.end()); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; { diff --git a/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp index 4f3369870c8f2..03a6e18830510 100644 --- a/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: c++03, c++11 +// XFAIL: c++98, c++03, c++11 // <map> @@ -15,9 +15,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/multimap/multimap.ops/find1.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/find1.fail.cpp index e1eef034064d0..2759af46be144 100644 --- a/test/std/containers/associative/multimap/multimap.ops/find1.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/find1.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/multimap/multimap.ops/find2.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/find2.fail.cpp index 4c03f583fa1c0..c67f3b39dabd7 100644 --- a/test/std/containers/associative/multimap/multimap.ops/find2.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/find2.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/multimap/multimap.ops/find3.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/find3.fail.cpp index f10bc60aa8641..e53fc4d558870 100644 --- a/test/std/containers/associative/multimap/multimap.ops/find3.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/find3.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 38b931802f8e4..5c0315f956a8d 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 @@ -87,7 +87,7 @@ int main() assert(r == m.end()); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; { 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 index c5271f65d7e51..77927bb5abeda 100644 --- a/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: c++03, c++11 +// XFAIL: c++98, c++03, c++11 // <map> @@ -15,9 +15,9 @@ // 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 +// +// 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 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 index b452be864e2bc..9b39573a5f42c 100644 --- a/test/std/containers/associative/multimap/multimap.ops/lower_bound1.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/lower_bound1.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 index a2ba30236a40d..68710bd1bc38d 100644 --- a/test/std/containers/associative/multimap/multimap.ops/lower_bound2.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/lower_bound2.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 index 50d9fca91ad90..f254ef4785a1a 100644 --- a/test/std/containers/associative/multimap/multimap.ops/lower_bound3.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/lower_bound3.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 7c647a9426cbe..012354cef7bbf 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 @@ -87,7 +87,7 @@ int main() assert(r == m.end()); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; { 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 index 322c6f55130c8..3f6852d085c36 100644 --- a/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: c++03, c++11 +// XFAIL: c++98, c++03, c++11 // <map> @@ -15,9 +15,9 @@ // 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 +// +// 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 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 index bb78ad6981601..d47d7bfc89f47 100644 --- a/test/std/containers/associative/multimap/multimap.ops/upper_bound1.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/upper_bound1.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 index a79d5938e56e4..a3da9d82c95c5 100644 --- a/test/std/containers/associative/multimap/multimap.ops/upper_bound2.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/upper_bound2.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 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 index 1c1dc74b72c79..6ffdb206cc30c 100644 --- a/test/std/containers/associative/multimap/multimap.ops/upper_bound3.fail.cpp +++ b/test/std/containers/associative/multimap/multimap.ops/upper_bound3.fail.cpp @@ -13,9 +13,9 @@ // 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 +// +// 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 diff --git a/test/std/containers/associative/multimap/multimap.special/member_swap.pass.cpp b/test/std/containers/associative/multimap/multimap.special/member_swap.pass.cpp index fb17e7340bd4f..f216f9f76a11d 100644 --- a/test/std/containers/associative/multimap/multimap.special/member_swap.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.special/member_swap.pass.cpp @@ -96,7 +96,7 @@ int main() assert(m2 == m1_save); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; { diff --git a/test/std/containers/associative/multimap/multimap.special/non_member_swap.pass.cpp b/test/std/containers/associative/multimap/multimap.special/non_member_swap.pass.cpp index a91dfebb14a9d..a075919bba9aa 100644 --- a/test/std/containers/associative/multimap/multimap.special/non_member_swap.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.special/non_member_swap.pass.cpp @@ -98,6 +98,7 @@ int main() assert(m1 == m2_save); assert(m2 == m1_save); } + } { typedef test_allocator<V> A; typedef test_compare<std::less<int> > C; @@ -166,8 +167,7 @@ int main() assert(m2.key_comp() == C(1)); assert(m2.get_allocator() == A(1)); } - } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; { @@ -242,6 +242,7 @@ int main() assert(m1 == m2_save); assert(m2 == m1_save); } + } { typedef min_allocator<V> A; typedef test_compare<std::less<int> > C; @@ -276,6 +277,5 @@ int main() assert(m2.key_comp() == C(1)); assert(m2.get_allocator() == A()); } - } #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 e70ee1fae565c..ffc71b0eeb924 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <map> // void swap(multimap& c) @@ -15,13 +17,14 @@ // // In C++17, the standard says that swap shall have: // noexcept(allocator_traits<Allocator>::is_always_equal::value && -// noexcept(swap(declval<Compare&>(), declval<Compare&>()))); +// noexcept(swap(declval<Compare&>(), declval<Compare&>()))); // This tests a conforming extension #include <map> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -29,23 +32,20 @@ template <class T> struct some_comp { typedef T value_type; - + some_comp() {} some_comp(const some_comp&) {} - void deallocate(void*, unsigned) {} - - typedef std::true_type propagate_on_container_swap; + bool operator()(const T&, const T&) const { return false; } }; 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; + bool operator()(const T&, const T&) const { return false; } }; #if TEST_STD_VER >= 14 @@ -57,7 +57,7 @@ template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -69,7 +69,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -82,7 +82,7 @@ template <class T> struct some_alloc3 { typedef T value_type; - + some_alloc3() {} some_alloc3(const some_alloc3&); void deallocate(void*, unsigned) {} @@ -93,7 +93,6 @@ struct some_alloc3 int main() { -#if __has_feature(cxx_noexcept) typedef std::pair<const MoveOnly, MoveOnly> V; { typedef std::multimap<MoveOnly, MoveOnly> C; @@ -144,6 +143,4 @@ int main() static_assert( noexcept(swap(c1, c2)), ""); } #endif - -#endif } diff --git a/test/std/containers/associative/multimap/size.pass.cpp b/test/std/containers/associative/multimap/size.pass.cpp index ac71d4c95b641..7ba7ceb2be6e0 100644 --- a/test/std/containers/associative/multimap/size.pass.cpp +++ b/test/std/containers/associative/multimap/size.pass.cpp @@ -37,7 +37,7 @@ int main() m.erase(m.begin()); assert(m.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; M m; diff --git a/test/std/containers/associative/multimap/types.pass.cpp b/test/std/containers/associative/multimap/types.pass.cpp index a0f4db056a83b..999ecbb7c2236 100644 --- a/test/std/containers/associative/multimap/types.pass.cpp +++ b/test/std/containers/associative/multimap/types.pass.cpp @@ -50,7 +50,7 @@ int main() static_assert((std::is_same<C::size_type, std::size_t>::value), ""); static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), ""); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> C; static_assert((std::is_same<C::key_type, int>::value), ""); diff --git a/test/std/containers/associative/multiset/clear.pass.cpp b/test/std/containers/associative/multiset/clear.pass.cpp index 3069de5a300d9..f762ef7d35044 100644 --- a/test/std/containers/associative/multiset/clear.pass.cpp +++ b/test/std/containers/associative/multiset/clear.pass.cpp @@ -39,7 +39,7 @@ int main() m.clear(); assert(m.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> M; typedef int V; diff --git a/test/std/containers/associative/multiset/count.pass.cpp b/test/std/containers/associative/multiset/count.pass.cpp index 93bd6f80eaad2..997a949388cf0 100644 --- a/test/std/containers/associative/multiset/count.pass.cpp +++ b/test/std/containers/associative/multiset/count.pass.cpp @@ -55,7 +55,7 @@ int main() assert(r == 0); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; typedef std::multiset<int, std::less<int>, min_allocator<int>> M; diff --git a/test/std/containers/associative/multiset/emplace.pass.cpp b/test/std/containers/associative/multiset/emplace.pass.cpp index 450ee6cd35a39..93842a250f8ef 100644 --- a/test/std/containers/associative/multiset/emplace.pass.cpp +++ b/test/std/containers/associative/multiset/emplace.pass.cpp @@ -68,7 +68,7 @@ int main() assert(m.size() == 1); assert(*r == 2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> M; typedef M::iterator R; diff --git a/test/std/containers/associative/multiset/emplace_hint.pass.cpp b/test/std/containers/associative/multiset/emplace_hint.pass.cpp index 194adf761c4c2..48519fd4356a8 100644 --- a/test/std/containers/associative/multiset/emplace_hint.pass.cpp +++ b/test/std/containers/associative/multiset/emplace_hint.pass.cpp @@ -68,7 +68,7 @@ int main() assert(m.size() == 1); assert(*r == 2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> M; typedef M::iterator R; diff --git a/test/std/containers/associative/multiset/empty.pass.cpp b/test/std/containers/associative/multiset/empty.pass.cpp index 32aef90d41886..acca4e021e0c3 100644 --- a/test/std/containers/associative/multiset/empty.pass.cpp +++ b/test/std/containers/associative/multiset/empty.pass.cpp @@ -29,7 +29,7 @@ int main() m.clear(); assert(m.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> M; M m; diff --git a/test/std/containers/associative/multiset/equal_range.pass.cpp b/test/std/containers/associative/multiset/equal_range.pass.cpp index 8c69d0c61ec54..7ab95cfb8f67b 100644 --- a/test/std/containers/associative/multiset/equal_range.pass.cpp +++ b/test/std/containers/associative/multiset/equal_range.pass.cpp @@ -100,7 +100,7 @@ int main() assert(r.second == next(m.begin(), 9)); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; typedef std::multiset<int, std::less<int>, min_allocator<int>> M; diff --git a/test/std/containers/associative/multiset/erase_iter.pass.cpp b/test/std/containers/associative/multiset/erase_iter.pass.cpp index 1d41540edb8a7..8ee45c64cff09 100644 --- a/test/std/containers/associative/multiset/erase_iter.pass.cpp +++ b/test/std/containers/associative/multiset/erase_iter.pass.cpp @@ -106,7 +106,7 @@ int main() assert(i == m.begin()); assert(i == m.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> M; typedef int V; @@ -186,7 +186,7 @@ int main() assert(i == m.end()); } #endif -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 { // This is LWG #2059 typedef TemplateConstructor T; diff --git a/test/std/containers/associative/multiset/erase_iter_iter.pass.cpp b/test/std/containers/associative/multiset/erase_iter_iter.pass.cpp index e1d7090d816f0..70d3477907e3d 100644 --- a/test/std/containers/associative/multiset/erase_iter_iter.pass.cpp +++ b/test/std/containers/associative/multiset/erase_iter_iter.pass.cpp @@ -78,7 +78,7 @@ int main() assert(m.size() == 0); assert(i == m.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> M; typedef int V; diff --git a/test/std/containers/associative/multiset/erase_key.pass.cpp b/test/std/containers/associative/multiset/erase_key.pass.cpp index e9bce1e1b6402..7293bcfb2c358 100644 --- a/test/std/containers/associative/multiset/erase_key.pass.cpp +++ b/test/std/containers/associative/multiset/erase_key.pass.cpp @@ -72,7 +72,7 @@ int main() assert(m.size() == 0); assert(i == 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> M; typedef int V; diff --git a/test/std/containers/associative/multiset/find.pass.cpp b/test/std/containers/associative/multiset/find.pass.cpp index 364460a6ca3af..3b7d96fe91105 100644 --- a/test/std/containers/associative/multiset/find.pass.cpp +++ b/test/std/containers/associative/multiset/find.pass.cpp @@ -92,7 +92,7 @@ int main() assert(r == next(m.begin(), 8)); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; typedef std::multiset<int, std::less<int>, min_allocator<int>> M; diff --git a/test/std/containers/associative/multiset/incomplete_type.pass.cpp b/test/std/containers/associative/multiset/incomplete_type.pass.cpp new file mode 100644 index 0000000000000..0355e18f9f296 --- /dev/null +++ b/test/std/containers/associative/multiset/incomplete_type.pass.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. +// +//===----------------------------------------------------------------------===// + +// <set> + +// Check that std::multiset and it's iterators can be instantiated with an incomplete +// type. + +#include <set> + +struct A { + typedef std::multiset<A> Set; + int data; + Set m; + Set::iterator it; + Set::const_iterator cit; +}; + +inline bool operator==(A const& L, A const& R) { return &L == &R; } +inline bool operator<(A const& L, A const& R) { return L.data < R.data; } +int main() { + A a; +} diff --git a/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp b/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp new file mode 100644 index 0000000000000..a280d10d5ab21 --- /dev/null +++ b/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <set> + +// class multiset + +// insert(...) + +// UNSUPPORTED: c++98, c++03 + +#include <set> + +#include "container_test_types.h" +#include "../../set_allocator_requirement_test_templates.h" + +int main() +{ + testMultisetInsert<TCT::multiset<> >(); +} diff --git a/test/std/containers/associative/multiset/insert_cv.pass.cpp b/test/std/containers/associative/multiset/insert_cv.pass.cpp index 179715753ab02..2aa920d709725 100644 --- a/test/std/containers/associative/multiset/insert_cv.pass.cpp +++ b/test/std/containers/associative/multiset/insert_cv.pass.cpp @@ -44,7 +44,7 @@ int main() assert(m.size() == 4); assert(*r == 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> M; typedef M::iterator R; diff --git a/test/std/containers/associative/multiset/insert_initializer_list.pass.cpp b/test/std/containers/associative/multiset/insert_initializer_list.pass.cpp index 7e923f2516ddc..7b82cea5fbea2 100644 --- a/test/std/containers/associative/multiset/insert_initializer_list.pass.cpp +++ b/test/std/containers/associative/multiset/insert_initializer_list.pass.cpp @@ -39,7 +39,7 @@ int main() assert(*++i == V(10)); } #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> C; typedef C::value_type V; diff --git a/test/std/containers/associative/multiset/insert_iter_cv.pass.cpp b/test/std/containers/associative/multiset/insert_iter_cv.pass.cpp index 7d204024c212b..ca08bacad2f1f 100644 --- a/test/std/containers/associative/multiset/insert_iter_cv.pass.cpp +++ b/test/std/containers/associative/multiset/insert_iter_cv.pass.cpp @@ -44,7 +44,7 @@ int main() assert(m.size() == 4); assert(*r == 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> M; typedef M::iterator R; diff --git a/test/std/containers/associative/multiset/insert_iter_iter.pass.cpp b/test/std/containers/associative/multiset/insert_iter_iter.pass.cpp index 189c454986697..fb664d74e4be4 100644 --- a/test/std/containers/associative/multiset/insert_iter_iter.pass.cpp +++ b/test/std/containers/associative/multiset/insert_iter_iter.pass.cpp @@ -51,7 +51,7 @@ int main() assert(*next(m.begin(), 7) == 3); assert(*next(m.begin(), 8) == 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> M; typedef int V; diff --git a/test/std/containers/associative/multiset/insert_iter_rv.pass.cpp b/test/std/containers/associative/multiset/insert_iter_rv.pass.cpp index ee631f005c931..0afc8dc87c23a 100644 --- a/test/std/containers/associative/multiset/insert_iter_rv.pass.cpp +++ b/test/std/containers/associative/multiset/insert_iter_rv.pass.cpp @@ -47,7 +47,7 @@ int main() assert(*r == 3); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<MoveOnly, std::less<MoveOnly>, min_allocator<MoveOnly>> M; typedef M::iterator R; diff --git a/test/std/containers/associative/multiset/insert_rv.pass.cpp b/test/std/containers/associative/multiset/insert_rv.pass.cpp index 29c233e9a119a..3ee464bc5bc72 100644 --- a/test/std/containers/associative/multiset/insert_rv.pass.cpp +++ b/test/std/containers/associative/multiset/insert_rv.pass.cpp @@ -47,7 +47,7 @@ int main() assert(*r == 3); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<MoveOnly, std::less<MoveOnly>, min_allocator<MoveOnly>> M; typedef M::iterator R; diff --git a/test/std/containers/associative/multiset/iterator.pass.cpp b/test/std/containers/associative/multiset/iterator.pass.cpp index d1f0ecfd6aa06..c152a43981963 100644 --- a/test/std/containers/associative/multiset/iterator.pass.cpp +++ b/test/std/containers/associative/multiset/iterator.pass.cpp @@ -70,7 +70,7 @@ int main() std::multiset<int>::const_iterator k = i; assert(i == k); for (int j = 1; j <= 8; ++j) - for (int k = 0; k < 3; ++k, ++i) + for (int n = 0; n < 3; ++n, ++i) assert(*i == j); } { @@ -113,7 +113,7 @@ int main() for (int k = 0; k < 3; ++k, ++i) assert(*i == j); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; V ar[] = @@ -151,7 +151,7 @@ int main() std::multiset<int, std::less<int>, min_allocator<int>>::const_iterator k = i; assert(i == k); for (int j = 1; j <= 8; ++j) - for (int k = 0; k < 3; ++k, ++i) + for (int n = 0; n < 3; ++n, ++i) assert(*i == j); } { diff --git a/test/std/containers/associative/multiset/lower_bound.pass.cpp b/test/std/containers/associative/multiset/lower_bound.pass.cpp index e466791d9356f..ae8cfe6eff4df 100644 --- a/test/std/containers/associative/multiset/lower_bound.pass.cpp +++ b/test/std/containers/associative/multiset/lower_bound.pass.cpp @@ -86,7 +86,7 @@ int main() assert(r == next(m.begin(), 9)); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; typedef std::multiset<int, std::less<int>, min_allocator<int>> M; diff --git a/test/std/containers/associative/multiset/max_size.pass.cpp b/test/std/containers/associative/multiset/max_size.pass.cpp index 5524f771b341a..79492c9b1c400 100644 --- a/test/std/containers/associative/multiset/max_size.pass.cpp +++ b/test/std/containers/associative/multiset/max_size.pass.cpp @@ -25,7 +25,7 @@ int main() M m; assert(m.max_size() != 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> M; M m; diff --git a/test/std/containers/associative/multiset/multiset.cons/assign_initializer_list.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/assign_initializer_list.pass.cpp index 7d76581d6d8e7..2c5318afd73bf 100644 --- a/test/std/containers/associative/multiset/multiset.cons/assign_initializer_list.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.cons/assign_initializer_list.pass.cpp @@ -37,7 +37,7 @@ int main() assert(*++i == V(6)); } #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> C; typedef C::value_type V; diff --git a/test/std/containers/associative/multiset/multiset.cons/compare_copy_constructible.fail.cpp b/test/std/containers/associative/multiset/multiset.cons/compare_copy_constructible.fail.cpp new file mode 100644 index 0000000000000..2eade5299d6f0 --- /dev/null +++ b/test/std/containers/associative/multiset/multiset.cons/compare_copy_constructible.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. +// +//===----------------------------------------------------------------------===// + +// <set> + +// Check that std::multiset fails to instantiate if the comparison predicate is +// not copy-constructible. This is LWG issue 2436 + +#include <set> + +template <class T> +struct Comp { + bool operator () (const T& lhs, const T& rhs) const { return lhs < rhs; } + + Comp () {} +private: + Comp (const Comp &); // declared but not defined + }; + + +int main() { + std::multiset<int, Comp<int> > m; +} diff --git a/test/std/containers/associative/multiset/multiset.cons/default.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/default.pass.cpp index 5bb0312f012b6..0bc50ab7aaf86 100644 --- a/test/std/containers/associative/multiset/multiset.cons/default.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.cons/default.pass.cpp @@ -25,7 +25,7 @@ int main() assert(m.empty()); assert(m.begin() == m.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::multiset<int, std::less<int>, min_allocator<int>> m; assert(m.empty()); diff --git a/test/std/containers/associative/multiset/multiset.cons/default_noexcept.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/default_noexcept.pass.cpp index bf8c53b9ee5d6..15520e7834ff7 100644 --- a/test/std/containers/associative/multiset/multiset.cons/default_noexcept.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.cons/default_noexcept.pass.cpp @@ -17,9 +17,12 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <set> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -28,18 +31,18 @@ struct some_comp { typedef T value_type; some_comp(); + bool operator()(const T&, const T&) const { return false; } }; int main() { -#if __has_feature(cxx_noexcept) { typedef std::multiset<MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::multiset<MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::multiset<MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C; @@ -49,5 +52,4 @@ int main() typedef std::multiset<MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/multiset/multiset.cons/dtor_noexcept.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/dtor_noexcept.pass.cpp index fd612c06dbbc1..f4e868ebbc8f1 100644 --- a/test/std/containers/associative/multiset/multiset.cons/dtor_noexcept.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.cons/dtor_noexcept.pass.cpp @@ -11,26 +11,24 @@ // ~multiset() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <set> #include <cassert> #include "MoveOnly.h" #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_comp { typedef T value_type; ~some_comp() noexcept(false); + bool operator()(const T&, const T&) const { return false; } }; -#endif - int main() { -#if __has_feature(cxx_noexcept) { typedef std::multiset<MoveOnly> C; static_assert(std::is_nothrow_destructible<C>::value, ""); @@ -47,5 +45,4 @@ int main() typedef std::multiset<MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/multiset/multiset.cons/initializer_list.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/initializer_list.pass.cpp index dadafec7c3b1c..7327bf62646b1 100644 --- a/test/std/containers/associative/multiset/multiset.cons/initializer_list.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.cons/initializer_list.pass.cpp @@ -36,7 +36,7 @@ int main() assert(*++i == V(6)); } #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> C; typedef C::value_type V; diff --git a/test/std/containers/associative/multiset/multiset.cons/iter_iter.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/iter_iter.pass.cpp index f6c1fd76de146..ebe8353bab1fb 100644 --- a/test/std/containers/associative/multiset/multiset.cons/iter_iter.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.cons/iter_iter.pass.cpp @@ -50,7 +50,7 @@ int main() assert(*next(m.begin(), 7) == 3); assert(*next(m.begin(), 8) == 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; V ar[] = diff --git a/test/std/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp index 4ed00c7124cc0..4313f46a03d7f 100644 --- a/test/std/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp @@ -24,6 +24,7 @@ int main() { + { typedef int V; V ar[] = { @@ -55,6 +56,7 @@ int main() assert(*next(m.begin(), 6) == 3); assert(*next(m.begin(), 7) == 3); assert(*next(m.begin(), 8) == 3); + } #if _LIBCPP_STD_VER > 11 { typedef int V; diff --git a/test/std/containers/associative/multiset/multiset.cons/move.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/move.pass.cpp index 40321cd247e19..5a905cf15a086 100644 --- a/test/std/containers/associative/multiset/multiset.cons/move.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.cons/move.pass.cpp @@ -77,7 +77,7 @@ int main() assert(distance(mo.begin(), mo.end()) == 0); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; V ar[] = diff --git a/test/std/containers/associative/multiset/multiset.cons/move_alloc.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/move_alloc.pass.cpp index 4408208f2ac44..3da3fc09a45f2 100644 --- a/test/std/containers/associative/multiset/multiset.cons/move_alloc.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.cons/move_alloc.pass.cpp @@ -163,7 +163,7 @@ int main() M m1(I(a1), I(a1+num), C(), A()); assert(Counter_base::gConstructed == 2*num); - + M m2(m1); assert(m2 == m1); assert(Counter_base::gConstructed == 3*num); @@ -181,7 +181,7 @@ int main() } assert(Counter_base::gConstructed == 2*num); } - assert(Counter_base::gConstructed == 0); + assert(Counter_base::gConstructed == 0); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/std/containers/associative/multiset/multiset.cons/move_assign.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/move_assign.pass.cpp index ca1ba971f5a46..b0ec4f39451c0 100644 --- a/test/std/containers/associative/multiset/multiset.cons/move_assign.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.cons/move_assign.pass.cpp @@ -142,7 +142,7 @@ int main() assert(m1.empty()); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef MoveOnly V; typedef test_compare<std::less<MoveOnly> > C; diff --git a/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.pass.cpp index 211bb36e7e953..57388637e97a5 100644 --- a/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.cons/move_assign_noexcept.pass.cpp @@ -17,6 +17,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <set> #include <cassert> @@ -28,11 +30,11 @@ struct some_comp { typedef T value_type; some_comp& operator=(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; int main() { -#if __has_feature(cxx_noexcept) { typedef std::multiset<MoveOnly> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); @@ -49,5 +51,4 @@ int main() typedef std::multiset<MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/multiset/multiset.cons/move_noexcept.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/move_noexcept.pass.cpp index 31a34cbde3061..e3a7beedb92bf 100644 --- a/test/std/containers/associative/multiset/multiset.cons/move_noexcept.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.cons/move_noexcept.pass.cpp @@ -15,6 +15,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <set> #include <cassert> @@ -26,11 +28,11 @@ struct some_comp { typedef T value_type; some_comp(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; int main() { -#if __has_feature(cxx_noexcept) { typedef std::multiset<MoveOnly> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); @@ -47,5 +49,4 @@ int main() typedef std::multiset<MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/multiset/multiset.special/member_swap.pass.cpp b/test/std/containers/associative/multiset/multiset.special/member_swap.pass.cpp index 7745ddab78c36..7036138f8439f 100644 --- a/test/std/containers/associative/multiset/multiset.special/member_swap.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.special/member_swap.pass.cpp @@ -96,7 +96,7 @@ int main() assert(m2 == m1_save); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; typedef std::multiset<int, std::less<int>, min_allocator<int>> M; diff --git a/test/std/containers/associative/multiset/multiset.special/non_member_swap.pass.cpp b/test/std/containers/associative/multiset/multiset.special/non_member_swap.pass.cpp index f456de7f62438..91ec4ce93a27f 100644 --- a/test/std/containers/associative/multiset/multiset.special/non_member_swap.pass.cpp +++ b/test/std/containers/associative/multiset/multiset.special/non_member_swap.pass.cpp @@ -21,6 +21,7 @@ int main() { typedef int V; + { typedef std::multiset<int> M; { M m1; @@ -94,6 +95,7 @@ int main() assert(m1 == m2_save); assert(m2 == m1_save); } + } { typedef test_allocator<V> A; typedef test_compare<std::less<int> > C; 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 8e2c67c9b5ec6..87639943a0b5a 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <set> // void swap(multiset& c) @@ -15,13 +17,14 @@ // // In C++17, the standard says that swap shall have: // noexcept(allocator_traits<Allocator>::is_always_equal::value && -// noexcept(swap(declval<Compare&>(), declval<Compare&>()))); +// noexcept(swap(declval<Compare&>(), declval<Compare&>()))); // This tests a conforming extension #include <set> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -29,23 +32,20 @@ template <class T> struct some_comp { typedef T value_type; - + some_comp() {} some_comp(const some_comp&) {} - void deallocate(void*, unsigned) {} - - typedef std::true_type propagate_on_container_swap; + bool operator()(const T&, const T&) const { return false; } }; 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; + bool operator()(const T&, const T&) const { return false; } }; #if TEST_STD_VER >= 14 @@ -57,7 +57,7 @@ template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -69,7 +69,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -82,7 +82,7 @@ template <class T> struct some_alloc3 { typedef T value_type; - + some_alloc3() {} some_alloc3(const some_alloc3&); void deallocate(void*, unsigned) {} @@ -93,7 +93,6 @@ struct some_alloc3 int main() { -#if __has_feature(cxx_noexcept) { typedef std::multiset<MoveOnly> C; C c1, c2; @@ -143,6 +142,4 @@ int main() static_assert( noexcept(swap(c1, c2)), ""); } #endif - -#endif } diff --git a/test/std/containers/associative/multiset/size.pass.cpp b/test/std/containers/associative/multiset/size.pass.cpp index 68099b566dfd4..d11975b79935a 100644 --- a/test/std/containers/associative/multiset/size.pass.cpp +++ b/test/std/containers/associative/multiset/size.pass.cpp @@ -37,7 +37,7 @@ int main() m.erase(m.begin()); assert(m.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> M; M m; diff --git a/test/std/containers/associative/multiset/types.pass.cpp b/test/std/containers/associative/multiset/types.pass.cpp index e1e3ad9100c3c..b37b9b328f8fd 100644 --- a/test/std/containers/associative/multiset/types.pass.cpp +++ b/test/std/containers/associative/multiset/types.pass.cpp @@ -50,7 +50,7 @@ int main() static_assert((std::is_same<C::size_type, std::size_t>::value), ""); static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), ""); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::multiset<int, std::less<int>, min_allocator<int>> C; static_assert((std::is_same<C::key_type, int>::value), ""); diff --git a/test/std/containers/associative/multiset/upper_bound.pass.cpp b/test/std/containers/associative/multiset/upper_bound.pass.cpp index 7ad3d6ced3d62..7bb0c3cb41f3d 100644 --- a/test/std/containers/associative/multiset/upper_bound.pass.cpp +++ b/test/std/containers/associative/multiset/upper_bound.pass.cpp @@ -86,7 +86,7 @@ int main() assert(r == next(m.begin(), 9)); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; typedef std::multiset<int, std::less<int>, min_allocator<int>> M; diff --git a/test/std/containers/associative/set/clear.pass.cpp b/test/std/containers/associative/set/clear.pass.cpp index 4439ad3b1e4ea..7a5bf4b14a71a 100644 --- a/test/std/containers/associative/set/clear.pass.cpp +++ b/test/std/containers/associative/set/clear.pass.cpp @@ -39,7 +39,7 @@ int main() m.clear(); assert(m.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> M; typedef int V; diff --git a/test/std/containers/associative/set/count.pass.cpp b/test/std/containers/associative/set/count.pass.cpp index 32fe0b8bcee9c..ddc913910b5e8 100644 --- a/test/std/containers/associative/set/count.pass.cpp +++ b/test/std/containers/associative/set/count.pass.cpp @@ -56,7 +56,7 @@ int main() r = m.count(4); assert(r == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; typedef std::set<int, std::less<int>, min_allocator<int>> M; diff --git a/test/std/containers/associative/set/emplace.pass.cpp b/test/std/containers/associative/set/emplace.pass.cpp index 5ebab4d24b92d..47ef455a996bf 100644 --- a/test/std/containers/associative/set/emplace.pass.cpp +++ b/test/std/containers/associative/set/emplace.pass.cpp @@ -74,7 +74,7 @@ int main() assert(m.size() == 1); assert(*r.first == 2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> M; typedef std::pair<M::iterator, bool> R; diff --git a/test/std/containers/associative/set/emplace_hint.pass.cpp b/test/std/containers/associative/set/emplace_hint.pass.cpp index 5fdeb4ffef3aa..036f4d6dfb68c 100644 --- a/test/std/containers/associative/set/emplace_hint.pass.cpp +++ b/test/std/containers/associative/set/emplace_hint.pass.cpp @@ -68,7 +68,7 @@ int main() assert(m.size() == 1); assert(*r == 2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> M; typedef M::iterator R; diff --git a/test/std/containers/associative/set/empty.pass.cpp b/test/std/containers/associative/set/empty.pass.cpp index eb1080263f4fe..1eaa8fc905378 100644 --- a/test/std/containers/associative/set/empty.pass.cpp +++ b/test/std/containers/associative/set/empty.pass.cpp @@ -29,7 +29,7 @@ int main() m.clear(); assert(m.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> M; M m; diff --git a/test/std/containers/associative/set/equal_range.pass.cpp b/test/std/containers/associative/set/equal_range.pass.cpp index 8a180ef492482..ed41f691a4599 100644 --- a/test/std/containers/associative/set/equal_range.pass.cpp +++ b/test/std/containers/associative/set/equal_range.pass.cpp @@ -158,7 +158,7 @@ int main() assert(r.second == next(m.begin(), 8)); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; typedef std::set<int, std::less<int>, min_allocator<int>> M; diff --git a/test/std/containers/associative/set/erase_iter.pass.cpp b/test/std/containers/associative/set/erase_iter.pass.cpp index 36828be86f284..85be1f5b9c212 100644 --- a/test/std/containers/associative/set/erase_iter.pass.cpp +++ b/test/std/containers/associative/set/erase_iter.pass.cpp @@ -106,7 +106,7 @@ int main() assert(i == m.begin()); assert(i == m.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> M; typedef int V; @@ -186,7 +186,7 @@ int main() assert(i == m.end()); } #endif -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 { // This is LWG #2059 typedef TemplateConstructor T; diff --git a/test/std/containers/associative/set/erase_iter_iter.pass.cpp b/test/std/containers/associative/set/erase_iter_iter.pass.cpp index 4799503166550..775e6cea06fab 100644 --- a/test/std/containers/associative/set/erase_iter_iter.pass.cpp +++ b/test/std/containers/associative/set/erase_iter_iter.pass.cpp @@ -78,7 +78,7 @@ int main() assert(m.size() == 0); assert(i == m.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> M; typedef int V; diff --git a/test/std/containers/associative/set/erase_key.pass.cpp b/test/std/containers/associative/set/erase_key.pass.cpp index 9d92bd70d7001..6fc15d9ccfd47 100644 --- a/test/std/containers/associative/set/erase_key.pass.cpp +++ b/test/std/containers/associative/set/erase_key.pass.cpp @@ -109,7 +109,7 @@ int main() assert(m.size() == 0); assert(i == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> M; typedef int V; diff --git a/test/std/containers/associative/set/find.pass.cpp b/test/std/containers/associative/set/find.pass.cpp index d08d2fb1e2450..60f16fcd65d4c 100644 --- a/test/std/containers/associative/set/find.pass.cpp +++ b/test/std/containers/associative/set/find.pass.cpp @@ -92,7 +92,7 @@ int main() assert(r == next(m.begin(), 8)); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; typedef std::set<int, std::less<int>, min_allocator<int>> M; diff --git a/test/std/containers/associative/set/incomplete_type.pass.cpp b/test/std/containers/associative/set/incomplete_type.pass.cpp new file mode 100644 index 0000000000000..d3a1d6638d7ec --- /dev/null +++ b/test/std/containers/associative/set/incomplete_type.pass.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. +// +//===----------------------------------------------------------------------===// + +// <set> + +// Check that std::set and it's iterators can be instantiated with an incomplete +// type. + +#include <set> + +struct A { + typedef std::set<A> Set; + int data; + Set m; + Set::iterator it; + Set::const_iterator cit; +}; + +inline bool operator==(A const& L, A const& R) { return &L == &R; } +inline bool operator<(A const& L, A const& R) { return L.data < R.data; } +int main() { + A a; +} diff --git a/test/std/containers/associative/set/insert_and_emplace_allocator_requirements.pass.cpp b/test/std/containers/associative/set/insert_and_emplace_allocator_requirements.pass.cpp new file mode 100644 index 0000000000000..b14340b1d763f --- /dev/null +++ b/test/std/containers/associative/set/insert_and_emplace_allocator_requirements.pass.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. +// +//===----------------------------------------------------------------------===// + +// <set> + +// class set + +// insert(...) +// emplace(...) +// emplace_hint(...) + +// UNSUPPORTED: c++98, c++03 + +#include <set> +#include "container_test_types.h" +#include "../../set_allocator_requirement_test_templates.h" + +int main() +{ + testSetInsert<TCT::set<> >(); + testSetEmplace<TCT::set<> >(); + testSetEmplaceHint<TCT::set<> >(); +} diff --git a/test/std/containers/associative/set/insert_cv.pass.cpp b/test/std/containers/associative/set/insert_cv.pass.cpp index 18d5c2e033953..8d5290a97af93 100644 --- a/test/std/containers/associative/set/insert_cv.pass.cpp +++ b/test/std/containers/associative/set/insert_cv.pass.cpp @@ -48,7 +48,7 @@ int main() assert(m.size() == 3); assert(*r.first == 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> M; typedef std::pair<M::iterator, bool> R; diff --git a/test/std/containers/associative/set/insert_initializer_list.pass.cpp b/test/std/containers/associative/set/insert_initializer_list.pass.cpp index fc6d612b2ebed..60a6e754e17ea 100644 --- a/test/std/containers/associative/set/insert_initializer_list.pass.cpp +++ b/test/std/containers/associative/set/insert_initializer_list.pass.cpp @@ -38,7 +38,7 @@ int main() assert(*++i == V(8)); assert(*++i == V(10)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> C; typedef C::value_type V; diff --git a/test/std/containers/associative/set/insert_iter_cv.pass.cpp b/test/std/containers/associative/set/insert_iter_cv.pass.cpp index 718e720559f46..12d6402a87c23 100644 --- a/test/std/containers/associative/set/insert_iter_cv.pass.cpp +++ b/test/std/containers/associative/set/insert_iter_cv.pass.cpp @@ -44,7 +44,7 @@ int main() assert(m.size() == 3); assert(*r == 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> M; typedef M::iterator R; diff --git a/test/std/containers/associative/set/insert_iter_iter.pass.cpp b/test/std/containers/associative/set/insert_iter_iter.pass.cpp index ff729a0e7b9b0..46edd0db04682 100644 --- a/test/std/containers/associative/set/insert_iter_iter.pass.cpp +++ b/test/std/containers/associative/set/insert_iter_iter.pass.cpp @@ -45,7 +45,7 @@ int main() assert(*next(m.begin()) == 2); assert(*next(m.begin(), 2) == 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> M; typedef int V; diff --git a/test/std/containers/associative/set/insert_iter_rv.pass.cpp b/test/std/containers/associative/set/insert_iter_rv.pass.cpp index 296ead84914d3..be827d644d264 100644 --- a/test/std/containers/associative/set/insert_iter_rv.pass.cpp +++ b/test/std/containers/associative/set/insert_iter_rv.pass.cpp @@ -46,7 +46,7 @@ int main() assert(m.size() == 3); assert(*r == 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<MoveOnly, std::less<MoveOnly>, min_allocator<MoveOnly>> M; typedef M::iterator R; diff --git a/test/std/containers/associative/set/insert_rv.pass.cpp b/test/std/containers/associative/set/insert_rv.pass.cpp index 32cede1549569..e528ef347b886 100644 --- a/test/std/containers/associative/set/insert_rv.pass.cpp +++ b/test/std/containers/associative/set/insert_rv.pass.cpp @@ -50,7 +50,7 @@ int main() assert(m.size() == 3); assert(*r.first == 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<MoveOnly, std::less<MoveOnly>, min_allocator<MoveOnly>> M; typedef std::pair<M::iterator, bool> R; diff --git a/test/std/containers/associative/set/iterator.pass.cpp b/test/std/containers/associative/set/iterator.pass.cpp index ecd950f03a009..c318341ce8599 100644 --- a/test/std/containers/associative/set/iterator.pass.cpp +++ b/test/std/containers/associative/set/iterator.pass.cpp @@ -111,7 +111,7 @@ int main() for (int j = 1; j <= m.size(); ++j, ++i) assert(*i == j); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; V ar[] = diff --git a/test/std/containers/associative/set/lower_bound.pass.cpp b/test/std/containers/associative/set/lower_bound.pass.cpp index df202f31a4c30..55d49a097ef6c 100644 --- a/test/std/containers/associative/set/lower_bound.pass.cpp +++ b/test/std/containers/associative/set/lower_bound.pass.cpp @@ -124,7 +124,7 @@ int main() assert(r == next(m.begin(), 8)); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; typedef std::set<int, std::less<int>, min_allocator<int>> M; @@ -281,7 +281,7 @@ int main() r = m.lower_bound(20); assert(r == next(m.begin(), 8)); } - + { typedef PrivateConstructor V; typedef std::set<V, std::less<>> M; diff --git a/test/std/containers/associative/set/max_size.pass.cpp b/test/std/containers/associative/set/max_size.pass.cpp index cde4397c71788..9df6a4157e110 100644 --- a/test/std/containers/associative/set/max_size.pass.cpp +++ b/test/std/containers/associative/set/max_size.pass.cpp @@ -25,7 +25,7 @@ int main() M m; assert(m.max_size() != 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> M; M m; diff --git a/test/std/containers/associative/set/set.cons/assign_initializer_list.pass.cpp b/test/std/containers/associative/set/set.cons/assign_initializer_list.pass.cpp index 892ae5a0a799b..70e174a596121 100644 --- a/test/std/containers/associative/set/set.cons/assign_initializer_list.pass.cpp +++ b/test/std/containers/associative/set/set.cons/assign_initializer_list.pass.cpp @@ -36,7 +36,7 @@ int main() assert(*++i == V(5)); assert(*++i == V(6)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> C; typedef C::value_type V; diff --git a/test/std/containers/associative/set/set.cons/compare_copy_constructible.fail.cpp b/test/std/containers/associative/set/set.cons/compare_copy_constructible.fail.cpp new file mode 100644 index 0000000000000..dcf23effc4436 --- /dev/null +++ b/test/std/containers/associative/set/set.cons/compare_copy_constructible.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. +// +//===----------------------------------------------------------------------===// + +// <set> + +// Check that std::set fails to instantiate if the comparison predicate is +// not copy-constructible. This is LWG issue 2436 + +#include <set> + +template <class T> +struct Comp { + bool operator () (const T& lhs, const T& rhs) const { return lhs < rhs; } + + Comp () {} +private: + Comp (const Comp &); // declared but not defined + }; + + +int main() { + std::set<int, Comp<int> > m; +} diff --git a/test/std/containers/associative/set/set.cons/default.pass.cpp b/test/std/containers/associative/set/set.cons/default.pass.cpp index 746a2d1730716..4c924ca70e966 100644 --- a/test/std/containers/associative/set/set.cons/default.pass.cpp +++ b/test/std/containers/associative/set/set.cons/default.pass.cpp @@ -25,7 +25,7 @@ int main() assert(m.empty()); assert(m.begin() == m.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::set<int, std::less<int>, min_allocator<int>> m; assert(m.empty()); diff --git a/test/std/containers/associative/set/set.cons/default_noexcept.pass.cpp b/test/std/containers/associative/set/set.cons/default_noexcept.pass.cpp index 2156169acbc45..6293c24a43d3f 100644 --- a/test/std/containers/associative/set/set.cons/default_noexcept.pass.cpp +++ b/test/std/containers/associative/set/set.cons/default_noexcept.pass.cpp @@ -17,9 +17,12 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <set> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -28,18 +31,18 @@ struct some_comp { typedef T value_type; some_comp(); + bool operator()(const T&, const T&) const { return false; } }; int main() { -#if __has_feature(cxx_noexcept) { typedef std::set<MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::set<MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::set<MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C; @@ -49,5 +52,4 @@ int main() typedef std::set<MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/set/set.cons/dtor_noexcept.pass.cpp b/test/std/containers/associative/set/set.cons/dtor_noexcept.pass.cpp index b554d828d4864..60d1d42c3d9cf 100644 --- a/test/std/containers/associative/set/set.cons/dtor_noexcept.pass.cpp +++ b/test/std/containers/associative/set/set.cons/dtor_noexcept.pass.cpp @@ -11,26 +11,24 @@ // ~set() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <set> #include <cassert> #include "MoveOnly.h" #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_comp { typedef T value_type; ~some_comp() noexcept(false); + bool operator()(const T&, const T&) const { return false; } }; -#endif - int main() { -#if __has_feature(cxx_noexcept) { typedef std::set<MoveOnly> C; static_assert(std::is_nothrow_destructible<C>::value, ""); @@ -47,5 +45,4 @@ int main() typedef std::set<MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/set/set.cons/initializer_list.pass.cpp b/test/std/containers/associative/set/set.cons/initializer_list.pass.cpp index 2ad538e143f8f..5bb5460ddc0d5 100644 --- a/test/std/containers/associative/set/set.cons/initializer_list.pass.cpp +++ b/test/std/containers/associative/set/set.cons/initializer_list.pass.cpp @@ -35,7 +35,7 @@ int main() assert(*++i == V(5)); assert(*++i == V(6)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> C; typedef C::value_type V; diff --git a/test/std/containers/associative/set/set.cons/iter_iter.pass.cpp b/test/std/containers/associative/set/set.cons/iter_iter.pass.cpp index 7ca7fe14d6c40..db765bd9e3376 100644 --- a/test/std/containers/associative/set/set.cons/iter_iter.pass.cpp +++ b/test/std/containers/associative/set/set.cons/iter_iter.pass.cpp @@ -44,7 +44,7 @@ int main() assert(*next(m.begin()) == 2); assert(*next(m.begin(), 2) == 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; V ar[] = diff --git a/test/std/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp b/test/std/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp index 5ccb6e5cbcd75..077a749caacac 100644 --- a/test/std/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp +++ b/test/std/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp @@ -28,6 +28,7 @@ int main() { + { typedef int V; V ar[] = { @@ -53,6 +54,7 @@ int main() assert(*m.begin() == 1); assert(*next(m.begin()) == 2); assert(*next(m.begin(), 2) == 3); + } #if _LIBCPP_STD_VER > 11 { typedef int V; diff --git a/test/std/containers/associative/set/set.cons/move.pass.cpp b/test/std/containers/associative/set/set.cons/move.pass.cpp index 4026ec70c3e1c..c836d4550203e 100644 --- a/test/std/containers/associative/set/set.cons/move.pass.cpp +++ b/test/std/containers/associative/set/set.cons/move.pass.cpp @@ -70,7 +70,7 @@ int main() assert(mo.size() == 0); assert(distance(mo.begin(), mo.end()) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; V ar[] = diff --git a/test/std/containers/associative/set/set.cons/move_alloc.pass.cpp b/test/std/containers/associative/set/set.cons/move_alloc.pass.cpp index 799f0e402d63b..ba2adf5bb520f 100644 --- a/test/std/containers/associative/set/set.cons/move_alloc.pass.cpp +++ b/test/std/containers/associative/set/set.cons/move_alloc.pass.cpp @@ -163,7 +163,7 @@ int main() M m1(I(a1), I(a1+num), C(), A()); assert(Counter_base::gConstructed == 3+num); - + M m2(m1); assert(m2 == m1); assert(Counter_base::gConstructed == 6+num); @@ -181,7 +181,7 @@ int main() } assert(Counter_base::gConstructed == 3+num); } - assert(Counter_base::gConstructed == 0); + assert(Counter_base::gConstructed == 0); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES diff --git a/test/std/containers/associative/set/set.cons/move_assign.pass.cpp b/test/std/containers/associative/set/set.cons/move_assign.pass.cpp index ed0e77ae17966..07cb4153fa4a1 100644 --- a/test/std/containers/associative/set/set.cons/move_assign.pass.cpp +++ b/test/std/containers/associative/set/set.cons/move_assign.pass.cpp @@ -141,7 +141,7 @@ int main() assert(m3.key_comp() == C(5)); assert(m1.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef MoveOnly V; typedef test_compare<std::less<MoveOnly> > C; diff --git a/test/std/containers/associative/set/set.cons/move_assign_noexcept.pass.cpp b/test/std/containers/associative/set/set.cons/move_assign_noexcept.pass.cpp index 3999c55e9e7c0..3f7d783b76300 100644 --- a/test/std/containers/associative/set/set.cons/move_assign_noexcept.pass.cpp +++ b/test/std/containers/associative/set/set.cons/move_assign_noexcept.pass.cpp @@ -17,6 +17,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <set> #include <cassert> @@ -28,11 +30,11 @@ struct some_comp { typedef T value_type; some_comp& operator=(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; int main() { -#if __has_feature(cxx_noexcept) { typedef std::set<MoveOnly> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); @@ -49,5 +51,4 @@ int main() typedef std::set<MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/set/set.cons/move_noexcept.pass.cpp b/test/std/containers/associative/set/set.cons/move_noexcept.pass.cpp index 5ccfed4675c54..72c2f7530a9e5 100644 --- a/test/std/containers/associative/set/set.cons/move_noexcept.pass.cpp +++ b/test/std/containers/associative/set/set.cons/move_noexcept.pass.cpp @@ -15,6 +15,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <set> #include <cassert> @@ -26,11 +28,11 @@ struct some_comp { typedef T value_type; some_comp(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; int main() { -#if __has_feature(cxx_noexcept) { typedef std::set<MoveOnly> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); @@ -47,5 +49,4 @@ int main() typedef std::set<MoveOnly, some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/associative/set/set.special/member_swap.pass.cpp b/test/std/containers/associative/set/set.special/member_swap.pass.cpp index b5129f880afdc..486d5f44291b0 100644 --- a/test/std/containers/associative/set/set.special/member_swap.pass.cpp +++ b/test/std/containers/associative/set/set.special/member_swap.pass.cpp @@ -96,7 +96,7 @@ int main() assert(m2 == m1_save); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; typedef std::set<int, std::less<int>, min_allocator<int>> M; diff --git a/test/std/containers/associative/set/set.special/non_member_swap.pass.cpp b/test/std/containers/associative/set/set.special/non_member_swap.pass.cpp index 0ac14464c70f3..3d2d7d7d3bbc1 100644 --- a/test/std/containers/associative/set/set.special/non_member_swap.pass.cpp +++ b/test/std/containers/associative/set/set.special/non_member_swap.pass.cpp @@ -21,6 +21,7 @@ int main() { typedef int V; + { typedef std::set<int> M; { M m1; @@ -94,6 +95,7 @@ int main() assert(m1 == m2_save); assert(m2 == m1_save); } + } { typedef test_allocator<V> A; typedef test_compare<std::less<int> > C; 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 3ec6976127545..0eb7d871b8b48 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <set> // void swap(set& c) @@ -15,13 +17,14 @@ // // In C++17, the standard says that swap shall have: // noexcept(allocator_traits<Allocator>::is_always_equal::value && -// noexcept(swap(declval<Compare&>(), declval<Compare&>()))); +// noexcept(swap(declval<Compare&>(), declval<Compare&>()))); // This tests a conforming extension #include <set> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -29,23 +32,20 @@ template <class T> struct some_comp { typedef T value_type; - + some_comp() {} some_comp(const some_comp&) {} - void deallocate(void*, unsigned) {} - - typedef std::true_type propagate_on_container_swap; + bool operator()(const T&, const T&) const { return false; } }; 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; + bool operator()(const T&, const T&) const { return false; } }; #if TEST_STD_VER >= 14 @@ -57,7 +57,7 @@ template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -69,7 +69,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -82,7 +82,7 @@ template <class T> struct some_alloc3 { typedef T value_type; - + some_alloc3() {} some_alloc3(const some_alloc3&); void deallocate(void*, unsigned) {} @@ -93,7 +93,6 @@ struct some_alloc3 int main() { -#if __has_feature(cxx_noexcept) { typedef std::set<MoveOnly> C; C c1, c2; @@ -144,5 +143,4 @@ int main() } #endif -#endif } diff --git a/test/std/containers/associative/set/size.pass.cpp b/test/std/containers/associative/set/size.pass.cpp index e786547355081..853aeca743660 100644 --- a/test/std/containers/associative/set/size.pass.cpp +++ b/test/std/containers/associative/set/size.pass.cpp @@ -37,7 +37,7 @@ int main() m.erase(m.begin()); assert(m.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> M; M m; diff --git a/test/std/containers/associative/set/types.pass.cpp b/test/std/containers/associative/set/types.pass.cpp index 3362c42aee429..f1ce8a7c975c5 100644 --- a/test/std/containers/associative/set/types.pass.cpp +++ b/test/std/containers/associative/set/types.pass.cpp @@ -50,7 +50,7 @@ int main() static_assert((std::is_same<C::size_type, std::size_t>::value), ""); static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), ""); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::set<int, std::less<int>, min_allocator<int>> C; static_assert((std::is_same<C::key_type, int>::value), ""); diff --git a/test/std/containers/associative/set/upper_bound.pass.cpp b/test/std/containers/associative/set/upper_bound.pass.cpp index 10a28f064698f..9d4ab2805d0db 100644 --- a/test/std/containers/associative/set/upper_bound.pass.cpp +++ b/test/std/containers/associative/set/upper_bound.pass.cpp @@ -124,7 +124,7 @@ int main() assert(r == next(m.begin(), 8)); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int V; typedef std::set<int, std::less<int>, min_allocator<int>> M; @@ -281,7 +281,7 @@ int main() r = m.upper_bound(20); assert(r == next(m.begin(), 8)); } - + { typedef PrivateConstructor V; typedef std::set<V, std::less<>> M; diff --git a/test/std/containers/container.adaptors/priority.queue/priqueue.cons.alloc/ctor_comp_cont_alloc.pass.cpp b/test/std/containers/container.adaptors/priority.queue/priqueue.cons.alloc/ctor_comp_cont_alloc.pass.cpp index 66ca614126f4d..dc5cca3c55684 100644 --- a/test/std/containers/container.adaptors/priority.queue/priqueue.cons.alloc/ctor_comp_cont_alloc.pass.cpp +++ b/test/std/containers/container.adaptors/priority.queue/priqueue.cons.alloc/ctor_comp_cont_alloc.pass.cpp @@ -16,6 +16,7 @@ #include <queue> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" template <class C> @@ -41,11 +42,11 @@ struct test : base(comp, a) {} test(const value_compare& comp, const container_type& c, const test_allocator<int>& a) : base(comp, c, a) {} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if TEST_STD_VER >= 11 // testing rvalue constructor test(const value_compare& comp, container_type&& c, const test_allocator<int>& a) : base(comp, std::move(c), a) {} test(test&& q, const test_allocator<int>& a) : base(std::move(q), a) {} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif test_allocator<int> get_allocator() {return c.get_allocator();} using base::c; diff --git a/test/std/containers/container.adaptors/priority.queue/priqueue.cons.alloc/ctor_comp_rcont_alloc.pass.cpp b/test/std/containers/container.adaptors/priority.queue/priqueue.cons.alloc/ctor_comp_rcont_alloc.pass.cpp index 643b0c625abbb..a27a6e205123a 100644 --- a/test/std/containers/container.adaptors/priority.queue/priqueue.cons.alloc/ctor_comp_rcont_alloc.pass.cpp +++ b/test/std/containers/container.adaptors/priority.queue/priqueue.cons.alloc/ctor_comp_rcont_alloc.pass.cpp @@ -16,6 +16,7 @@ #include <queue> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" template <class C> @@ -41,11 +42,11 @@ struct test : base(comp, a) {} test(const value_compare& comp, const container_type& c, const test_allocator<int>& a) : base(comp, c, a) {} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if TEST_STD_VER >= 11 // testing rvalue ctor test(const value_compare& comp, container_type&& c, const test_allocator<int>& a) : base(comp, std::move(c), a) {} test(test&& q, const test_allocator<int>& a) : base(std::move(q), a) {} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif test_allocator<int> get_allocator() {return c.get_allocator();} using base::c; diff --git a/test/std/containers/container.adaptors/priority.queue/priqueue.cons/default_noexcept.pass.cpp b/test/std/containers/container.adaptors/priority.queue/priqueue.cons/default_noexcept.pass.cpp index cdfa58b585544..c79feb93eb6ca 100644 --- a/test/std/containers/container.adaptors/priority.queue/priqueue.cons/default_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/priority.queue/priqueue.cons/default_noexcept.pass.cpp @@ -15,17 +15,18 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <queue> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" int main() { -#if __has_feature(cxx_noexcept) { typedef std::priority_queue<MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/container.adaptors/priority.queue/priqueue.cons/dtor_noexcept.pass.cpp b/test/std/containers/container.adaptors/priority.queue/priqueue.cons/dtor_noexcept.pass.cpp index e3d071d9aad09..3cedefef2c871 100644 --- a/test/std/containers/container.adaptors/priority.queue/priqueue.cons/dtor_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/priority.queue/priqueue.cons/dtor_noexcept.pass.cpp @@ -11,6 +11,8 @@ // ~priority_queue() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <queue> #include <cassert> @@ -18,10 +20,8 @@ int main() { -#if __has_feature(cxx_noexcept) { typedef std::priority_queue<MoveOnly> C; static_assert(std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/container.adaptors/priority.queue/priqueue.cons/move_assign_noexcept.pass.cpp b/test/std/containers/container.adaptors/priority.queue/priqueue.cons/move_assign_noexcept.pass.cpp index 590d82fe6da48..f14c3ae7ce438 100644 --- a/test/std/containers/container.adaptors/priority.queue/priqueue.cons/move_assign_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/priority.queue/priqueue.cons/move_assign_noexcept.pass.cpp @@ -15,6 +15,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <queue> #include <cassert> @@ -22,10 +24,8 @@ int main() { -#if __has_feature(cxx_noexcept) { typedef std::priority_queue<MoveOnly> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/container.adaptors/priority.queue/priqueue.cons/move_noexcept.pass.cpp b/test/std/containers/container.adaptors/priority.queue/priqueue.cons/move_noexcept.pass.cpp index 05ff253d31b42..0218992670f25 100644 --- a/test/std/containers/container.adaptors/priority.queue/priqueue.cons/move_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/priority.queue/priqueue.cons/move_noexcept.pass.cpp @@ -15,6 +15,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <queue> #include <cassert> @@ -22,10 +24,8 @@ int main() { -#if __has_feature(cxx_noexcept) { typedef std::priority_queue<MoveOnly> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/container.adaptors/priority.queue/priqueue.special/swap_noexcept.pass.cpp b/test/std/containers/container.adaptors/priority.queue/priqueue.special/swap_noexcept.pass.cpp index 4d2b441c60ee1..bfff607590fec 100644 --- a/test/std/containers/container.adaptors/priority.queue/priqueue.special/swap_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/priority.queue/priqueue.special/swap_noexcept.pass.cpp @@ -15,6 +15,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <queue> #include <cassert> @@ -22,11 +24,9 @@ int main() { -#if __has_feature(cxx_noexcept) { typedef std::priority_queue<MoveOnly> C; C c1, c2; static_assert(noexcept(swap(c1, c2)), ""); } -#endif } diff --git a/test/std/containers/container.adaptors/priority.queue/types.fail.cpp b/test/std/containers/container.adaptors/priority.queue/types.fail.cpp new file mode 100644 index 0000000000000..0d3025e1739aa --- /dev/null +++ b/test/std/containers/container.adaptors/priority.queue/types.fail.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <queue> + +// template <class T, class Container = vector<T>, +// class Compare = less<typename Container::value_type>> +// class priority_queue +// { +// public: +// typedef Container container_type; +// typedef typename container_type::value_type value_type; +// typedef typename container_type::reference reference; +// typedef typename container_type::const_reference const_reference; +// typedef typename container_type::size_type size_type; +// +// protected: +// container_type c; +// Compare comp; + +#include <queue> +#include <cassert> +#include <type_traits> + +int main() +{ +// LWG#2566 says that the first template param must match the second one's value type + std::priority_queue<double, std::deque<int>> t; +} diff --git a/test/std/containers/container.adaptors/priority.queue/types.pass.cpp b/test/std/containers/container.adaptors/priority.queue/types.pass.cpp index ade20d47d4e36..6bc476a3ce055 100644 --- a/test/std/containers/container.adaptors/priority.queue/types.pass.cpp +++ b/test/std/containers/container.adaptors/priority.queue/types.pass.cpp @@ -15,6 +15,7 @@ // { // public: // typedef Container container_type; +// typedef Compare value_compare; // LWG#2684 // typedef typename container_type::value_type value_type; // typedef typename container_type::reference reference; // typedef typename container_type::const_reference const_reference; @@ -26,7 +27,11 @@ #include <queue> #include <cassert> +#include <deque> +#include <functional> +#include <memory> #include <type_traits> +#include <vector> struct test : private std::priority_queue<int> @@ -48,13 +53,16 @@ struct C int main() { - static_assert((std::is_same<std::priority_queue<int>::container_type, std::vector<int> >::value), ""); - static_assert((std::is_same<std::priority_queue<double, std::deque<int> >::container_type, std::deque<int> >::value), ""); - static_assert((std::is_same<std::priority_queue<double, std::deque<int> >::value_type, int>::value), ""); - static_assert((std::is_same<std::priority_queue<int>::reference, std::vector<int>::reference>::value), ""); - static_assert((std::is_same<std::priority_queue<int>::const_reference, std::vector<int>::const_reference>::value), ""); - static_assert((std::is_same<std::priority_queue<int>::size_type, std::vector<int>::size_type>::value), ""); - static_assert((std::uses_allocator<std::priority_queue<int>, std::allocator<int> >::value), ""); + static_assert(( std::is_same<std::priority_queue<int>::container_type, std::vector<int> >::value), ""); + static_assert(( std::is_same<std::priority_queue<int, std::deque<int> >::container_type, std::deque<int> >::value), ""); + static_assert(( std::is_same<std::priority_queue<int, std::deque<int> >::value_type, int>::value), ""); + static_assert(( std::is_same<std::priority_queue<int>::reference, std::vector<int>::reference>::value), ""); + static_assert(( std::is_same<std::priority_queue<int>::const_reference, std::vector<int>::const_reference>::value), ""); + static_assert(( std::is_same<std::priority_queue<int>::size_type, std::vector<int>::size_type>::value), ""); + static_assert(( std::is_same<std::priority_queue<int>::value_compare, std::less<int> >::value), ""); + static_assert(( std::is_same<std::priority_queue<int, std::deque<int> >::value_compare, std::less<int> >::value), ""); + static_assert(( std::is_same<std::priority_queue<int, std::deque<int>, std::greater<int> >::value_compare, std::greater<int> >::value), ""); + static_assert(( std::uses_allocator<std::priority_queue<int>, std::allocator<int> >::value), ""); static_assert((!std::uses_allocator<std::priority_queue<int, C>, std::allocator<int> >::value), ""); test t; } diff --git a/test/std/containers/container.adaptors/queue/queue.cons/default_noexcept.pass.cpp b/test/std/containers/container.adaptors/queue/queue.cons/default_noexcept.pass.cpp index 392853432669b..43045893fe075 100644 --- a/test/std/containers/container.adaptors/queue/queue.cons/default_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/queue/queue.cons/default_noexcept.pass.cpp @@ -14,17 +14,18 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <queue> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" int main() { -#if __has_feature(cxx_noexcept) { typedef std::queue<MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/container.adaptors/queue/queue.cons/dtor_noexcept.pass.cpp b/test/std/containers/container.adaptors/queue/queue.cons/dtor_noexcept.pass.cpp index d9b8f731f28a7..2a6783287b09f 100644 --- a/test/std/containers/container.adaptors/queue/queue.cons/dtor_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/queue/queue.cons/dtor_noexcept.pass.cpp @@ -11,6 +11,8 @@ // ~queue() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <queue> #include <cassert> @@ -18,10 +20,8 @@ int main() { -#if __has_feature(cxx_noexcept) { typedef std::queue<MoveOnly> C; static_assert(std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/container.adaptors/queue/queue.cons/move_assign_noexcept.pass.cpp b/test/std/containers/container.adaptors/queue/queue.cons/move_assign_noexcept.pass.cpp index beef0f12ffb73..42e1c458c9daf 100644 --- a/test/std/containers/container.adaptors/queue/queue.cons/move_assign_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/queue/queue.cons/move_assign_noexcept.pass.cpp @@ -14,6 +14,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <queue> #include <cassert> @@ -21,10 +23,8 @@ int main() { -#if __has_feature(cxx_noexcept) { typedef std::queue<MoveOnly> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/container.adaptors/queue/queue.cons/move_noexcept.pass.cpp b/test/std/containers/container.adaptors/queue/queue.cons/move_noexcept.pass.cpp index 2402e609b9888..1c13b622c0a5a 100644 --- a/test/std/containers/container.adaptors/queue/queue.cons/move_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/queue/queue.cons/move_noexcept.pass.cpp @@ -14,6 +14,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <queue> #include <cassert> @@ -21,10 +23,8 @@ int main() { -#if __has_feature(cxx_noexcept) { typedef std::queue<MoveOnly> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/container.adaptors/queue/queue.defn/types.fail.cpp b/test/std/containers/container.adaptors/queue/queue.defn/types.fail.cpp new file mode 100644 index 0000000000000..2b8341fff009e --- /dev/null +++ b/test/std/containers/container.adaptors/queue/queue.defn/types.fail.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <queue> + +#include <queue> +#include <cassert> +#include <type_traits> + +int main() +{ +// LWG#2566 says that the first template param must match the second one's value type + std::queue<double, std::deque<int>> t; +} diff --git a/test/std/containers/container.adaptors/queue/queue.defn/types.pass.cpp b/test/std/containers/container.adaptors/queue/queue.defn/types.pass.cpp index cc918a361707c..7f1883a168389 100644 --- a/test/std/containers/container.adaptors/queue/queue.defn/types.pass.cpp +++ b/test/std/containers/container.adaptors/queue/queue.defn/types.pass.cpp @@ -46,13 +46,13 @@ struct C int main() { - static_assert((std::is_same<std::queue<int>::container_type, std::deque<int> >::value), ""); - static_assert((std::is_same<std::queue<double, std::vector<int> >::container_type, std::vector<int> >::value), ""); - static_assert((std::is_same<std::queue<double, std::vector<int> >::value_type, int>::value), ""); - static_assert((std::is_same<std::queue<int>::reference, std::deque<int>::reference>::value), ""); - static_assert((std::is_same<std::queue<int>::const_reference, std::deque<int>::const_reference>::value), ""); - static_assert((std::is_same<std::queue<int>::size_type, std::deque<int>::size_type>::value), ""); - static_assert((std::uses_allocator<std::queue<int>, std::allocator<int> >::value), ""); + static_assert(( std::is_same<std::queue<int>::container_type, std::deque<int> >::value), ""); + static_assert(( std::is_same<std::queue<int, std::vector<int> >::container_type, std::vector<int> >::value), ""); + static_assert(( std::is_same<std::queue<int, std::vector<int> >::value_type, int>::value), ""); + static_assert(( std::is_same<std::queue<int>::reference, std::deque<int>::reference>::value), ""); + static_assert(( std::is_same<std::queue<int>::const_reference, std::deque<int>::const_reference>::value), ""); + static_assert(( std::is_same<std::queue<int>::size_type, std::deque<int>::size_type>::value), ""); + static_assert(( std::uses_allocator<std::queue<int>, std::allocator<int> >::value), ""); static_assert((!std::uses_allocator<std::queue<int, C>, std::allocator<int> >::value), ""); test t; } diff --git a/test/std/containers/container.adaptors/queue/queue.special/swap_noexcept.pass.cpp b/test/std/containers/container.adaptors/queue/queue.special/swap_noexcept.pass.cpp index cfe4a1bb70768..e18f80a91198c 100644 --- a/test/std/containers/container.adaptors/queue/queue.special/swap_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/queue/queue.special/swap_noexcept.pass.cpp @@ -14,6 +14,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <queue> #include <cassert> @@ -21,11 +23,9 @@ int main() { -#if __has_feature(cxx_noexcept) { typedef std::queue<MoveOnly> C; C c1, c2; static_assert(noexcept(swap(c1, c2)), ""); } -#endif } diff --git a/test/std/containers/container.adaptors/stack/stack.cons/default_noexcept.pass.cpp b/test/std/containers/container.adaptors/stack/stack.cons/default_noexcept.pass.cpp index bab55863b55f4..2d1f9437fc45a 100644 --- a/test/std/containers/container.adaptors/stack/stack.cons/default_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/stack/stack.cons/default_noexcept.pass.cpp @@ -14,17 +14,18 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <stack> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" int main() { -#if __has_feature(cxx_noexcept) { typedef std::stack<MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/container.adaptors/stack/stack.cons/dtor_noexcept.pass.cpp b/test/std/containers/container.adaptors/stack/stack.cons/dtor_noexcept.pass.cpp index 477bd57a6d102..0a0111b4dc469 100644 --- a/test/std/containers/container.adaptors/stack/stack.cons/dtor_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/stack/stack.cons/dtor_noexcept.pass.cpp @@ -11,6 +11,8 @@ // ~stack() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <stack> #include <cassert> @@ -18,10 +20,8 @@ int main() { -#if __has_feature(cxx_noexcept) { typedef std::stack<MoveOnly> C; static_assert(std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/container.adaptors/stack/stack.cons/move_assign_noexcept.pass.cpp b/test/std/containers/container.adaptors/stack/stack.cons/move_assign_noexcept.pass.cpp index dd836796dc170..d5822839cabff 100644 --- a/test/std/containers/container.adaptors/stack/stack.cons/move_assign_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/stack/stack.cons/move_assign_noexcept.pass.cpp @@ -14,6 +14,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <stack> #include <cassert> @@ -21,10 +23,8 @@ int main() { -#if __has_feature(cxx_noexcept) { typedef std::stack<MoveOnly> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/container.adaptors/stack/stack.cons/move_noexcept.pass.cpp b/test/std/containers/container.adaptors/stack/stack.cons/move_noexcept.pass.cpp index cfc660b36def0..7eb563c76835d 100644 --- a/test/std/containers/container.adaptors/stack/stack.cons/move_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/stack/stack.cons/move_noexcept.pass.cpp @@ -14,6 +14,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <stack> #include <cassert> @@ -21,10 +23,8 @@ int main() { -#if __has_feature(cxx_noexcept) { typedef std::stack<MoveOnly> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/container.adaptors/stack/stack.defn/types.fail.cpp b/test/std/containers/container.adaptors/stack/stack.defn/types.fail.cpp new file mode 100644 index 0000000000000..ee4c5441e7c3e --- /dev/null +++ b/test/std/containers/container.adaptors/stack/stack.defn/types.fail.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <queue> + +// template <class T, class Container = vector<T>, +// class Compare = less<typename Container::value_type>> +// class priority_queue +// { +// public: +// typedef Container container_type; +// typedef typename container_type::value_type value_type; +// typedef typename container_type::reference reference; +// typedef typename container_type::const_reference const_reference; +// typedef typename container_type::size_type size_type; +// +// protected: +// container_type c; +// Compare comp; + +#include <stack> +#include <cassert> +#include <type_traits> + +int main() +{ +// LWG#2566 says that the first template param must match the second one's value type + std::stack<double, std::deque<int>> t; +} diff --git a/test/std/containers/container.adaptors/stack/stack.defn/types.pass.cpp b/test/std/containers/container.adaptors/stack/stack.defn/types.pass.cpp index afc5ebd537538..77a798b8382a1 100644 --- a/test/std/containers/container.adaptors/stack/stack.defn/types.pass.cpp +++ b/test/std/containers/container.adaptors/stack/stack.defn/types.pass.cpp @@ -47,13 +47,13 @@ struct C int main() { - static_assert((std::is_same<std::stack<int>::container_type, std::deque<int> >::value), ""); - static_assert((std::is_same<std::stack<double, std::vector<int> >::container_type, std::vector<int> >::value), ""); - static_assert((std::is_same<std::stack<double, std::vector<int> >::value_type, int>::value), ""); - static_assert((std::is_same<std::stack<int>::reference, std::deque<int>::reference>::value), ""); - static_assert((std::is_same<std::stack<int>::const_reference, std::deque<int>::const_reference>::value), ""); - static_assert((std::is_same<std::stack<int>::size_type, std::deque<int>::size_type>::value), ""); - static_assert((std::uses_allocator<std::stack<int>, std::allocator<int> >::value), ""); + static_assert(( std::is_same<std::stack<int>::container_type, std::deque<int> >::value), ""); + static_assert(( std::is_same<std::stack<int, std::vector<int> >::container_type, std::vector<int> >::value), ""); + static_assert(( std::is_same<std::stack<int, std::vector<int> >::value_type, int>::value), ""); + static_assert(( std::is_same<std::stack<int>::reference, std::deque<int>::reference>::value), ""); + static_assert(( std::is_same<std::stack<int>::const_reference, std::deque<int>::const_reference>::value), ""); + static_assert(( std::is_same<std::stack<int>::size_type, std::deque<int>::size_type>::value), ""); + static_assert(( std::uses_allocator<std::stack<int>, std::allocator<int> >::value), ""); static_assert((!std::uses_allocator<std::stack<int, C>, std::allocator<int> >::value), ""); test t; } diff --git a/test/std/containers/container.adaptors/stack/stack.special/swap_noexcept.pass.cpp b/test/std/containers/container.adaptors/stack/stack.special/swap_noexcept.pass.cpp index 80e024f5f1e07..976e362a0483d 100644 --- a/test/std/containers/container.adaptors/stack/stack.special/swap_noexcept.pass.cpp +++ b/test/std/containers/container.adaptors/stack/stack.special/swap_noexcept.pass.cpp @@ -14,6 +14,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <stack> #include <cassert> @@ -21,11 +23,9 @@ int main() { -#if __has_feature(cxx_noexcept) { typedef std::stack<MoveOnly> C; C c1, c2; static_assert(noexcept(swap(c1, c2)), ""); } -#endif } diff --git a/test/std/containers/map_allocator_requirement_test_templates.h b/test/std/containers/map_allocator_requirement_test_templates.h new file mode 100644 index 0000000000000..2ae3a2e3c87a4 --- /dev/null +++ b/test/std/containers/map_allocator_requirement_test_templates.h @@ -0,0 +1,743 @@ +//===----------------------------------------------------------------------===// +// +// 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 MAP_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H +#define MAP_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H + +// <map> +// <unordered_map> + +// class map +// class unordered_map + +// insert(...); +// emplace(...); +// emplace_hint(...); + +// UNSUPPORTED: c++98, c++03 + +#include <cassert> + +#include "test_macros.h" +#include "count_new.hpp" +#include "container_test_types.h" +#include "assert_checkpoint.h" + + +template <class Container> +void testMapInsert() +{ + typedef typename Container::value_type ValueTp; + typedef typename Container::key_type Key; + typedef typename Container::mapped_type Mapped; + typedef Container C; + typedef std::pair<typename C::iterator, bool> R; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::insert(const value_type&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + assert(c.insert(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + assert(c.insert(v2).second == false); + } + } + { + CHECKPOINT("Testing C::insert(value_type&)"); + Container c; + ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + assert(c.insert(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + assert(c.insert(v2).second == false); + } + } + { + CHECKPOINT("Testing C::insert(value_type&&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&&>(); + assert(c.insert(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + assert(c.insert(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::insert(const value_type&&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + assert(c.insert(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + assert(c.insert(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::insert({key, value})"); + Container c; + cc->expect<ValueTp&&>(); + assert(c.insert({42, 1}).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + assert(c.insert(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)"); + Container c; + std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) }; + cc->expect<ValueTp const&>(2); + c.insert(il); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(il); + } + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); + Container c; + const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) }; + cc->expect<ValueTp const&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(std::begin(ValueList), std::end(ValueList)); + } + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); + Container c; + ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; + cc->expect<ValueTp&&>(3); + c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), + std::move_iterator<ValueTp*>(std::end(ValueList))); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp ValueList2[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; + c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)), + std::move_iterator<ValueTp*>(std::end(ValueList2))); + } + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); + Container c; + ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; + cc->expect<ValueTp const&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(std::begin(ValueList), std::end(ValueList)); + } + } +} + + +template <class Container> +void testMapInsertHint() +{ + typedef typename Container::value_type ValueTp; + typedef typename Container::key_type Key; + typedef typename Container::mapped_type Mapped; + typedef typename std::pair<Key, Mapped> NonConstKeyPair; + typedef Container C; + typedef typename C::iterator It; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::insert(p, const value_type&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + It ret = c.insert(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + It ret2 = c.insert(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::insert(p, value_type&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp const&>(); + It ret = c.insert(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + It ret2 = c.insert(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::insert(p, value_type&&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&&>(); + It ret = c.insert(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + It ret2 = c.insert(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::insert(p, {key, value})"); + Container c; + cc->expect<ValueTp&&>(); + It ret = c.insert(c.end(), {42, 1}); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + It ret2 = c.insert(c.begin(), {42, 1}); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::insert(p, const value_type&&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + It ret = c.insert(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + It ret2 = c.insert(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::insert(p, pair<Key, Mapped> const&)"); + Container c; + const NonConstKeyPair v(42, 1); + cc->expect<const NonConstKeyPair&>(); + It ret = c.insert(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const NonConstKeyPair v2(42, 1); + It ret2 = c.insert(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::insert(p, pair<Key, Mapped>&&)"); + Container c; + NonConstKeyPair v(42, 1); + cc->expect<NonConstKeyPair&&>(); + It ret = c.insert(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + NonConstKeyPair v2(42, 1); + It ret2 = c.insert(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + + +} + + +template <class Container> +void testMapEmplace() +{ + typedef typename Container::value_type ValueTp; + typedef typename Container::key_type Key; + typedef typename Container::mapped_type Mapped; + typedef typename std::pair<Key, Mapped> NonConstKeyPair; + typedef Container C; + typedef std::pair<typename C::iterator, bool> R; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::emplace(const value_type&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + assert(c.emplace(v2).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(value_type&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&>(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + assert(c.emplace(v2).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(value_type&&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&&>(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + assert(c.emplace(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(const value_type&&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&&>(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + assert(c.emplace(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(pair<Key, Mapped> const&)"); + Container c; + const NonConstKeyPair v(42, 1); + cc->expect<const NonConstKeyPair&>(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const NonConstKeyPair v2(42, 1); + assert(c.emplace(v2).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(pair<Key, Mapped> &&)"); + Container c; + NonConstKeyPair v(42, 1); + cc->expect<NonConstKeyPair&&>(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + NonConstKeyPair v2(42, 1); + assert(c.emplace(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(const Key&, ConvertibleToMapped&&)"); + Container c; + const Key k(42); + cc->expect<Key const&, int&&>(); + assert(c.emplace(k, 1).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const Key k2(42); + assert(c.emplace(k2, 2).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(Key&, Mapped&)"); + Container c; + Key k(42); + Mapped m(1); + cc->expect<Key&, Mapped&>(); + assert(c.emplace(k, m).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + Key k2(42); + assert(c.emplace(k2, m).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(Key&&, Mapped&&)"); + Container c; + Key k(42); + Mapped m(1); + cc->expect<Key&&, Mapped&&>(); + assert(c.emplace(std::move(k), std::move(m)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + Key k2(42); + Mapped m2(2); + assert(c.emplace(std::move(k2), std::move(m2)).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(ConvertibleToKey&&, ConvertibleToMapped&&)"); + Container c; + cc->expect<int&&, int&&>(); + assert(c.emplace(42, 1).second); + assert(!cc->unchecked()); + { + // test that emplacing a duplicate item allocates. We cannot optimize + // this case because int&& does not match the type of key exactly. + cc->expect<int&&, int&&>(); + assert(c.emplace(42, 1).second == false); + assert(!cc->unchecked()); + } + } +} + + +template <class Container> +void testMapEmplaceHint() +{ + typedef typename Container::value_type ValueTp; + typedef typename Container::key_type Key; + typedef typename Container::mapped_type Mapped; + typedef typename std::pair<Key, Mapped> NonConstKeyPair; + typedef Container C; + typedef typename C::iterator It; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::emplace_hint(p, const value_type&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, value_type&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&>(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, value_type&&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&&>(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, const value_type&&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&&>(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, pair<Key, Mapped> const&)"); + Container c; + const NonConstKeyPair v(42, 1); + cc->expect<const NonConstKeyPair&>(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const NonConstKeyPair v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, pair<Key, Mapped>&&)"); + Container c; + NonConstKeyPair v(42, 1); + cc->expect<NonConstKeyPair&&>(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + NonConstKeyPair v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, const Key&, ConvertibleToMapped&&)"); + Container c; + const Key k(42); + cc->expect<Key const&, int&&>(); + It ret = c.emplace_hint(c.end(), k, 42); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const Key k2(42); + It ret2 = c.emplace_hint(c.begin(), k2, 1); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, Key&, Mapped&)"); + Container c; + Key k(42); + Mapped m(1); + cc->expect<Key&, Mapped&>(); + It ret = c.emplace_hint(c.end(), k, m); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + Key k2(42); + Mapped m2(2); + It ret2 = c.emplace_hint(c.begin(), k2, m2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, Key&&, Mapped&&)"); + Container c; + Key k(42); + Mapped m(1); + cc->expect<Key&&, Mapped&&>(); + It ret = c.emplace_hint(c.end(), std::move(k), std::move(m)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + Key k2(42); + Mapped m2(2); + It ret2 = c.emplace_hint(c.begin(), std::move(k2), std::move(m2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, ConvertibleToKey&&, ConvertibleToMapped&&)"); + Container c; + cc->expect<int&&, int&&>(); + It ret = c.emplace_hint(c.end(), 42, 1); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + cc->expect<int&&, int&&>(); + It ret2 = c.emplace_hint(c.begin(), 42, 2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + assert(!cc->unchecked()); + } + } + +} + + +template <class Container> +void testMultimapInsert() +{ + typedef typename Container::value_type ValueTp; + typedef Container C; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::insert(const value_type&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + c.insert(v); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(value_type&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&>(); + c.insert(v); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(value_type&&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&&>(); + c.insert(std::move(v)); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert({key, value})"); + Container c; + cc->expect<ValueTp&&>(); + c.insert({42, 1}); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)"); + Container c; + std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) }; + cc->expect<ValueTp const&>(2); + c.insert(il); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); + Container c; + const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) }; + cc->expect<ValueTp const&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); + Container c; + ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; + cc->expect<ValueTp&&>(3); + c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), + std::move_iterator<ValueTp*>(std::end(ValueList))); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); + Container c; + ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; + cc->expect<ValueTp&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + } +} + + +template <class Container> +void testMultimapInsertHint() +{ + typedef typename Container::value_type ValueTp; + typedef Container C; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::insert(p, const value_type&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + c.insert(c.begin(), v); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(p, value_type&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&>(); + c.insert(c.begin(), v); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(p, value_type&&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&&>(); + c.insert(c.begin(), std::move(v)); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(p, {key, value})"); + Container c; + cc->expect<ValueTp&&>(); + c.insert(c.begin(), {42, 1}); + assert(!cc->unchecked()); + } +} + +#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 5e429adb6fc98..64ea75a40064e 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 @@ -35,4 +35,18 @@ int main() C c = {}; assert(c.size() == 0); } + + { + typedef double T; + typedef std::array<T, 3> C; + C c = {1}; + assert(c.size() == 3.0); + assert(c[0] == 1); + } + { + typedef int T; + typedef std::array<T, 1> C; + C c = {}; + assert(c.size() == 1); + } } 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 c1b0b235ab34d..413f291a2a365 100644 --- a/test/std/containers/sequences/array/array.special/swap.pass.cpp +++ b/test/std/containers/sequences/array/array.special/swap.pass.cpp @@ -14,10 +14,28 @@ #include <array> #include <cassert> +#include "test_macros.h" // std::array is explicitly allowed to be initialized with A a = { init-list };. // Disable the missing braces warning for this reason. #include "disable_missing_braces_warning.h" +struct NonSwappable { + NonSwappable() {} +private: + NonSwappable(NonSwappable const&); + NonSwappable& operator=(NonSwappable const&); +}; + +template <class Tp> +decltype(swap(std::declval<Tp>(), std::declval<Tp>())) +can_swap_imp(int); + +template <class Tp> +std::false_type can_swap_imp(...); + +template <class Tp> +struct can_swap : std::is_same<decltype(can_swap_imp<Tp>(0)), void> {}; + int main() { { @@ -44,4 +62,24 @@ int main() assert(c1.size() == 0); assert(c2.size() == 0); } + { + typedef NonSwappable T; + typedef std::array<T, 0> C0; + static_assert(can_swap<C0&>::value, ""); + C0 l = {}; + C0 r = {}; + swap(l, r); +#if TEST_STD_VER >= 11 + static_assert(noexcept(swap(l, r)), ""); +#endif + } +#if TEST_STD_VER >= 11 + { + // NonSwappable is still considered swappable in C++03 because there + // is no access control SFINAE. + typedef NonSwappable T; + typedef std::array<T, 42> C1; + static_assert(!can_swap<C1&>::value, ""); + } +#endif } 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 651798e1e790d..8d01dbf959ce2 100644 --- a/test/std/containers/sequences/array/array.swap/swap.pass.cpp +++ b/test/std/containers/sequences/array/array.swap/swap.pass.cpp @@ -10,14 +10,24 @@ // <array> // void swap(array& a); +// namespace std { void swap(array<T, N> &x, array<T, N> &y); -#include <array> #include <cassert> +#include <array> + +#include "test_macros.h" // std::array is explicitly allowed to be initialized with A a = { init-list };. // Disable the missing braces warning for this reason. #include "disable_missing_braces_warning.h" +struct NonSwappable { + NonSwappable() {} +private: + NonSwappable(NonSwappable const&); + NonSwappable& operator=(NonSwappable const&); +}; + int main() { { @@ -37,6 +47,22 @@ int main() } { typedef double T; + typedef std::array<T, 3> C; + C c1 = {1, 2, 3.5}; + C c2 = {4, 5, 6.5}; + std::swap(c1, c2); + assert(c1.size() == 3); + assert(c1[0] == 4); + assert(c1[1] == 5); + assert(c1[2] == 6.5); + assert(c2.size() == 3); + assert(c2[0] == 1); + assert(c2[1] == 2); + assert(c2[2] == 3.5); + } + + { + typedef double T; typedef std::array<T, 0> C; C c1 = {}; C c2 = {}; @@ -44,4 +70,24 @@ int main() assert(c1.size() == 0); assert(c2.size() == 0); } + { + typedef double T; + typedef std::array<T, 0> C; + C c1 = {}; + C c2 = {}; + std::swap(c1, c2); + assert(c1.size() == 0); + assert(c2.size() == 0); + } + { + typedef NonSwappable T; + typedef std::array<T, 0> C0; + C0 l = {}; + C0 r = {}; + l.swap(r); +#if TEST_STD_VER >= 11 + static_assert(noexcept(l.swap(r)), ""); +#endif + } + } diff --git a/test/std/containers/sequences/array/at.pass.cpp b/test/std/containers/sequences/array/at.pass.cpp index 5cb89dfeeb9ad..9707beeb39461 100644 --- a/test/std/containers/sequences/array/at.pass.cpp +++ b/test/std/containers/sequences/array/at.pass.cpp @@ -49,14 +49,14 @@ int main() const C c = {1, 2, 3.5}; C::const_reference r1 = c.at(0); assert(r1 == 1); - + C::const_reference r2 = c.at(2); assert(r2 == 3.5); try { (void) c.at(3); } catch (const std::out_of_range &) {} } - + #if TEST_STD_VER > 11 { typedef double T; diff --git a/test/std/containers/sequences/array/front_back.pass.cpp b/test/std/containers/sequences/array/front_back.pass.cpp index bccaade986ea8..7d53b8265e96e 100644 --- a/test/std/containers/sequences/array/front_back.pass.cpp +++ b/test/std/containers/sequences/array/front_back.pass.cpp @@ -34,7 +34,7 @@ int main() assert(r1 == 1); r1 = 5.5; assert(c[0] == 5.5); - + C::reference r2 = c.back(); assert(r2 == 3.5); r2 = 7.5; diff --git a/test/std/containers/sequences/array/indexing.pass.cpp b/test/std/containers/sequences/array/indexing.pass.cpp index 5ccb0b487b95b..64d2716a75922 100644 --- a/test/std/containers/sequences/array/indexing.pass.cpp +++ b/test/std/containers/sequences/array/indexing.pass.cpp @@ -33,7 +33,7 @@ int main() assert(r1 == 1); r1 = 5.5; assert(c.front() == 5.5); - + C::reference r2 = c[2]; assert(r2 == 3.5); r2 = 7.5; diff --git a/test/std/containers/sequences/array/iterators.pass.cpp b/test/std/containers/sequences/array/iterators.pass.cpp index 98997d8c26d5a..233e9328c4ed0 100644 --- a/test/std/containers/sequences/array/iterators.pass.cpp +++ b/test/std/containers/sequences/array/iterators.pass.cpp @@ -59,7 +59,7 @@ int main() assert ( c.cend() == std::cend(c)); assert ( c.rend() == std::rend(c)); assert ( c.crend() == std::crend(c)); - + assert ( std::begin(c) != std::end(c)); assert ( std::rbegin(c) != std::rend(c)); assert ( std::cbegin(c) != std::cend(c)); diff --git a/test/std/containers/sequences/array/types.pass.cpp b/test/std/containers/sequences/array/types.pass.cpp index 065ade959d055..9cf390c4eacb5 100644 --- a/test/std/containers/sequences/array/types.pass.cpp +++ b/test/std/containers/sequences/array/types.pass.cpp @@ -29,6 +29,25 @@ #include <iterator> #include <type_traits> +#include "test_macros.h" + +template <class C> +void test_iterators() { + typedef std::iterator_traits<typename C::iterator> ItT; + typedef std::iterator_traits<typename C::const_iterator> CItT; + static_assert((std::is_same<typename ItT::iterator_category, std::random_access_iterator_tag>::value), ""); + static_assert((std::is_same<typename ItT::value_type, typename C::value_type>::value), ""); + static_assert((std::is_same<typename ItT::reference, typename C::reference>::value), ""); + static_assert((std::is_same<typename ItT::pointer, typename C::pointer>::value), ""); + static_assert((std::is_same<typename ItT::difference_type, typename C::difference_type>::value), ""); + + static_assert((std::is_same<typename CItT::iterator_category, std::random_access_iterator_tag>::value), ""); + static_assert((std::is_same<typename CItT::value_type, typename C::value_type>::value), ""); + static_assert((std::is_same<typename CItT::reference, typename C::const_reference>::value), ""); + static_assert((std::is_same<typename CItT::pointer, typename C::const_pointer>::value), ""); + static_assert((std::is_same<typename CItT::difference_type, typename C::difference_type>::value), ""); +} + int main() { { @@ -36,27 +55,43 @@ int main() typedef std::array<T, 10> C; static_assert((std::is_same<C::reference, T&>::value), ""); static_assert((std::is_same<C::const_reference, const T&>::value), ""); - static_assert((std::is_same<C::iterator, T*>::value), ""); - static_assert((std::is_same<C::const_iterator, const T*>::value), ""); + LIBCPP_STATIC_ASSERT((std::is_same<C::iterator, T*>::value), ""); + LIBCPP_STATIC_ASSERT((std::is_same<C::const_iterator, const T*>::value), ""); + test_iterators<C>(); static_assert((std::is_same<C::pointer, T*>::value), ""); static_assert((std::is_same<C::const_pointer, const T*>::value), ""); static_assert((std::is_same<C::size_type, std::size_t>::value), ""); static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), ""); static_assert((std::is_same<C::reverse_iterator, std::reverse_iterator<C::iterator> >::value), ""); static_assert((std::is_same<C::const_reverse_iterator, std::reverse_iterator<C::const_iterator> >::value), ""); + + static_assert((std::is_signed<typename C::difference_type>::value), ""); + static_assert((std::is_unsigned<typename C::size_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::iterator>::difference_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::const_iterator>::difference_type>::value), ""); } { typedef int* T; typedef std::array<T, 0> C; static_assert((std::is_same<C::reference, T&>::value), ""); static_assert((std::is_same<C::const_reference, const T&>::value), ""); - static_assert((std::is_same<C::iterator, T*>::value), ""); - static_assert((std::is_same<C::const_iterator, const T*>::value), ""); + LIBCPP_STATIC_ASSERT((std::is_same<C::iterator, T*>::value), ""); + LIBCPP_STATIC_ASSERT((std::is_same<C::const_iterator, const T*>::value), ""); + test_iterators<C>(); static_assert((std::is_same<C::pointer, T*>::value), ""); static_assert((std::is_same<C::const_pointer, const T*>::value), ""); static_assert((std::is_same<C::size_type, std::size_t>::value), ""); static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), ""); static_assert((std::is_same<C::reverse_iterator, std::reverse_iterator<C::iterator> >::value), ""); static_assert((std::is_same<C::const_reverse_iterator, std::reverse_iterator<C::const_iterator> >::value), ""); + + static_assert((std::is_signed<typename C::difference_type>::value), ""); + static_assert((std::is_unsigned<typename C::size_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::iterator>::difference_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::const_iterator>::difference_type>::value), ""); } } diff --git a/test/std/containers/sequences/deque/deque.capacity/access.pass.cpp b/test/std/containers/sequences/deque/deque.capacity/access.pass.cpp index 996fc9a18fe77..a6a8e7424b254 100644 --- a/test/std/containers/sequences/deque/deque.capacity/access.pass.cpp +++ b/test/std/containers/sequences/deque/deque.capacity/access.pass.cpp @@ -68,7 +68,7 @@ int main() assert(c.front() == 0); assert(c.back() == 9); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::deque<int, min_allocator<int>> c = make<std::deque<int, min_allocator<int>> >(10); for (unsigned i = 0; i < 10; ++i) 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 84f04f9d52daa..53c6bd3380a22 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 @@ -12,6 +12,8 @@ // void resize(size_type n); #include <deque> +#include <algorithm> +#include <iterator> #include <cassert> #include "test_macros.h" 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 2bf2423fb9af7..12af64386bd86 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 @@ -12,6 +12,8 @@ // void resize(size_type n, const value_type& v); #include <deque> +#include <algorithm> +#include <iterator> #include <cassert> #include "test_macros.h" diff --git a/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp b/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp index 841bfd9f8a7f7..787c2394b38e3 100644 --- a/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp @@ -31,7 +31,7 @@ int main() { test<int>(std::allocator<int>()); test<NotConstructible>(test_allocator<NotConstructible>(3)); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<int>(min_allocator<int>()); test<NotConstructible>(min_allocator<NotConstructible>{}); #endif diff --git a/test/std/containers/sequences/deque/deque.cons/assign_initializer_list.pass.cpp b/test/std/containers/sequences/deque/deque.cons/assign_initializer_list.pass.cpp index c760b4372444a..dea6492a515d8 100644 --- a/test/std/containers/sequences/deque/deque.cons/assign_initializer_list.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/assign_initializer_list.pass.cpp @@ -28,7 +28,7 @@ int main() assert(d[2] == 5); assert(d[3] == 6); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::deque<int, min_allocator<int>> d; d.assign({3, 4, 5, 6}); diff --git a/test/std/containers/sequences/deque/deque.cons/copy.pass.cpp b/test/std/containers/sequences/deque/deque.cons/copy.pass.cpp index fa0c1203ede9b..ec73555b9c4f5 100644 --- a/test/std/containers/sequences/deque/deque.cons/copy.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/copy.pass.cpp @@ -45,7 +45,7 @@ int main() assert(v2.get_allocator() == other_allocator<int>(-2)); } #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45}; int* an = ab + sizeof(ab)/sizeof(ab[0]); diff --git a/test/std/containers/sequences/deque/deque.cons/copy_alloc.pass.cpp b/test/std/containers/sequences/deque/deque.cons/copy_alloc.pass.cpp index efea4948eba19..3a49a8bc0c66f 100644 --- a/test/std/containers/sequences/deque/deque.cons/copy_alloc.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/copy_alloc.pass.cpp @@ -40,7 +40,7 @@ int main() test(std::deque<int, other_allocator<int> >(ab, an, other_allocator<int>(3)), other_allocator<int>(4)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45}; int* an = ab + sizeof(ab)/sizeof(ab[0]); diff --git a/test/std/containers/sequences/deque/deque.cons/default.pass.cpp b/test/std/containers/sequences/deque/deque.cons/default.pass.cpp index b725dade70b20..7c42d9e7786ee 100644 --- a/test/std/containers/sequences/deque/deque.cons/default.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/default.pass.cpp @@ -24,7 +24,7 @@ test() { std::deque<T, Allocator> d; assert(d.size() == 0); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 std::deque<T, Allocator> d1 = {}; assert(d1.size() == 0); #endif @@ -34,7 +34,7 @@ int main() { test<int, std::allocator<int> >(); test<NotConstructible, stack_allocator<NotConstructible, 1> >(); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<int, min_allocator<int> >(); test<NotConstructible, min_allocator<NotConstructible> >(); #endif diff --git a/test/std/containers/sequences/deque/deque.cons/default_noexcept.pass.cpp b/test/std/containers/sequences/deque/deque.cons/default_noexcept.pass.cpp index c612dbc5e838f..30cca929da11f 100644 --- a/test/std/containers/sequences/deque/deque.cons/default_noexcept.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/default_noexcept.pass.cpp @@ -14,9 +14,12 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <deque> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -29,14 +32,13 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::deque<MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::deque<MoveOnly, test_allocator<MoveOnly>> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::deque<MoveOnly, other_allocator<MoveOnly>> C; @@ -46,5 +48,4 @@ int main() typedef std::deque<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp b/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp index ecdc2404c855b..503e1237e9eb0 100644 --- a/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp @@ -11,14 +11,14 @@ // ~deque() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <deque> #include <cassert> #include "MoveOnly.h" #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_alloc { @@ -27,11 +27,8 @@ struct some_alloc ~some_alloc() noexcept(false); }; -#endif - int main() { -#if __has_feature(cxx_noexcept) { typedef std::deque<MoveOnly> C; static_assert(std::is_nothrow_destructible<C>::value, ""); @@ -48,5 +45,4 @@ int main() typedef std::deque<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/deque/deque.cons/initializer_list.pass.cpp b/test/std/containers/sequences/deque/deque.cons/initializer_list.pass.cpp index a9e0218e2e0b4..dbf27053a9f9f 100644 --- a/test/std/containers/sequences/deque/deque.cons/initializer_list.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/initializer_list.pass.cpp @@ -27,7 +27,7 @@ int main() assert(d[2] == 5); assert(d[3] == 6); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::deque<int, min_allocator<int>> d = {3, 4, 5, 6}; assert(d.size() == 4); diff --git a/test/std/containers/sequences/deque/deque.cons/initializer_list_alloc.pass.cpp b/test/std/containers/sequences/deque/deque.cons/initializer_list_alloc.pass.cpp index 36c5af60ee34d..9be3c63a6b312 100644 --- a/test/std/containers/sequences/deque/deque.cons/initializer_list_alloc.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/initializer_list_alloc.pass.cpp @@ -29,7 +29,7 @@ int main() assert(d[2] == 5); assert(d[3] == 6); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::deque<int, min_allocator<int>> d({3, 4, 5, 6}, min_allocator<int>()); assert(d.get_allocator() == min_allocator<int>()); diff --git a/test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp b/test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp index faadf2b1a1db8..12a7faf686dbe 100644 --- a/test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp @@ -56,7 +56,7 @@ int main() test(bidirectional_iterator<const int*>(ab), bidirectional_iterator<const int*>(an)); test(random_access_iterator<const int*>(ab), random_access_iterator<const int*>(an)); test<stack_allocator<int, 4096> >(ab, an); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<min_allocator<int> >(ab, an); #endif } diff --git a/test/std/containers/sequences/deque/deque.cons/iter_iter_alloc.pass.cpp b/test/std/containers/sequences/deque/deque.cons/iter_iter_alloc.pass.cpp index b8c3e889929d8..c8f7759a19d60 100644 --- a/test/std/containers/sequences/deque/deque.cons/iter_iter_alloc.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/iter_iter_alloc.pass.cpp @@ -42,7 +42,7 @@ int main() test(forward_iterator<const int*>(ab), forward_iterator<const int*>(an), test_allocator<int>(4)); test(bidirectional_iterator<const int*>(ab), bidirectional_iterator<const int*>(an), test_allocator<int>(5)); test(random_access_iterator<const int*>(ab), random_access_iterator<const int*>(an), test_allocator<int>(6)); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test(input_iterator<const int*>(ab), input_iterator<const int*>(an), min_allocator<int>()); test(forward_iterator<const int*>(ab), forward_iterator<const int*>(an), min_allocator<int>()); test(bidirectional_iterator<const int*>(ab), bidirectional_iterator<const int*>(an), min_allocator<int>()); diff --git a/test/std/containers/sequences/deque/deque.cons/move.pass.cpp b/test/std/containers/sequences/deque/deque.cons/move.pass.cpp index 4a7aa8a058eba..68875139da1aa 100644 --- a/test/std/containers/sequences/deque/deque.cons/move.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/move.pass.cpp @@ -51,7 +51,7 @@ int main() assert(c1.size() == 0); assert(c3.get_allocator() == c1.get_allocator()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45}; int* an = ab + sizeof(ab)/sizeof(ab[0]); diff --git a/test/std/containers/sequences/deque/deque.cons/move_alloc.pass.cpp b/test/std/containers/sequences/deque/deque.cons/move_alloc.pass.cpp index 1a5db6db65009..4aa0fa6827e79 100644 --- a/test/std/containers/sequences/deque/deque.cons/move_alloc.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/move_alloc.pass.cpp @@ -66,7 +66,7 @@ int main() assert(c3.get_allocator() == A(3)); assert(c1.size() != 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45}; int* an = ab + sizeof(ab)/sizeof(ab[0]); diff --git a/test/std/containers/sequences/deque/deque.cons/move_assign.pass.cpp b/test/std/containers/sequences/deque/deque.cons/move_assign.pass.cpp index e50cd8ed508d1..ed8f1544bc8ff 100644 --- a/test/std/containers/sequences/deque/deque.cons/move_assign.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/move_assign.pass.cpp @@ -69,7 +69,7 @@ int main() assert(c1.size() == 0); assert(c3.get_allocator() == A(5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45}; int* an = ab + sizeof(ab)/sizeof(ab[0]); diff --git a/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.pass.cpp b/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.pass.cpp index 24180b5b5bdd3..cebf76a15a4ae 100644 --- a/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/move_assign_noexcept.pass.cpp @@ -16,6 +16,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <deque> #include <cassert> @@ -31,7 +33,6 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::deque<MoveOnly> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); @@ -48,5 +49,4 @@ int main() typedef std::deque<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/deque/deque.cons/move_noexcept.pass.cpp b/test/std/containers/sequences/deque/deque.cons/move_noexcept.pass.cpp index 0ea0431be8e2f..f53e1ba6c8074 100644 --- a/test/std/containers/sequences/deque/deque.cons/move_noexcept.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/move_noexcept.pass.cpp @@ -14,6 +14,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <deque> #include <cassert> @@ -29,7 +31,6 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::deque<MoveOnly> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); @@ -46,5 +47,4 @@ int main() typedef std::deque<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/deque/deque.cons/op_equal.pass.cpp b/test/std/containers/sequences/deque/deque.cons/op_equal.pass.cpp index 3a6ec8370b843..6aac6b20c49ec 100644 --- a/test/std/containers/sequences/deque/deque.cons/op_equal.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/op_equal.pass.cpp @@ -46,7 +46,7 @@ int main() assert(l2 == l); assert(l2.get_allocator() == other_allocator<int>(5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45}; int* an = ab + sizeof(ab)/sizeof(ab[0]); diff --git a/test/std/containers/sequences/deque/deque.cons/op_equal_initializer_list.pass.cpp b/test/std/containers/sequences/deque/deque.cons/op_equal_initializer_list.pass.cpp index 6468e4329bdad..597f642db3ce5 100644 --- a/test/std/containers/sequences/deque/deque.cons/op_equal_initializer_list.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/op_equal_initializer_list.pass.cpp @@ -28,7 +28,7 @@ int main() assert(d[2] == 5); assert(d[3] == 6); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::deque<int, min_allocator<int>> d; d = {3, 4, 5, 6}; diff --git a/test/std/containers/sequences/deque/deque.cons/size.pass.cpp b/test/std/containers/sequences/deque/deque.cons/size.pass.cpp index d2e324b0e3f52..b3fccf6671c9d 100644 --- a/test/std/containers/sequences/deque/deque.cons/size.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/size.pass.cpp @@ -100,7 +100,7 @@ int main() test1<DefaultOnly, stack_allocator<DefaultOnly, 4096> >(4095); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<DefaultOnly, min_allocator<DefaultOnly> >(4095); #endif diff --git a/test/std/containers/sequences/deque/deque.cons/size_value.pass.cpp b/test/std/containers/sequences/deque/deque.cons/size_value.pass.cpp index 859deba1e1ae2..aeda168d19d46 100644 --- a/test/std/containers/sequences/deque/deque.cons/size_value.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/size_value.pass.cpp @@ -45,7 +45,7 @@ int main() test<int, std::allocator<int> >(4096, 1165); test<int, std::allocator<int> >(4097, 157); test<int, stack_allocator<int, 4096> >(4095, 90); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<int, min_allocator<int> >(4095, 90); #endif } diff --git a/test/std/containers/sequences/deque/deque.cons/size_value_alloc.pass.cpp b/test/std/containers/sequences/deque/deque.cons/size_value_alloc.pass.cpp index 5693be702de77..ed8a7e13baa58 100644 --- a/test/std/containers/sequences/deque/deque.cons/size_value_alloc.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/size_value_alloc.pass.cpp @@ -47,7 +47,7 @@ int main() test(4096, 1165, a); test(4097, 157, a); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { min_allocator<int> a; test(0, 5, a); diff --git a/test/std/containers/sequences/deque/deque.modifiers/emplace_back.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/emplace_back.pass.cpp index cf717c2e2f27e..784b3a38553a0 100644 --- a/test/std/containers/sequences/deque/deque.modifiers/emplace_back.pass.cpp +++ b/test/std/containers/sequences/deque/deque.modifiers/emplace_back.pass.cpp @@ -16,6 +16,7 @@ #include "../../../Emplaceable.h" #include "min_allocator.h" +#include "test_allocator.h" #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -74,7 +75,7 @@ int main() for (int j = 0; j < N; ++j) testN<std::deque<Emplaceable> >(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]); @@ -82,6 +83,17 @@ int main() for (int j = 0; j < N; ++j) testN<std::deque<Emplaceable, min_allocator<Emplaceable>> >(rng[i], rng[j]); } + { + std::deque<Tag_X, TaggingAllocator<Tag_X>> c; + c.emplace_back(); + assert(c.size() == 1); + c.emplace_back(1, 2, 3); + assert(c.size() == 2); + c.emplace_front(); + assert(c.size() == 3); + c.emplace_front(1, 2, 3); + assert(c.size() == 4); + } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/std/containers/sequences/deque/deque.modifiers/emplace_front.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/emplace_front.pass.cpp index becf94ffb4ef3..afc0e4972e38f 100644 --- a/test/std/containers/sequences/deque/deque.modifiers/emplace_front.pass.cpp +++ b/test/std/containers/sequences/deque/deque.modifiers/emplace_front.pass.cpp @@ -74,7 +74,7 @@ int main() for (int j = 0; j < N; ++j) testN<std::deque<Emplaceable> >(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.modifiers/erase_iter.invalidation.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/erase_iter.invalidation.pass.cpp index 49465cddaef7d..a7a93571f5097 100644 --- 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 @@ -23,9 +23,9 @@ 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); @@ -42,7 +42,7 @@ 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(); @@ -60,7 +60,7 @@ 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); diff --git a/test/std/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp index a45b75d25c9c2..116ed9aa4b5a1 100644 --- a/test/std/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp +++ b/test/std/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp @@ -12,6 +12,8 @@ // iterator erase(const_iterator p) #include <deque> +#include <algorithm> +#include <iterator> #include <cassert> #include "min_allocator.h" @@ -78,7 +80,7 @@ int main() 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.modifiers/erase_iter_iter.invalidation.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.invalidation.pass.cpp index c785e264db06a..a0ccd200bfb7c 100644 --- 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 @@ -26,9 +26,9 @@ void del_at_start(C c, size_t num) 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); @@ -38,7 +38,7 @@ void del_at_start(C c, size_t num) assert( *it2 == *it4); assert(&*it2 == &*it4); } - + template <typename C> void del_at_end(C c, size_t num) { @@ -46,7 +46,7 @@ void del_at_end(C c, size_t num) 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(); diff --git a/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp index 0576aca5c1a8c..a53abaf85d331 100644 --- a/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp +++ b/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp @@ -14,6 +14,8 @@ // iterator erase(const_iterator f, const_iterator l) #include <deque> +#include <algorithm> +#include <iterator> #include <cassert> #include "min_allocator.h" @@ -84,7 +86,7 @@ int main() 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.modifiers/pop_back.invalidation.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/pop_back.invalidation.pass.cpp index 1d84f73ccb56d..0f5f8e67a24b3 100644 --- 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 @@ -22,9 +22,9 @@ 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); @@ -40,7 +40,7 @@ int main() std::deque<int> queue; for (int i = 0; i < 20; ++i) queue.push_back(i); - + while (queue.size() > 1) { test(queue); diff --git a/test/std/containers/sequences/deque/deque.modifiers/pop_back.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/pop_back.pass.cpp index b345faaf89e9f..aeb62c9d996a4 100644 --- a/test/std/containers/sequences/deque/deque.modifiers/pop_back.pass.cpp +++ b/test/std/containers/sequences/deque/deque.modifiers/pop_back.pass.cpp @@ -72,7 +72,7 @@ int main() 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.modifiers/pop_front.invalidation.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/pop_front.invalidation.pass.cpp index 78317f3a3f9ce..d7fd910cca5f0 100644 --- 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 @@ -22,9 +22,9 @@ 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); @@ -40,7 +40,7 @@ int main() std::deque<int> queue; for (int i = 0; i < 20; ++i) queue.push_back(i); - + while (queue.size() > 1) { test(queue); diff --git a/test/std/containers/sequences/deque/deque.modifiers/pop_front.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/pop_front.pass.cpp index d570ec333715b..c7a3a625eab67 100644 --- a/test/std/containers/sequences/deque/deque.modifiers/pop_front.pass.cpp +++ b/test/std/containers/sequences/deque/deque.modifiers/pop_front.pass.cpp @@ -72,7 +72,7 @@ int main() 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.modifiers/push_back.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/push_back.pass.cpp index 96df6097d9940..198cbcf67cc73 100644 --- a/test/std/containers/sequences/deque/deque.modifiers/push_back.pass.cpp +++ b/test/std/containers/sequences/deque/deque.modifiers/push_back.pass.cpp @@ -62,7 +62,7 @@ int main() for (int j = 0; j < N; ++j) test<std::deque<int> >(rng[j]); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2046, 2047, 2048, 2049, 4094, 4095, 4096}; const int N = sizeof(rng)/sizeof(rng[0]); 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 b37e961e442fa..1fe1da102f37f 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 @@ -26,11 +26,11 @@ class CMyClass { bool equal(const CMyClass &rhs) const { return fTag == rhs.fTag && fMagicValue == rhs.fMagicValue; } - + private: int fMagicValue; int fTag; - + private: static int kStartedConstructionMagicValue; private: static int kFinishedConstructionMagicValue; }; @@ -84,7 +84,7 @@ int main() assert(vec==vec2); } } - + { typedef std::deque<CMyClass, test_allocator<CMyClass> > C; C vec; diff --git a/test/std/containers/sequences/deque/deque.modifiers/push_back_rvalue.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/push_back_rvalue.pass.cpp index d4ab0d3e2f266..b5c881064a953 100644 --- a/test/std/containers/sequences/deque/deque.modifiers/push_back_rvalue.pass.cpp +++ b/test/std/containers/sequences/deque/deque.modifiers/push_back_rvalue.pass.cpp @@ -68,7 +68,7 @@ int main() for (int j = 0; j < N; ++j) test<std::deque<MoveOnly> >(rng[j]); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2046, 2047, 2048, 2049, 4094, 4095, 4096}; const int N = sizeof(rng)/sizeof(rng[0]); diff --git a/test/std/containers/sequences/deque/deque.modifiers/push_front.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/push_front.pass.cpp index 4d6443b1f967e..ee4f3d7f9ed72 100644 --- a/test/std/containers/sequences/deque/deque.modifiers/push_front.pass.cpp +++ b/test/std/containers/sequences/deque/deque.modifiers/push_front.pass.cpp @@ -71,7 +71,7 @@ int main() 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.modifiers/push_front_exception_safety.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp index b4caa947aed84..7464870f07e1b 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 @@ -30,7 +30,7 @@ class CMyClass { private: int fMagicValue; int fTag; - + private: static int kStartedConstructionMagicValue; private: static int kFinishedConstructionMagicValue; }; @@ -84,7 +84,7 @@ int main() assert(vec==vec2); } } - + { typedef std::deque<CMyClass, test_allocator<CMyClass> > C; C vec; diff --git a/test/std/containers/sequences/deque/deque.modifiers/push_front_rvalue.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/push_front_rvalue.pass.cpp index ea91ec1b0a44c..ab15ca3326bf6 100644 --- a/test/std/containers/sequences/deque/deque.modifiers/push_front_rvalue.pass.cpp +++ b/test/std/containers/sequences/deque/deque.modifiers/push_front_rvalue.pass.cpp @@ -77,7 +77,7 @@ int main() for (int j = 0; j < N; ++j) testN<std::deque<MoveOnly> >(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.special/copy.pass.cpp b/test/std/containers/sequences/deque/deque.special/copy.pass.cpp index 3a9962b330a4d..846d87c6b6642 100644 --- a/test/std/containers/sequences/deque/deque.special/copy.pass.cpp +++ b/test/std/containers/sequences/deque/deque.special/copy.pass.cpp @@ -76,7 +76,7 @@ int main() 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.special/copy_backward.pass.cpp b/test/std/containers/sequences/deque/deque.special/copy_backward.pass.cpp index ccb30a9997d81..e7f37f98d2701 100644 --- a/test/std/containers/sequences/deque/deque.special/copy_backward.pass.cpp +++ b/test/std/containers/sequences/deque/deque.special/copy_backward.pass.cpp @@ -75,7 +75,7 @@ int main() 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.special/move.pass.cpp b/test/std/containers/sequences/deque/deque.special/move.pass.cpp index abd8e079975ac..1bdbeaf9d5c6f 100644 --- a/test/std/containers/sequences/deque/deque.special/move.pass.cpp +++ b/test/std/containers/sequences/deque/deque.special/move.pass.cpp @@ -75,7 +75,7 @@ int main() 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.special/move_backward.pass.cpp b/test/std/containers/sequences/deque/deque.special/move_backward.pass.cpp index ea04f6a15acf8..8e909c63c9120 100644 --- a/test/std/containers/sequences/deque/deque.special/move_backward.pass.cpp +++ b/test/std/containers/sequences/deque/deque.special/move_backward.pass.cpp @@ -75,7 +75,7 @@ int main() 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.special/swap.pass.cpp b/test/std/containers/sequences/deque/deque.special/swap.pass.cpp index 26757c351f1a3..ab21f434937e1 100644 --- a/test/std/containers/sequences/deque/deque.special/swap.pass.cpp +++ b/test/std/containers/sequences/deque/deque.special/swap.pass.cpp @@ -85,7 +85,7 @@ int main() assert((c2 == std::deque<int, A>(a1, a1+sizeof(a1)/sizeof(a1[0])))); assert(c2.get_allocator() == A(1)); } -#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.special/swap_noexcept.pass.cpp b/test/std/containers/sequences/deque/deque.special/swap_noexcept.pass.cpp index 83bcac8997edf..2f999e9a7a5d5 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <deque> // void swap(deque& c) @@ -21,6 +23,7 @@ #include <deque> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -28,7 +31,7 @@ template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -40,7 +43,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -51,7 +54,6 @@ struct some_alloc2 int main() { -#if __has_feature(cxx_noexcept) { typedef std::deque<MoveOnly> C; C c1, c2; @@ -86,5 +88,4 @@ int main() } #endif -#endif } diff --git a/test/std/containers/sequences/deque/iterators.pass.cpp b/test/std/containers/sequences/deque/iterators.pass.cpp index 8ec491fae4da6..19d7996f824ff 100644 --- a/test/std/containers/sequences/deque/iterators.pass.cpp +++ b/test/std/containers/sequences/deque/iterators.pass.cpp @@ -33,7 +33,7 @@ int main() j = c.cbegin(); assert(i == j); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::deque<int, min_allocator<int>> C; C c; @@ -68,7 +68,7 @@ int main() assert ( (cii >= ii1 )); assert (cii - ii1 == 0); assert (ii1 - cii == 0); - + // std::deque<int> c; // assert ( ii1 != c.cbegin()); // assert ( cii != c.begin()); diff --git a/test/std/containers/sequences/deque/types.pass.cpp b/test/std/containers/sequences/deque/types.pass.cpp index da9470d8a6c68..53b33d9e6be93 100644 --- a/test/std/containers/sequences/deque/types.pass.cpp +++ b/test/std/containers/sequences/deque/types.pass.cpp @@ -64,6 +64,12 @@ test() static_assert((std::is_same< typename C::const_reverse_iterator, std::reverse_iterator<typename C::const_iterator> >::value), ""); + static_assert((std::is_signed<typename C::difference_type>::value), ""); + static_assert((std::is_unsigned<typename C::size_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::iterator>::difference_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::const_iterator>::difference_type>::value), ""); } int main() @@ -73,7 +79,8 @@ int main() test<Copyable, test_allocator<Copyable> >(); static_assert((std::is_same<std::deque<char>::allocator_type, std::allocator<char> >::value), ""); -#if __cplusplus >= 201103L + +#if TEST_STD_VER >= 11 { typedef std::deque<short, min_allocator<short>> C; static_assert((std::is_same<C::value_type, short>::value), ""); @@ -85,6 +92,13 @@ int main() // min_allocator doesn't have a size_type, so one gets synthesized static_assert((std::is_same<C::size_type, std::make_unsigned<C::difference_type>::type>::value), ""); static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), ""); + + static_assert((std::is_signed<typename C::difference_type>::value), ""); + static_assert((std::is_unsigned<typename C::size_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::iterator>::difference_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::const_iterator>::difference_type>::value), ""); } #endif } diff --git a/test/std/containers/sequences/forwardlist/forwardlist.access/front.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.access/front.pass.cpp index 2ec9b8713326b..ae14eda501735 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.access/front.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.access/front.pass.cpp @@ -38,7 +38,7 @@ int main() assert(c.front() == 0); assert(*c.begin() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp index 7aba906ec20df..352945c852d81 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp @@ -28,7 +28,7 @@ int main() assert(c.get_allocator() == A(12)); assert(c.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<NotConstructible> A; typedef A::value_type T; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_copy.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_copy.pass.cpp index 0b9263db98991..244054477d56c 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_copy.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_copy.pass.cpp @@ -117,7 +117,7 @@ int main() assert(c1 == c0); assert(c1.get_allocator() == A(10)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef min_allocator<int> A; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_init.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_init.pass.cpp index e0382a10db492..d4dda02b84130 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_init.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_init.pass.cpp @@ -42,7 +42,7 @@ int main() assert(*i == 10+n); assert(n == 4); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_move.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_move.pass.cpp index 1532b53e7a834..935284831d075 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_move.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_move.pass.cpp @@ -159,7 +159,7 @@ int main() assert(c1.get_allocator() == A(10)); assert(c0.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef MoveOnly T; typedef min_allocator<T> A; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_op_init.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_op_init.pass.cpp index 551908fea1668..3d35916ccacb9 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_op_init.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_op_init.pass.cpp @@ -42,7 +42,7 @@ int main() assert(*i == 10+n); assert(n == 4); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_range.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_range.pass.cpp index 0b348e6920caa..ccefa2df7ce0d 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_range.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_range.pass.cpp @@ -47,7 +47,7 @@ int main() assert(*i == 10+n); assert(n == 4); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_size_value.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_size_value.pass.cpp index ea53e1c37320f..1a1610d37c2fb 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_size_value.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_size_value.pass.cpp @@ -41,7 +41,7 @@ int main() assert(*i == 10); assert(n == 4); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/copy.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/copy.pass.cpp index 2fc53bc3a514b..5240afa82b80d 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/copy.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/copy.pass.cpp @@ -50,7 +50,7 @@ int main() assert(c.get_allocator() == A(-2)); } #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef min_allocator<int> A; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/copy_alloc.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/copy_alloc.pass.cpp index bcc24e1cc68e1..e4b73bb54e9b6 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/copy_alloc.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/copy_alloc.pass.cpp @@ -48,7 +48,7 @@ int main() assert(c == c0); assert(c.get_allocator() == A(9)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef min_allocator<int> A; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/default.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/default.pass.cpp index 38e95fad83961..04c4524cf980a 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/default.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/default.pass.cpp @@ -24,7 +24,7 @@ int main() C c; assert(c.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/default_noexcept.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/default_noexcept.pass.cpp index 5167a065a9ad0..0ec1f80562a8d 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/default_noexcept.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/default_noexcept.pass.cpp @@ -14,9 +14,12 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <forward_list> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -29,14 +32,13 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::forward_list<MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::forward_list<MoveOnly, test_allocator<MoveOnly>> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::forward_list<MoveOnly, other_allocator<MoveOnly>> C; @@ -46,5 +48,4 @@ int main() typedef std::forward_list<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/dtor_noexcept.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/dtor_noexcept.pass.cpp index da41bf4eb1fcc..85d929b4e32e7 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/dtor_noexcept.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/dtor_noexcept.pass.cpp @@ -11,14 +11,14 @@ // ~forward_list() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <forward_list> #include <cassert> #include "MoveOnly.h" #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_alloc { @@ -27,11 +27,8 @@ struct some_alloc ~some_alloc() noexcept(false); }; -#endif - int main() { -#if __has_feature(cxx_noexcept) { typedef std::forward_list<MoveOnly> C; static_assert(std::is_nothrow_destructible<C>::value, ""); @@ -48,5 +45,4 @@ int main() typedef std::forward_list<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/init.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/init.pass.cpp index 5b31c4dad0a0c..c783f60ff4c9d 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/init.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/init.pass.cpp @@ -28,7 +28,7 @@ int main() assert(*i == n); assert(n == 10); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/init_alloc.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/init_alloc.pass.cpp index 750486b829f2f..ba9984f969b50 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/init_alloc.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/init_alloc.pass.cpp @@ -31,7 +31,7 @@ int main() assert(n == 10); assert(c.get_allocator() == A(14)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef min_allocator<T> A; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/move.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/move.pass.cpp index 88ecb75409512..a3e204ec28da6 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/move.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/move.pass.cpp @@ -52,7 +52,7 @@ int main() assert(c0.empty()); assert(c.get_allocator() == A(10)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef MoveOnly T; typedef min_allocator<T> A; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/move_alloc.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/move_alloc.pass.cpp index 3f0e45af1f0bc..6a1afe1334b03 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/move_alloc.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/move_alloc.pass.cpp @@ -52,7 +52,7 @@ int main() assert(!c0.empty()); assert(c.get_allocator() == A(9)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef MoveOnly T; typedef min_allocator<T> A; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.pass.cpp index 28ce2c12b6190..b9a6ef7ab8a85 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/move_assign_noexcept.pass.cpp @@ -16,6 +16,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <forward_list> #include <cassert> @@ -31,7 +33,6 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::forward_list<MoveOnly> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); @@ -48,5 +49,4 @@ int main() typedef std::forward_list<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/move_noexcept.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/move_noexcept.pass.cpp index 7b001ea67b19f..0359133afc9b5 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/move_noexcept.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/move_noexcept.pass.cpp @@ -14,6 +14,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <forward_list> #include <cassert> @@ -29,7 +31,6 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::forward_list<MoveOnly> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); @@ -46,5 +47,4 @@ int main() typedef std::forward_list<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/range.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/range.pass.cpp index 763952439f00f..3c0f2b8403caa 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/range.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/range.pass.cpp @@ -32,7 +32,7 @@ int main() assert(*i == n); assert(n == std::end(t) - std::begin(t)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/range_alloc.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/range_alloc.pass.cpp index d72c3581022d3..96a29d24e89c4 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/range_alloc.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/range_alloc.pass.cpp @@ -36,7 +36,7 @@ int main() assert(n == std::end(t) - std::begin(t)); assert(c.get_allocator() == A(13)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef min_allocator<T> A; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp index e02dcb4bf691c..736d59936aa3f 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp @@ -45,7 +45,7 @@ int main() #endif assert(n == N); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef DefaultOnly T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/size_value.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/size_value.pass.cpp index 05ab98bb205d6..56ce632e0a481 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/size_value.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/size_value.pass.cpp @@ -29,7 +29,7 @@ int main() assert(*i == v); assert(n == N); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.cons/size_value_alloc.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.cons/size_value_alloc.pass.cpp index 1d631ab12ba18..86338a275a555 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.cons/size_value_alloc.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/size_value_alloc.pass.cpp @@ -32,7 +32,7 @@ int main() assert(n == N); assert(c.get_allocator() == A(12)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<int> A; typedef A::value_type T; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.iter/before_begin.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.iter/before_begin.pass.cpp index 083cec2886dab..c6104e73350bf 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.iter/before_begin.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.iter/before_begin.pass.cpp @@ -60,7 +60,7 @@ int main() C::const_iterator i = c.before_begin(); assert(std::distance(i, c.end()) == 11); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.iter/iterators.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.iter/iterators.pass.cpp index 6f3ac548db8b2..925cca4d5e8dc 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.iter/iterators.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.iter/iterators.pass.cpp @@ -71,7 +71,7 @@ int main() C::iterator i; C::const_iterator j; } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; @@ -127,7 +127,7 @@ int main() std::forward_list<int>::const_iterator cii{}; assert ( ii1 == ii2 ); assert ( ii1 == ii4 ); - + assert (!(ii1 != ii2 )); assert ( (ii1 == cii )); diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/clear.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/clear.pass.cpp index 2739b49d8eb22..0e625ac76a02c 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/clear.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/clear.pass.cpp @@ -38,7 +38,7 @@ int main() c.clear(); assert(distance(c.begin(), c.end()) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef NotConstructible T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/emplace_after.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/emplace_after.pass.cpp index e305c5b6ab529..dd8ea88c2c1aa 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/emplace_after.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/emplace_after.pass.cpp @@ -52,7 +52,7 @@ int main() assert(*next(c.begin(), 3) == Emplaceable(2, 3.5)); assert(distance(c.begin(), c.end()) == 4); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef Emplaceable T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/emplace_front.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/emplace_front.pass.cpp index c02337e0562db..18ed69d33f0ba 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/emplace_front.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/emplace_front.pass.cpp @@ -32,7 +32,7 @@ int main() assert(*next(c.begin()) == Emplaceable()); assert(distance(c.begin(), c.end()) == 2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef Emplaceable T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_many.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_many.pass.cpp index bd9b15300efac..df859c69a117b 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_many.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_many.pass.cpp @@ -84,7 +84,7 @@ int main() assert(i == c.end()); assert(distance(c.begin(), c.end()) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_one.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_one.pass.cpp index 4f51498bc6518..bf6a88a65406c 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_one.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_one.pass.cpp @@ -55,7 +55,7 @@ int main() assert(i == c.end()); assert(distance(c.begin(), c.end()) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_const.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_const.pass.cpp index ec650b6957278..82dca739410ff 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_const.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_const.pass.cpp @@ -50,7 +50,7 @@ int main() assert(*next(c.begin(), 3) == 2); assert(distance(c.begin(), c.end()) == 4); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_init.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_init.pass.cpp index 4d30181998095..15e1a08b08bf1 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_init.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_init.pass.cpp @@ -44,7 +44,7 @@ int main() assert(*next(c.begin(), 3) == 1); assert(*next(c.begin(), 4) == 2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_range.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_range.pass.cpp index 103475f1edabe..a41f8dbbfb2ba 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_range.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_range.pass.cpp @@ -48,7 +48,7 @@ int main() assert(*next(c.begin(), 3) == 1); assert(*next(c.begin(), 4) == 2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_rv.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_rv.pass.cpp index f7f376caa0901..2e21cc79d2699 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_rv.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_rv.pass.cpp @@ -52,7 +52,7 @@ int main() assert(*next(c.begin(), 3) == 2); assert(distance(c.begin(), c.end()) == 4); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef MoveOnly T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_size_value.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_size_value.pass.cpp index b2da2ecd3bbd4..f4b7e344112a0 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_size_value.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_size_value.pass.cpp @@ -43,7 +43,7 @@ int main() assert(*next(c.begin(), 3) == 3); assert(*next(c.begin(), 4) == 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/pop_front.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/pop_front.pass.cpp index 7f14e54a2e6f0..d831ceb289189 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/pop_front.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/pop_front.pass.cpp @@ -46,7 +46,7 @@ int main() assert(distance(c.begin(), c.end()) == 0); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/push_front_const.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/push_front_const.pass.cpp index 85958afc1ce39..4b55a0b1d808e 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/push_front_const.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/push_front_const.pass.cpp @@ -30,7 +30,7 @@ int main() assert(*next(c.begin()) == 1); assert(distance(c.begin(), c.end()) == 2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/push_front_rv.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/push_front_rv.pass.cpp index d7c9d758aa032..dfcd2cf90ebcd 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/push_front_rv.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/push_front_rv.pass.cpp @@ -32,7 +32,7 @@ int main() assert(*next(c.begin()) == 1); assert(distance(c.begin(), c.end()) == 2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef MoveOnly T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size.pass.cpp index ef7ef82626dcd..6337cd7797221 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size.pass.cpp @@ -64,7 +64,7 @@ int main() assert(*next(c.begin(), 4) == 0); assert(*next(c.begin(), 5) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef DefaultOnly T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp index d4bd6b4e01115..356e0d657c351 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp @@ -14,9 +14,14 @@ #include <forward_list> #include <cassert> +#include "test_macros.h" #include "DefaultOnly.h" #include "min_allocator.h" +#if TEST_STD_VER >= 11 +#include "container_test_types.h" +#endif + int main() { { @@ -49,7 +54,7 @@ int main() assert(*next(c.begin(), 4) == 10); assert(*next(c.begin(), 5) == 10); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; @@ -80,5 +85,19 @@ int main() assert(*next(c.begin(), 4) == 10); assert(*next(c.begin(), 5) == 10); } + { + // Test that the allocator's construct method is being used to + // construct the new elements and that it's called exactly N times. + typedef int T; + typedef std::forward_list<int, ContainerTestAllocator<int, int>> Container; + ConstructController* cc = getConstructController(); + cc->reset(); + { + Container c; + cc->expect<int const&>(6); + c.resize(6, 42); + assert(!cc->unchecked()); + } + } #endif } diff --git a/test/std/containers/sequences/forwardlist/forwardlist.ops/merge.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.ops/merge.pass.cpp index 3b6f853c84cdb..a67dd1a4b120f 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.ops/merge.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.ops/merge.pass.cpp @@ -31,7 +31,7 @@ int main() C c3(std::begin(t3), std::end(t3)); assert(c1 == c3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_pred.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_pred.pass.cpp index 7e873bdddd094..6b4e323bd02df 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_pred.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_pred.pass.cpp @@ -32,7 +32,7 @@ int main() C c3(std::begin(t3), std::end(t3)); assert(c1 == c3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.ops/remove.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.ops/remove.pass.cpp index 18d4cae8cc61b..b7607e190bbf6 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.ops/remove.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.ops/remove.pass.cpp @@ -103,7 +103,7 @@ int main() } assert ( it == c.end ()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.ops/remove_if.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.ops/remove_if.pass.cpp index ed408fbd685c1..ef6f6a0f1887d 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.ops/remove_if.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.ops/remove_if.pass.cpp @@ -88,7 +88,7 @@ int main() assert(c1 == c2); assert(cp.count() == std::distance(std::begin(t1), std::end(t1))); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef unary_counting_predicate<bool(*)(T), T> Predicate; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.ops/reverse.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.ops/reverse.pass.cpp index 9bf0d03a8855a..2876f65d0630d 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.ops/reverse.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.ops/reverse.pass.cpp @@ -35,7 +35,7 @@ int main() { for (int i = 0; i < 10; ++i) test<std::forward_list<int> >(i); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 for (int i = 0; i < 10; ++i) test<std::forward_list<int, min_allocator<int>> >(i); #endif diff --git a/test/std/containers/sequences/forwardlist/forwardlist.ops/sort.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.ops/sort.pass.cpp index 06e40c595ecb4..65512e317cea0 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.ops/sort.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.ops/sort.pass.cpp @@ -40,7 +40,7 @@ int main() { for (int i = 0; i < 40; ++i) test<std::forward_list<int> >(i); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 for (int i = 0; i < 40; ++i) test<std::forward_list<int, min_allocator<int>> >(i); #endif diff --git a/test/std/containers/sequences/forwardlist/forwardlist.ops/sort_pred.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.ops/sort_pred.pass.cpp index 8b6ca39b2aab6..6e5cce39e67d2 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.ops/sort_pred.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.ops/sort_pred.pass.cpp @@ -41,7 +41,7 @@ int main() { for (int i = 0; i < 40; ++i) test<std::forward_list<int> >(i); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 for (int i = 0; i < 40; ++i) test<std::forward_list<int, min_allocator<int>> >(i); #endif diff --git a/test/std/containers/sequences/forwardlist/forwardlist.ops/splice_after_flist.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.ops/splice_after_flist.pass.cpp index 51da651970cd3..c8d4e2d34f1e0 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.ops/splice_after_flist.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.ops/splice_after_flist.pass.cpp @@ -55,7 +55,7 @@ int main() } } } -#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.ops/splice_after_range.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.ops/splice_after_range.pass.cpp index 90a1599596322..006869d6db693 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.ops/splice_after_range.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.ops/splice_after_range.pass.cpp @@ -121,7 +121,7 @@ int main() } } } -#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.ops/unique.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.ops/unique.pass.cpp index 25db6e64b8a99..e79abb6b6519a 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.ops/unique.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.ops/unique.pass.cpp @@ -67,7 +67,7 @@ int main() c1.unique(); assert(c1 == c2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.ops/unique_pred.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.ops/unique_pred.pass.cpp index b7dce20b7092e..11228afe83e60 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.ops/unique_pred.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.ops/unique_pred.pass.cpp @@ -72,7 +72,7 @@ int main() c1.unique(g); assert(c1 == c2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.spec/member_swap.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.spec/member_swap.pass.cpp index 2b2be7b6c222c..e7a8d048f6f6f 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.spec/member_swap.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.spec/member_swap.pass.cpp @@ -176,7 +176,7 @@ int main() assert(distance(c2.begin(), c2.end()) == 0); assert(c2.get_allocator() == A(1)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef min_allocator<T> A; diff --git a/test/std/containers/sequences/forwardlist/forwardlist.spec/non_member_swap.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.spec/non_member_swap.pass.cpp index d6ba5a47cbe60..983d8140571b1 100644 --- a/test/std/containers/sequences/forwardlist/forwardlist.spec/non_member_swap.pass.cpp +++ b/test/std/containers/sequences/forwardlist/forwardlist.spec/non_member_swap.pass.cpp @@ -177,7 +177,7 @@ int main() assert(distance(c2.begin(), c2.end()) == 0); assert(c2.get_allocator() == A(1)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef min_allocator<T> A; 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 cbe8142eeb4b0..5f8cf95aa7373 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <forward_list> // void swap(forward_list& c) @@ -21,6 +23,7 @@ #include <forward_list> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -28,7 +31,7 @@ template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -40,7 +43,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -51,7 +54,6 @@ struct some_alloc2 int main() { -#if __has_feature(cxx_noexcept) { typedef std::forward_list<MoveOnly> C; C c1, c2; @@ -85,6 +87,4 @@ int main() static_assert( noexcept(swap(c1, c2)), ""); } #endif - -#endif } diff --git a/test/std/containers/sequences/forwardlist/incomplete.pass.cpp b/test/std/containers/sequences/forwardlist/incomplete.pass.cpp new file mode 100644 index 0000000000000..df273449eac15 --- /dev/null +++ b/test/std/containers/sequences/forwardlist/incomplete.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. +// +//===----------------------------------------------------------------------===// + +// <forward_list> + +// forward_list() +// forward_list::iterator() +// forward_list::const_iterator() + +#include <forward_list> +#include <cassert> + +#include "test_macros.h" +#include "min_allocator.h" + +struct A { + std::forward_list<A> d; + std::forward_list<A>::iterator it; + std::forward_list<A>::const_iterator it2; +}; + +#if TEST_STD_VER >= 11 +struct B { + typedef std::forward_list<B, min_allocator<B>> FList; + FList d; + FList::iterator it; + FList::const_iterator it2; +}; +#endif + +int main() +{ + { + A a; + assert(a.d.empty()); + a.it = a.d.begin(); + a.it2 = a.d.cbefore_begin(); + } +#if TEST_STD_VER >= 11 + { + B b; + assert(b.d.empty()); + b.it = b.d.begin(); + b.it2 = b.d.cbefore_begin(); + } +#endif +} diff --git a/test/std/containers/sequences/forwardlist/max_size.pass.cpp b/test/std/containers/sequences/forwardlist/max_size.pass.cpp index be7ebaf44b03e..a7f39bf90fb83 100644 --- a/test/std/containers/sequences/forwardlist/max_size.pass.cpp +++ b/test/std/containers/sequences/forwardlist/max_size.pass.cpp @@ -24,7 +24,7 @@ int main() C c; assert(c.max_size() > 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::forward_list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/forwardlist/types.pass.cpp b/test/std/containers/sequences/forwardlist/types.pass.cpp index a1f8862debbe2..5ed7e34b9202c 100644 --- a/test/std/containers/sequences/forwardlist/types.pass.cpp +++ b/test/std/containers/sequences/forwardlist/types.pass.cpp @@ -44,8 +44,15 @@ int main() static_assert((std::is_same<C::const_pointer, const char*>::value), ""); static_assert((std::is_same<C::size_type, std::size_t>::value), ""); static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), ""); + + static_assert((std::is_signed<typename C::difference_type>::value), ""); + static_assert((std::is_unsigned<typename C::size_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::iterator>::difference_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::const_iterator>::difference_type>::value), ""); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::forward_list<char, min_allocator<char>> C; static_assert((std::is_same<C::value_type, char>::value), ""); @@ -57,6 +64,13 @@ int main() // min_allocator doesn't have a size_type, so one gets synthesized static_assert((std::is_same<C::size_type, std::make_unsigned<C::difference_type>::type>::value), ""); static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), ""); + + static_assert((std::is_signed<typename C::difference_type>::value), ""); + static_assert((std::is_unsigned<typename C::size_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::iterator>::difference_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::const_iterator>::difference_type>::value), ""); } #endif } diff --git a/test/std/containers/sequences/list/iterators.pass.cpp b/test/std/containers/sequences/list/iterators.pass.cpp index a33ee3ecd2db6..fe0ac07996879 100644 --- a/test/std/containers/sequences/list/iterators.pass.cpp +++ b/test/std/containers/sequences/list/iterators.pass.cpp @@ -77,7 +77,7 @@ int main() C::iterator i; C::const_iterator j; } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::list<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/list/list.capacity/resize_size.pass.cpp b/test/std/containers/sequences/list/list.capacity/resize_size.pass.cpp index 14629b173a6c6..df934699d5ade 100644 --- a/test/std/containers/sequences/list/list.capacity/resize_size.pass.cpp +++ b/test/std/containers/sequences/list/list.capacity/resize_size.pass.cpp @@ -47,7 +47,7 @@ int main() assert(std::distance(l.begin(), l.end()) == 20); } #endif // __LIBCPP_MOVE -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> l(5, 2); l.resize(2); diff --git a/test/std/containers/sequences/list/list.capacity/resize_size_value.pass.cpp b/test/std/containers/sequences/list/list.capacity/resize_size_value.pass.cpp index 2738ffbbefdd6..4609ef9868357 100644 --- a/test/std/containers/sequences/list/list.capacity/resize_size_value.pass.cpp +++ b/test/std/containers/sequences/list/list.capacity/resize_size_value.pass.cpp @@ -33,7 +33,7 @@ int main() assert(l.front() == 2); assert(l.back() == 3.5); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<double, min_allocator<double>> l(5, 2); l.resize(2, 3.5); diff --git a/test/std/containers/sequences/list/list.cons/assign_copy.pass.cpp b/test/std/containers/sequences/list/list.cons/assign_copy.pass.cpp index b851eb9dc5a01..7c8cee2a5581f 100644 --- a/test/std/containers/sequences/list/list.cons/assign_copy.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/assign_copy.pass.cpp @@ -32,7 +32,7 @@ int main() assert(l2 == l); assert(l2.get_allocator() == other_allocator<int>(5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int> > l(3, 2, min_allocator<int>()); std::list<int, min_allocator<int> > l2(l, min_allocator<int>()); diff --git a/test/std/containers/sequences/list/list.cons/assign_initializer_list.pass.cpp b/test/std/containers/sequences/list/list.cons/assign_initializer_list.pass.cpp index 24bd140c4e4f8..9b2c6d68cbe54 100644 --- a/test/std/containers/sequences/list/list.cons/assign_initializer_list.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/assign_initializer_list.pass.cpp @@ -29,7 +29,7 @@ int main() assert(*i++ == 5); assert(*i++ == 6); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> d; d.assign({3, 4, 5, 6}); diff --git a/test/std/containers/sequences/list/list.cons/assign_move.pass.cpp b/test/std/containers/sequences/list/list.cons/assign_move.pass.cpp index 0fd586f84af73..2f863c6169fc6 100644 --- a/test/std/containers/sequences/list/list.cons/assign_move.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/assign_move.pass.cpp @@ -62,7 +62,7 @@ int main() assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{}); std::list<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{}); diff --git a/test/std/containers/sequences/list/list.cons/copy.pass.cpp b/test/std/containers/sequences/list/list.cons/copy.pass.cpp index 530690a925d44..a6abd1f3c30b6 100644 --- a/test/std/containers/sequences/list/list.cons/copy.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/copy.pass.cpp @@ -38,7 +38,7 @@ int main() assert(l2.get_allocator() == other_allocator<int>(-2)); } #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> l(3, 2); std::list<int, min_allocator<int>> l2 = l; diff --git a/test/std/containers/sequences/list/list.cons/copy_alloc.pass.cpp b/test/std/containers/sequences/list/list.cons/copy_alloc.pass.cpp index 99fe9f115f949..a164298f4faee 100644 --- a/test/std/containers/sequences/list/list.cons/copy_alloc.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/copy_alloc.pass.cpp @@ -31,7 +31,7 @@ int main() assert(l2 == l); assert(l2.get_allocator() == other_allocator<int>(3)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int> > l(3, 2, min_allocator<int>()); std::list<int, min_allocator<int> > l2(l, min_allocator<int>()); diff --git a/test/std/containers/sequences/list/list.cons/default.pass.cpp b/test/std/containers/sequences/list/list.cons/default.pass.cpp index c05bd74ca79e6..3c1c2ef166d43 100644 --- a/test/std/containers/sequences/list/list.cons/default.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/default.pass.cpp @@ -33,7 +33,7 @@ int main() assert(l.size() == 0); assert(std::distance(l.begin(), l.end()) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> l; assert(l.size() == 0); diff --git a/test/std/containers/sequences/list/list.cons/default_noexcept.pass.cpp b/test/std/containers/sequences/list/list.cons/default_noexcept.pass.cpp index 2455fb39a79af..6f76d8c568826 100644 --- a/test/std/containers/sequences/list/list.cons/default_noexcept.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/default_noexcept.pass.cpp @@ -14,9 +14,12 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <list> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -29,14 +32,13 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::list<MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::list<MoveOnly, test_allocator<MoveOnly>> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::list<MoveOnly, other_allocator<MoveOnly>> C; @@ -46,5 +48,4 @@ int main() typedef std::list<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp b/test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp index 9d9946b68966a..4b88580e12cac 100644 --- a/test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp @@ -33,7 +33,7 @@ int main() assert(l.size() == 0); assert(std::distance(l.begin(), l.end()) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> l; assert(l.size() == 0); diff --git a/test/std/containers/sequences/list/list.cons/dtor_noexcept.pass.cpp b/test/std/containers/sequences/list/list.cons/dtor_noexcept.pass.cpp index ca7ade6d19cb1..3d11f13358b51 100644 --- a/test/std/containers/sequences/list/list.cons/dtor_noexcept.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/dtor_noexcept.pass.cpp @@ -11,14 +11,14 @@ // ~list() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <list> #include <cassert> #include "MoveOnly.h" #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_alloc { @@ -27,11 +27,8 @@ struct some_alloc ~some_alloc() noexcept(false); }; -#endif - int main() { -#if __has_feature(cxx_noexcept) { typedef std::list<MoveOnly> C; static_assert(std::is_nothrow_destructible<C>::value, ""); @@ -48,5 +45,4 @@ int main() typedef std::list<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/list/list.cons/initializer_list.pass.cpp b/test/std/containers/sequences/list/list.cons/initializer_list.pass.cpp index 3307017989eb4..40413203bdfc4 100644 --- a/test/std/containers/sequences/list/list.cons/initializer_list.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/initializer_list.pass.cpp @@ -28,7 +28,7 @@ int main() assert(*i++ == 5); assert(*i++ == 6); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> d = {3, 4, 5, 6}; assert(d.size() == 4); diff --git a/test/std/containers/sequences/list/list.cons/initializer_list_alloc.pass.cpp b/test/std/containers/sequences/list/list.cons/initializer_list_alloc.pass.cpp index 4a85e378c1ce0..72add79f6670d 100644 --- a/test/std/containers/sequences/list/list.cons/initializer_list_alloc.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/initializer_list_alloc.pass.cpp @@ -30,7 +30,7 @@ int main() assert(*i++ == 5); assert(*i++ == 6); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> d({3, 4, 5, 6}, min_allocator<int>()); assert(d.get_allocator() == min_allocator<int>()); diff --git a/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp b/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp index 09eae8ab43c18..0dd71d70f85b1 100644 --- a/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp @@ -51,7 +51,7 @@ int main() for (std::list<int>::const_iterator i = l.begin(), e = l.end(); i != e; ++i, ++j) assert(*i == j); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a[] = {0, 1, 2, 3}; std::list<int, min_allocator<int>> l(input_iterator<const int*>(a), diff --git a/test/std/containers/sequences/list/list.cons/move.pass.cpp b/test/std/containers/sequences/list/list.cons/move.pass.cpp index 54209a55f7e22..1049b1b039829 100644 --- a/test/std/containers/sequences/list/list.cons/move.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/move.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <list> // list(list&& c); @@ -19,7 +21,6 @@ int main() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { std::list<MoveOnly, test_allocator<MoveOnly> > l(test_allocator<MoveOnly>(5)); std::list<MoveOnly, test_allocator<MoveOnly> > lo(test_allocator<MoveOnly>(5)); @@ -46,7 +47,6 @@ int main() assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); } -#if __cplusplus >= 201103L { std::list<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{}); std::list<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{}); @@ -60,15 +60,4 @@ int main() assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); } -#endif -#if _LIBCPP_DEBUG >= 1 - { - std::list<int> l1 = {1, 2, 3}; - std::list<int>::iterator i = l1.begin(); - std::list<int> l2 = std::move(l1); - assert(*l2.erase(i) == 2); - assert(l2.size() == 2); - } -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/std/containers/sequences/list/list.cons/move_alloc.pass.cpp b/test/std/containers/sequences/list/list.cons/move_alloc.pass.cpp index 8f82702b296f4..9f8a536b33c5a 100644 --- a/test/std/containers/sequences/list/list.cons/move_alloc.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/move_alloc.pass.cpp @@ -59,7 +59,7 @@ int main() assert(!l.empty()); assert(l2.get_allocator() == other_allocator<MoveOnly>(4)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{}); std::list<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{}); diff --git a/test/std/containers/sequences/list/list.cons/move_assign_noexcept.pass.cpp b/test/std/containers/sequences/list/list.cons/move_assign_noexcept.pass.cpp index 280d93d486e6d..d4f8fde2c8ff0 100644 --- a/test/std/containers/sequences/list/list.cons/move_assign_noexcept.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/move_assign_noexcept.pass.cpp @@ -16,6 +16,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <list> #include <cassert> @@ -31,7 +33,6 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::list<MoveOnly> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); @@ -48,5 +49,4 @@ int main() typedef std::list<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/list/list.cons/move_noexcept.pass.cpp b/test/std/containers/sequences/list/list.cons/move_noexcept.pass.cpp index e436a29f5d472..da2b6a36cef5d 100644 --- a/test/std/containers/sequences/list/list.cons/move_noexcept.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/move_noexcept.pass.cpp @@ -14,6 +14,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <list> #include <cassert> @@ -29,7 +31,6 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::list<MoveOnly> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); @@ -46,5 +47,4 @@ int main() typedef std::list<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/list/list.cons/op_equal_initializer_list.pass.cpp b/test/std/containers/sequences/list/list.cons/op_equal_initializer_list.pass.cpp index 7b7b8a327b886..1097bdab21989 100644 --- a/test/std/containers/sequences/list/list.cons/op_equal_initializer_list.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/op_equal_initializer_list.pass.cpp @@ -28,7 +28,7 @@ int main() assert(*i++ == 5); assert(*i++ == 6); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> d; d = {3, 4, 5, 6}; diff --git a/test/std/containers/sequences/list/list.cons/size_type.pass.cpp b/test/std/containers/sequences/list/list.cons/size_type.pass.cpp index 75b93a3dfb6b6..07b4f14dc3a22 100644 --- a/test/std/containers/sequences/list/list.cons/size_type.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/size_type.pass.cpp @@ -80,7 +80,7 @@ int main() assert(std::distance(l.begin(), l.end()) == 3); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> l(3); assert(l.size() == 3); diff --git a/test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp b/test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp index 12da86da0a413..ac7b18ea4990e 100644 --- a/test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp @@ -52,7 +52,7 @@ int main() ++i; assert(*i == 2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> l(3, 2); assert(l.size() == 3); diff --git a/test/std/containers/sequences/list/list.modifiers/clear.pass.cpp b/test/std/containers/sequences/list/list.modifiers/clear.pass.cpp index 38696b6eb503b..5d8c41fa19764 100644 --- a/test/std/containers/sequences/list/list.modifiers/clear.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/clear.pass.cpp @@ -24,7 +24,7 @@ int main() c.clear(); assert(c.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a[] = {1, 2, 3}; std::list<int, min_allocator<int>> c(a, a+3); diff --git a/test/std/containers/sequences/list/list.modifiers/emplace.pass.cpp b/test/std/containers/sequences/list/list.modifiers/emplace.pass.cpp index 6476d1d6c6aea..e8d46941252e9 100644 --- a/test/std/containers/sequences/list/list.modifiers/emplace.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/emplace.pass.cpp @@ -7,17 +7,17 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <list> // template <class... Args> void emplace(const_iterator p, Args&&... args); -#if _LIBCPP_DEBUG >= 1 -#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) -#endif #include <list> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" class A @@ -37,7 +37,6 @@ public: int main() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { std::list<A> c; c.emplace(c.cbegin(), 2, 3.5); @@ -51,17 +50,6 @@ int main() assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); } -#if _LIBCPP_DEBUG >= 1 - { - std::list<A> c1; - std::list<A> c2; - std::list<A>::iterator i = c1.emplace(c2.cbegin(), 2, 3.5); - assert(false); - } -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { std::list<A, min_allocator<A>> c; c.emplace(c.cbegin(), 2, 3.5); @@ -75,14 +63,5 @@ int main() assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); } -#if _LIBCPP_DEBUG >= 1 - { - std::list<A, min_allocator<A>> c1; - std::list<A, min_allocator<A>> c2; - std::list<A, min_allocator<A>>::iterator i = c1.emplace(c2.cbegin(), 2, 3.5); - assert(false); - } -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#endif + } diff --git a/test/std/containers/sequences/list/list.modifiers/emplace_back.pass.cpp b/test/std/containers/sequences/list/list.modifiers/emplace_back.pass.cpp index 5983efc59ad1b..2ff01f1676f26 100644 --- a/test/std/containers/sequences/list/list.modifiers/emplace_back.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/emplace_back.pass.cpp @@ -47,7 +47,7 @@ int main() assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<A, min_allocator<A>> c; c.emplace_back(2, 3.5); diff --git a/test/std/containers/sequences/list/list.modifiers/emplace_front.pass.cpp b/test/std/containers/sequences/list/list.modifiers/emplace_front.pass.cpp index e2e68e331381f..8a3df46a31e26 100644 --- a/test/std/containers/sequences/list/list.modifiers/emplace_front.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/emplace_front.pass.cpp @@ -47,7 +47,7 @@ int main() assert(c.back().geti() == 2); assert(c.back().getd() == 3.5); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<A, min_allocator<A>> c; c.emplace_front(2, 3.5); diff --git a/test/std/containers/sequences/list/list.modifiers/erase_iter.pass.cpp b/test/std/containers/sequences/list/list.modifiers/erase_iter.pass.cpp index c1cc900436706..0924fdb848797 100644 --- a/test/std/containers/sequences/list/list.modifiers/erase_iter.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/erase_iter.pass.cpp @@ -39,7 +39,7 @@ int main() assert(l1.size() == 0); assert(distance(l1.begin(), l1.end()) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 2, 3}; std::list<int, min_allocator<int>> l1(a1, a1+3); diff --git a/test/std/containers/sequences/list/list.modifiers/erase_iter_iter.pass.cpp b/test/std/containers/sequences/list/list.modifiers/erase_iter_iter.pass.cpp index bd3f66b4116a0..06b4f0cc654f6 100644 --- a/test/std/containers/sequences/list/list.modifiers/erase_iter_iter.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/erase_iter_iter.pass.cpp @@ -49,7 +49,7 @@ int main() assert(distance(l1.cbegin(), l1.cend()) == 0); assert(i == l1.begin()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> l1(a1, a1+3); std::list<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), l1.cbegin()); diff --git a/test/std/containers/sequences/list/list.modifiers/insert_iter_initializer_list.pass.cpp b/test/std/containers/sequences/list/list.modifiers/insert_iter_initializer_list.pass.cpp index a82a2696e82ac..91845e564b023 100644 --- a/test/std/containers/sequences/list/list.modifiers/insert_iter_initializer_list.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/insert_iter_initializer_list.pass.cpp @@ -40,7 +40,7 @@ int main() assert(*i++ == 1); assert(*i++ == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> d(10, 1); std::list<int, min_allocator<int>>::iterator i = d.insert(next(d.cbegin(), 2), {3, 4, 5, 6}); 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 736b9baae7469..18460a65743cf 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 @@ -7,117 +7,25 @@ // //===----------------------------------------------------------------------===// -// XFAIL: libcpp-no-exceptions // <list> // template <InputIterator Iter> // iterator insert(const_iterator position, Iter first, Iter last); -// UNSUPPORTED: sanitizer-new-delete - -#if _LIBCPP_DEBUG >= 1 -#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) -#endif - #include <list> #include <cstdlib> #include <cassert> + +#include "test_macros.h" #include "test_iterators.h" #include "min_allocator.h" +#include "count_new.hpp" -int throw_next = 0xFFFF; -int count = 0; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - if (throw_next == 0) - throw std::bad_alloc(); - --throw_next; - ++count; - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - --count; - std::free(p); -} - -int main() -{ - { - int a1[] = {1, 2, 3}; - std::list<int> l1; - std::list<int>::iterator i = l1.insert(l1.begin(), a1, a1+3); - assert(i == l1.begin()); - assert(l1.size() == 3); - assert(distance(l1.begin(), l1.end()) == 3); - i = l1.begin(); - assert(*i == 1); - ++i; - assert(*i == 2); - ++i; - assert(*i == 3); - int a2[] = {4, 5, 6}; - i = l1.insert(i, a2, a2+3); - assert(*i == 4); - assert(l1.size() == 6); - assert(distance(l1.begin(), l1.end()) == 6); - i = l1.begin(); - assert(*i == 1); - ++i; - assert(*i == 2); - ++i; - assert(*i == 4); - ++i; - assert(*i == 5); - ++i; - assert(*i == 6); - ++i; - assert(*i == 3); - throw_next = 2; - int save_count = count; - try - { - i = l1.insert(i, a2, a2+3); - assert(false); - } - catch (...) - { - } - assert(save_count == count); - assert(l1.size() == 6); - assert(distance(l1.begin(), l1.end()) == 6); - i = l1.begin(); - assert(*i == 1); - ++i; - assert(*i == 2); - ++i; - assert(*i == 4); - ++i; - assert(*i == 5); - ++i; - assert(*i == 6); - ++i; - assert(*i == 3); - } - throw_next = 0xFFFF; -#if _LIBCPP_DEBUG >= 1 - { - std::list<int> v(100); - std::list<int> v2(100); - int a[] = {1, 2, 3, 4, 5}; - const int N = sizeof(a)/sizeof(a[0]); - std::list<int>::iterator i = v.insert(next(v2.cbegin(), 10), input_iterator<const int*>(a), - input_iterator<const int*>(a+N)); - assert(false); - } -#endif -#if __cplusplus >= 201103L - { +template <class List> +void test() { int a1[] = {1, 2, 3}; - std::list<int, min_allocator<int>> l1; - std::list<int, min_allocator<int>>::iterator i = l1.insert(l1.begin(), a1, a1+3); + List l1; + typename List::iterator i = l1.insert(l1.begin(), a1, a1+3); assert(i == l1.begin()); assert(l1.size() == 3); assert(distance(l1.begin(), l1.end()) == 3); @@ -144,8 +52,10 @@ int main() assert(*i == 6); ++i; assert(*i == 3); - throw_next = 2; - int save_count = count; + +#if !defined(TEST_HAS_NO_EXCEPTIONS) && !defined(DISABLE_NEW_COUNT) + globalMemCounter.throw_after = 2; + int save_count = globalMemCounter.outstanding_new; try { i = l1.insert(i, a2, a2+3); @@ -154,7 +64,7 @@ int main() catch (...) { } - assert(save_count == count); + assert(globalMemCounter.checkOutstandingNewEq(save_count)); assert(l1.size() == 6); assert(distance(l1.begin(), l1.end()) == 6); i = l1.begin(); @@ -169,18 +79,13 @@ int main() assert(*i == 6); ++i; assert(*i == 3); - } -#if _LIBCPP_DEBUG >= 1 - { - throw_next = 0xFFFF; - std::list<int, min_allocator<int>> v(100); - std::list<int, min_allocator<int>> v2(100); - int a[] = {1, 2, 3, 4, 5}; - const int N = sizeof(a)/sizeof(a[0]); - std::list<int, min_allocator<int>>::iterator i = v.insert(next(v2.cbegin(), 10), input_iterator<const int*>(a), - input_iterator<const int*>(a+N)); - assert(false); - } #endif +} + +int main() +{ + test<std::list<int> >(); +#if TEST_STD_VER >= 11 + test<std::list<int, min_allocator<int>>>(); #endif } diff --git a/test/std/containers/sequences/list/list.modifiers/insert_iter_rvalue.pass.cpp b/test/std/containers/sequences/list/list.modifiers/insert_iter_rvalue.pass.cpp index 3d5dec299b952..5d579fcd202ee 100644 --- a/test/std/containers/sequences/list/list.modifiers/insert_iter_rvalue.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/insert_iter_rvalue.pass.cpp @@ -7,14 +7,12 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <list> // iterator insert(const_iterator position, value_type&& x); -#if _LIBCPP_DEBUG >= 1 -#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) -#endif - #include <list> #include <cassert> @@ -23,7 +21,6 @@ int main() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { std::list<MoveOnly> l1; l1.insert(l1.cend(), MoveOnly(1)); @@ -34,17 +31,6 @@ int main() assert(l1.front() == MoveOnly(2)); assert(l1.back() == MoveOnly(1)); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if _LIBCPP_DEBUG >= 1 - { - std::list<int> v1(3); - std::list<int> v2(3); - v1.insert(v2.begin(), 4); - assert(false); - } -#endif -#if __cplusplus >= 201103L -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { std::list<MoveOnly, min_allocator<MoveOnly>> l1; l1.insert(l1.cend(), MoveOnly(1)); @@ -55,14 +41,4 @@ int main() assert(l1.front() == MoveOnly(2)); assert(l1.back() == MoveOnly(1)); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if _LIBCPP_DEBUG >= 1 - { - std::list<int, min_allocator<int>> v1(3); - std::list<int, min_allocator<int>> v2(3); - v1.insert(v2.begin(), 4); - assert(false); - } -#endif -#endif } 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 c0f6ed198751f..d85c1f4b99873 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 @@ -14,75 +14,23 @@ // UNSUPPORTED: sanitizer-new-delete -#if _LIBCPP_DEBUG >= 1 -#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) -#endif - #include <list> #include <cstdlib> #include <cassert> #include "min_allocator.h" +#include "count_new.hpp" -int throw_next = 0xFFFF; -int count = 0; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - if (throw_next == 0) - throw std::bad_alloc(); - --throw_next; - ++count; - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - --count; - std::free(p); -} - -int main() -{ - { - int a1[] = {1, 2, 3}; - int a2[] = {1, 4, 4, 4, 4, 4, 2, 3}; - std::list<int> l1(a1, a1+3); - std::list<int>::iterator i = l1.insert(next(l1.cbegin()), 5, 4); - assert(i == next(l1.begin())); - assert(l1 == std::list<int>(a2, a2+8)); - throw_next = 4; - int save_count = count; - try - { - i = l1.insert(i, 5, 5); - assert(false); - } - catch (...) - { - } - throw_next = 0xFFFF; - assert(save_count == count); - assert(l1 == std::list<int>(a2, a2+8)); - } -#if _LIBCPP_DEBUG >= 1 - { - std::list<int> c1(100); - std::list<int> c2; - std::list<int>::iterator i = c1.insert(next(c2.cbegin(), 10), 5, 1); - assert(false); - } -#endif -#if __cplusplus >= 201103L - { +template <class List> +void test() { int a1[] = {1, 2, 3}; int a2[] = {1, 4, 4, 4, 4, 4, 2, 3}; - std::list<int, min_allocator<int>> l1(a1, a1+3); - std::list<int, min_allocator<int>>::iterator i = l1.insert(next(l1.cbegin()), 5, 4); + List l1(a1, a1+3); + typename List::iterator i = l1.insert(next(l1.cbegin()), 5, 4); assert(i == next(l1.begin())); - assert((l1 == std::list<int, min_allocator<int>>(a2, a2+8))); - throw_next = 4; - int save_count = count; + assert(l1 == List(a2, a2+8)); + globalMemCounter.throw_after = 4; + int save_count = globalMemCounter.outstanding_new; try { i = l1.insert(i, 5, 5); @@ -91,17 +39,14 @@ int main() catch (...) { } - throw_next = 0xFFFF; - assert(save_count == count); - assert((l1 == std::list<int, min_allocator<int>>(a2, a2+8))); - } -#if _LIBCPP_DEBUG >= 1 - { - std::list<int, min_allocator<int>> c1(100); - std::list<int, min_allocator<int>> c2; - std::list<int, min_allocator<int>>::iterator i = c1.insert(next(c2.cbegin(), 10), 5, 1); - assert(false); - } -#endif + assert(globalMemCounter.checkOutstandingNewEq(save_count)); + assert(l1 == List(a2, a2+8)); +} + +int main() +{ + test<std::list<int> >(); +#if TEST_STD_VER >= 11 + test<std::list<int, min_allocator<int>>>(); #endif } 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 1aacb63e4a709..87a033be64e9f 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 @@ -7,87 +7,33 @@ // //===----------------------------------------------------------------------===// -// XFAIL: libcpp-no-exceptions // <list> // iterator insert(const_iterator position, const value_type& x); -// UNSUPPORTED: sanitizer-new-delete - -#if _LIBCPP_DEBUG >= 1 -#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) -#endif - #include <list> #include <cstdlib> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" +#include "count_new.hpp" -int throw_next = 0xFFFF; -int count = 0; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - if (throw_next == 0) - throw std::bad_alloc(); - --throw_next; - ++count; - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - --count; - std::free(p); -} - -int main() +template <class List> +void test() { - { - int a1[] = {1, 2, 3}; - int a2[] = {1, 4, 2, 3}; - std::list<int> l1(a1, a1+3); - std::list<int>::iterator i = l1.insert(next(l1.cbegin()), 4); - assert(i == next(l1.begin())); - assert(l1.size() == 4); - assert(distance(l1.begin(), l1.end()) == 4); - assert(l1 == std::list<int>(a2, a2+4)); - throw_next = 0; - int save_count = count; - try - { - i = l1.insert(i, 5); - assert(false); - } - catch (...) - { - } - throw_next = 0xFFFF; - assert(save_count == count); - assert(l1 == std::list<int>(a2, a2+4)); - } -#if _LIBCPP_DEBUG >= 1 - { - std::list<int> v1(3); - std::list<int> v2(3); - int i = 4; - v1.insert(v2.begin(), i); - assert(false); - } -#endif -#if __cplusplus >= 201103L - { int a1[] = {1, 2, 3}; int a2[] = {1, 4, 2, 3}; - std::list<int, min_allocator<int>> l1(a1, a1+3); - std::list<int, min_allocator<int>>::iterator i = l1.insert(next(l1.cbegin()), 4); + List l1(a1, a1+3); + typename List::iterator i = l1.insert(next(l1.cbegin()), 4); assert(i == next(l1.begin())); assert(l1.size() == 4); assert(distance(l1.begin(), l1.end()) == 4); - assert((l1 == std::list<int, min_allocator<int>>(a2, a2+4))); - throw_next = 0; - int save_count = count; + assert(l1 == List(a2, a2+4)); + +#if !defined(TEST_HAS_NO_EXCEPTIONS) && !defined(DISABLE_NEW_COUNT) + globalMemCounter.throw_after = 0; + int save_count = globalMemCounter.outstanding_new; try { i = l1.insert(i, 5); @@ -96,18 +42,15 @@ int main() catch (...) { } - throw_next = 0xFFFF; - assert(save_count == count); - assert((l1 == std::list<int, min_allocator<int>>(a2, a2+4))); - } -#if _LIBCPP_DEBUG >= 1 - { - std::list<int, min_allocator<int>> v1(3); - std::list<int, min_allocator<int>> v2(3); - int i = 4; - v1.insert(v2.begin(), i); - assert(false); - } + assert(globalMemCounter.checkOutstandingNewEq(save_count)); + assert(l1 == List(a2, a2+4)); #endif +} + +int main() +{ + test<std::list<int> >(); +#if TEST_STD_VER >= 11 + test<std::list<int, min_allocator<int>>>(); #endif } diff --git a/test/std/containers/sequences/list/list.modifiers/pop_back.pass.cpp b/test/std/containers/sequences/list/list.modifiers/pop_back.pass.cpp index 3add8518809c5..c5b0277c6effa 100644 --- a/test/std/containers/sequences/list/list.modifiers/pop_back.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/pop_back.pass.cpp @@ -11,13 +11,10 @@ // void pop_back(); -#if _LIBCPP_DEBUG >= 1 -#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) -#endif - #include <list> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" int main() @@ -31,12 +28,8 @@ int main() assert(c == std::list<int>(a, a+1)); c.pop_back(); assert(c.empty()); -#if _LIBCPP_DEBUG >= 1 - c.pop_back(); - assert(false); -#endif } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a[] = {1, 2, 3}; std::list<int, min_allocator<int>> c(a, a+3); @@ -46,10 +39,6 @@ int main() assert((c == std::list<int, min_allocator<int>>(a, a+1))); c.pop_back(); assert(c.empty()); -#if _LIBCPP_DEBUG >= 1 - c.pop_back(); - assert(false); -#endif } #endif } diff --git a/test/std/containers/sequences/list/list.modifiers/pop_front.pass.cpp b/test/std/containers/sequences/list/list.modifiers/pop_front.pass.cpp index aec17cc08f43a..bb3ad546984d9 100644 --- a/test/std/containers/sequences/list/list.modifiers/pop_front.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/pop_front.pass.cpp @@ -28,7 +28,7 @@ int main() c.pop_front(); assert(c.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a[] = {1, 2, 3}; std::list<int, min_allocator<int>> c(a, a+3); diff --git a/test/std/containers/sequences/list/list.modifiers/push_back.pass.cpp b/test/std/containers/sequences/list/list.modifiers/push_back.pass.cpp index 2638c541fa1c4..3b05cd72968eb 100644 --- a/test/std/containers/sequences/list/list.modifiers/push_back.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/push_back.pass.cpp @@ -25,7 +25,7 @@ int main() int a[] = {0, 1, 2, 3, 4}; assert(c == std::list<int>(a, a+5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> c; for (int i = 0; i < 5; ++i) diff --git a/test/std/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp b/test/std/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp index a2837f813bea9..10acede511f4d 100644 --- a/test/std/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp @@ -30,7 +30,7 @@ int main() assert(l1.front() == MoveOnly(1)); assert(l1.back() == MoveOnly(2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<MoveOnly, min_allocator<MoveOnly>> l1; l1.push_back(MoveOnly(1)); diff --git a/test/std/containers/sequences/list/list.modifiers/push_front.pass.cpp b/test/std/containers/sequences/list/list.modifiers/push_front.pass.cpp index b7f4febcd385a..ed0ef662031a3 100644 --- a/test/std/containers/sequences/list/list.modifiers/push_front.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/push_front.pass.cpp @@ -25,7 +25,7 @@ int main() int a[] = {4, 3, 2, 1, 0}; assert(c == std::list<int>(a, a+5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> c; for (int i = 0; i < 5; ++i) diff --git a/test/std/containers/sequences/list/list.modifiers/push_front_rvalue.pass.cpp b/test/std/containers/sequences/list/list.modifiers/push_front_rvalue.pass.cpp index 4f41c3dd390b7..5321ee0faed3e 100644 --- a/test/std/containers/sequences/list/list.modifiers/push_front_rvalue.pass.cpp +++ b/test/std/containers/sequences/list/list.modifiers/push_front_rvalue.pass.cpp @@ -30,7 +30,7 @@ int main() assert(l1.front() == MoveOnly(2)); assert(l1.back() == MoveOnly(1)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<MoveOnly, min_allocator<MoveOnly>> l1; l1.push_front(MoveOnly(1)); diff --git a/test/std/containers/sequences/list/list.ops/merge.pass.cpp b/test/std/containers/sequences/list/list.ops/merge.pass.cpp index d226ed5dc6422..7c1287706f351 100644 --- a/test/std/containers/sequences/list/list.ops/merge.pass.cpp +++ b/test/std/containers/sequences/list/list.ops/merge.pass.cpp @@ -27,7 +27,7 @@ int main() c1.merge(c2); assert(c1 == std::list<int>(a3, a3+sizeof(a3)/sizeof(a3[0]))); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; diff --git a/test/std/containers/sequences/list/list.ops/merge_comp.pass.cpp b/test/std/containers/sequences/list/list.ops/merge_comp.pass.cpp index ce861a5dcb88a..838ff22b3a53b 100644 --- a/test/std/containers/sequences/list/list.ops/merge_comp.pass.cpp +++ b/test/std/containers/sequences/list/list.ops/merge_comp.pass.cpp @@ -28,7 +28,7 @@ int main() c1.merge(c2, std::greater<int>()); assert(c1 == std::list<int>(a3, a3+sizeof(a3)/sizeof(a3[0]))); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {10, 9, 7, 3, 1}; int a2[] = {11, 8, 6, 5, 4, 2, 0}; diff --git a/test/std/containers/sequences/list/list.ops/remove.pass.cpp b/test/std/containers/sequences/list/list.ops/remove.pass.cpp index f580c94ef4863..fed28e442e12e 100644 --- a/test/std/containers/sequences/list/list.ops/remove.pass.cpp +++ b/test/std/containers/sequences/list/list.ops/remove.pass.cpp @@ -57,7 +57,7 @@ int main() } assert ( it == c.end ()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 2, 3, 4}; int a2[] = {1, 2, 4}; diff --git a/test/std/containers/sequences/list/list.ops/remove_if.pass.cpp b/test/std/containers/sequences/list/list.ops/remove_if.pass.cpp index 162919ed85de0..1b457823d6ab2 100644 --- a/test/std/containers/sequences/list/list.ops/remove_if.pass.cpp +++ b/test/std/containers/sequences/list/list.ops/remove_if.pass.cpp @@ -50,7 +50,7 @@ int main() assert(c == std::list<int>(a2, a2+2)); assert(cp.count() == 4); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 2, 3, 4}; int a2[] = {3, 4}; diff --git a/test/std/containers/sequences/list/list.ops/reverse.pass.cpp b/test/std/containers/sequences/list/list.ops/reverse.pass.cpp index 046453ae53863..120caba38ac92 100644 --- a/test/std/containers/sequences/list/list.ops/reverse.pass.cpp +++ b/test/std/containers/sequences/list/list.ops/reverse.pass.cpp @@ -25,7 +25,7 @@ int main() c1.reverse(); assert(c1 == std::list<int>(a2, a2+sizeof(a2)/sizeof(a2[0]))); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; int a2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; diff --git a/test/std/containers/sequences/list/list.ops/sort.pass.cpp b/test/std/containers/sequences/list/list.ops/sort.pass.cpp index 1c11227237a76..d51aa92dd782f 100644 --- a/test/std/containers/sequences/list/list.ops/sort.pass.cpp +++ b/test/std/containers/sequences/list/list.ops/sort.pass.cpp @@ -25,7 +25,7 @@ int main() c1.sort(); assert(c1 == std::list<int>(a2, a2+sizeof(a2)/sizeof(a2[0]))); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {4, 8, 1, 0, 5, 7, 2, 3, 6, 11, 10, 9}; int a2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; diff --git a/test/std/containers/sequences/list/list.ops/sort_comp.pass.cpp b/test/std/containers/sequences/list/list.ops/sort_comp.pass.cpp index 28125ab83c007..517eb62ccae25 100644 --- a/test/std/containers/sequences/list/list.ops/sort_comp.pass.cpp +++ b/test/std/containers/sequences/list/list.ops/sort_comp.pass.cpp @@ -26,7 +26,7 @@ int main() c1.sort(std::greater<int>()); assert(c1 == std::list<int>(a2, a2+sizeof(a2)/sizeof(a2[0]))); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {4, 8, 1, 0, 5, 7, 2, 3, 6, 11, 10, 9}; int a2[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; diff --git a/test/std/containers/sequences/list/list.ops/splice_pos_list.pass.cpp b/test/std/containers/sequences/list/list.ops/splice_pos_list.pass.cpp index 354871c20afa7..41d861da0d55f 100644 --- a/test/std/containers/sequences/list/list.ops/splice_pos_list.pass.cpp +++ b/test/std/containers/sequences/list/list.ops/splice_pos_list.pass.cpp @@ -11,13 +11,10 @@ // void splice(const_iterator position, list& x); -#if _LIBCPP_DEBUG >= 1 -#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) -#endif - #include <list> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" int main() @@ -403,15 +400,7 @@ int main() ++i; assert(*i == 6); } -#if _LIBCPP_DEBUG >= 1 - { - std::list<int> v1(3); - std::list<int> v2(3); - v1.splice(v2.begin(), v2); - assert(false); - } -#endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> l1; std::list<int, min_allocator<int>> l2; @@ -791,13 +780,5 @@ int main() ++i; assert(*i == 6); } -#if _LIBCPP_DEBUG >= 1 - { - std::list<int, min_allocator<int>> v1(3); - std::list<int, min_allocator<int>> v2(3); - v1.splice(v2.begin(), v2); - assert(false); - } -#endif #endif } diff --git a/test/std/containers/sequences/list/list.ops/splice_pos_list_iter.pass.cpp b/test/std/containers/sequences/list/list.ops/splice_pos_list_iter.pass.cpp index 5082c3f85175b..427624a1cc3ef 100644 --- a/test/std/containers/sequences/list/list.ops/splice_pos_list_iter.pass.cpp +++ b/test/std/containers/sequences/list/list.ops/splice_pos_list_iter.pass.cpp @@ -11,13 +11,10 @@ // void splice(const_iterator position, list<T,Allocator>& x, iterator i); -#if _LIBCPP_DEBUG >= 1 -#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) -#endif - #include <list> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" int main() @@ -180,15 +177,7 @@ int main() ++i; assert(*i == 2); } -#if _LIBCPP_DEBUG >= 1 - { - std::list<int> v1(3); - std::list<int> v2(3); - v1.splice(v1.begin(), v2, v1.begin()); - assert(false); - } -#endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> l1; std::list<int, min_allocator<int>> l2(a2, a2+1); @@ -345,13 +334,5 @@ int main() ++i; assert(*i == 2); } -#if _LIBCPP_DEBUG >= 1 - { - std::list<int, min_allocator<int>> v1(3); - std::list<int, min_allocator<int>> v2(3); - v1.splice(v1.begin(), v2, v1.begin()); - assert(false); - } -#endif #endif } diff --git a/test/std/containers/sequences/list/list.ops/splice_pos_list_iter_iter.pass.cpp b/test/std/containers/sequences/list/list.ops/splice_pos_list_iter_iter.pass.cpp index fcc4acceec575..b7010636d20e4 100644 --- a/test/std/containers/sequences/list/list.ops/splice_pos_list_iter_iter.pass.cpp +++ b/test/std/containers/sequences/list/list.ops/splice_pos_list_iter_iter.pass.cpp @@ -11,13 +11,10 @@ // void splice(const_iterator position, list& x, iterator first, iterator last); -#if _LIBCPP_DEBUG >= 1 -#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) -#endif - #include <list> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" int main() @@ -120,15 +117,7 @@ int main() i = l2.begin(); assert(*i == 4); } -#if _LIBCPP_DEBUG >= 1 - { - std::list<int> v1(3); - std::list<int> v2(3); - v1.splice(v1.begin(), v2, v2.begin(), v1.end()); - assert(false); - } -#endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::list<int, min_allocator<int>> l1(a1, a1+3); l1.splice(l1.begin(), l1, next(l1.begin()), next(l1.begin())); @@ -225,13 +214,5 @@ int main() i = l2.begin(); assert(*i == 4); } -#if _LIBCPP_DEBUG >= 1 - { - std::list<int, min_allocator<int>> v1(3); - std::list<int, min_allocator<int>> v2(3); - v1.splice(v1.begin(), v2, v2.begin(), v1.end()); - assert(false); - } -#endif #endif } diff --git a/test/std/containers/sequences/list/list.ops/unique.pass.cpp b/test/std/containers/sequences/list/list.ops/unique.pass.cpp index 48cad1ddd1560..fa85b0eae77ca 100644 --- a/test/std/containers/sequences/list/list.ops/unique.pass.cpp +++ b/test/std/containers/sequences/list/list.ops/unique.pass.cpp @@ -25,7 +25,7 @@ int main() c.unique(); assert(c == std::list<int>(a2, a2+4)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {2, 1, 1, 4, 4, 4, 4, 3, 3}; int a2[] = {2, 1, 4, 3}; diff --git a/test/std/containers/sequences/list/list.ops/unique_pred.pass.cpp b/test/std/containers/sequences/list/list.ops/unique_pred.pass.cpp index f8935b81f6a73..de6347d46f39e 100644 --- a/test/std/containers/sequences/list/list.ops/unique_pred.pass.cpp +++ b/test/std/containers/sequences/list/list.ops/unique_pred.pass.cpp @@ -30,7 +30,7 @@ int main() c.unique(g); assert(c == std::list<int>(a2, a2+4)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {2, 1, 1, 4, 4, 4, 4, 3, 3}; int a2[] = {2, 1, 4, 3}; diff --git a/test/std/containers/sequences/list/list.special/db_swap_1.pass.cpp b/test/std/containers/sequences/list/list.special/db_swap_1.pass.cpp deleted file mode 100644 index f7171795cd5f0..0000000000000 --- a/test/std/containers/sequences/list/list.special/db_swap_1.pass.cpp +++ /dev/null @@ -1,59 +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. -// -//===----------------------------------------------------------------------===// - -// <list> - -// template <class T, class Alloc> -// void swap(list<T,Alloc>& x, list<T,Alloc>& y); - -#if _LIBCPP_DEBUG >= 1 -#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) -#endif - -#include <list> -#include <cassert> - -#include <__debug> -#include "min_allocator.h" - -int main() -{ -#if _LIBCPP_DEBUG >= 1 - { - int a1[] = {1, 3, 7, 9, 10}; - int a2[] = {0, 2, 4, 5, 6, 8, 11}; - std::list<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0])); - std::list<int> c2(a2, a2+sizeof(a2)/sizeof(a2[0])); - std::list<int>::iterator i1 = c1.begin(); - std::list<int>::iterator i2 = c2.begin(); - swap(c1, c2); - c1.erase(i2); - c2.erase(i1); - std::list<int>::iterator j = i1; - c1.erase(i1); - assert(false); - } -#if __cplusplus >= 201103L - { - int a1[] = {1, 3, 7, 9, 10}; - int a2[] = {0, 2, 4, 5, 6, 8, 11}; - std::list<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0])); - std::list<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0])); - std::list<int, min_allocator<int>>::iterator i1 = c1.begin(); - std::list<int, min_allocator<int>>::iterator i2 = c2.begin(); - swap(c1, c2); - c1.erase(i2); - c2.erase(i1); - std::list<int, min_allocator<int>>::iterator j = i1; - c1.erase(i1); - assert(false); - } -#endif -#endif -} diff --git a/test/std/containers/sequences/list/list.special/swap.pass.cpp b/test/std/containers/sequences/list/list.special/swap.pass.cpp index bc5f4857edc7c..54b262572dedc 100644 --- a/test/std/containers/sequences/list/list.special/swap.pass.cpp +++ b/test/std/containers/sequences/list/list.special/swap.pass.cpp @@ -59,21 +59,18 @@ int main() assert(c2.empty()); assert(distance(c2.begin(), c2.end()) == 0); } -#ifndef _LIBCPP_DEBUG_LEVEL -// This test known to result in undefined behavior detected by _LIBCPP_DEBUG_LEVEL >= 1 { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; typedef test_allocator<int> A; std::list<int, A> c1(a1, a1+sizeof(a1)/sizeof(a1[0]), A(1)); - std::list<int, A> c2(a2, a2+sizeof(a2)/sizeof(a2[0]), A(2)); + std::list<int, A> c2(a2, a2+sizeof(a2)/sizeof(a2[0]), A(1)); swap(c1, c2); assert((c1 == std::list<int, A>(a2, a2+sizeof(a2)/sizeof(a2[0])))); assert(c1.get_allocator() == A(1)); assert((c2 == std::list<int, A>(a1, a1+sizeof(a1)/sizeof(a1[0])))); - assert(c2.get_allocator() == A(2)); + assert(c2.get_allocator() == A(1)); } -#endif { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; @@ -86,7 +83,7 @@ int main() assert((c2 == std::list<int, A>(a1, a1+sizeof(a1)/sizeof(a1[0])))); assert(c2.get_allocator() == A(1)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; @@ -127,8 +124,6 @@ int main() assert(c2.empty()); assert(distance(c2.begin(), c2.end()) == 0); } -#ifndef _LIBCPP_DEBUG_LEVEL -// This test known to result in undefined behavior detected by _LIBCPP_DEBUG_LEVEL >= 1 { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; @@ -142,5 +137,4 @@ int main() assert(c2.get_allocator() == A()); } #endif -#endif } 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 9c83ad58fed47..820da4c78f81d 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <list> // void swap(list& c) @@ -21,6 +23,7 @@ #include <list> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -28,7 +31,7 @@ template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -40,7 +43,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -51,7 +54,6 @@ struct some_alloc2 int main() { -#if __has_feature(cxx_noexcept) { typedef std::list<MoveOnly> C; C c1, c2; @@ -86,5 +88,4 @@ int main() } #endif -#endif } diff --git a/test/std/containers/sequences/list/types.pass.cpp b/test/std/containers/sequences/list/types.pass.cpp index 77303601ae972..7d5f5b6fa2f0b 100644 --- a/test/std/containers/sequences/list/types.pass.cpp +++ b/test/std/containers/sequences/list/types.pass.cpp @@ -31,18 +31,39 @@ struct A { std::list<A> v; }; // incomplete type support int main() { - static_assert((std::is_same<std::list<int>::value_type, int>::value), ""); - static_assert((std::is_same<std::list<int>::allocator_type, std::allocator<int> >::value), ""); - static_assert((std::is_same<std::list<int>::reference, std::allocator<int>::reference>::value), ""); - static_assert((std::is_same<std::list<int>::const_reference, std::allocator<int>::const_reference>::value), ""); - static_assert((std::is_same<std::list<int>::pointer, std::allocator<int>::pointer>::value), ""); - static_assert((std::is_same<std::list<int>::const_pointer, std::allocator<int>::const_pointer>::value), ""); -#if __cplusplus >= 201103L - static_assert((std::is_same<std::list<int, min_allocator<int>>::value_type, int>::value), ""); - static_assert((std::is_same<std::list<int, min_allocator<int>>::allocator_type, min_allocator<int> >::value), ""); - static_assert((std::is_same<std::list<int, min_allocator<int>>::reference, int&>::value), ""); - static_assert((std::is_same<std::list<int, min_allocator<int>>::const_reference, const int&>::value), ""); - static_assert((std::is_same<std::list<int, min_allocator<int>>::pointer, min_pointer<int>>::value), ""); - static_assert((std::is_same<std::list<int, min_allocator<int>>::const_pointer, min_pointer<const int>>::value), ""); + { + typedef std::list<int> C; + static_assert((std::is_same<C::value_type, int>::value), ""); + static_assert((std::is_same<C::allocator_type, std::allocator<int> >::value), ""); + static_assert((std::is_same<C::reference, std::allocator<int>::reference>::value), ""); + static_assert((std::is_same<C::const_reference, std::allocator<int>::const_reference>::value), ""); + static_assert((std::is_same<C::pointer, std::allocator<int>::pointer>::value), ""); + static_assert((std::is_same<C::const_pointer, std::allocator<int>::const_pointer>::value), ""); + + static_assert((std::is_signed<typename C::difference_type>::value), ""); + static_assert((std::is_unsigned<typename C::size_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::iterator>::difference_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::const_iterator>::difference_type>::value), ""); + } + +#if TEST_STD_VER >= 11 + { + typedef std::list<int, min_allocator<int>> C; + static_assert((std::is_same<C::value_type, int>::value), ""); + static_assert((std::is_same<C::allocator_type, min_allocator<int> >::value), ""); + static_assert((std::is_same<C::reference, int&>::value), ""); + static_assert((std::is_same<C::const_reference, const int&>::value), ""); + static_assert((std::is_same<C::pointer, min_pointer<int>>::value), ""); + static_assert((std::is_same<C::const_pointer, min_pointer<const int>>::value), ""); + + static_assert((std::is_signed<typename C::difference_type>::value), ""); + static_assert((std::is_unsigned<typename C::size_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::iterator>::difference_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::const_iterator>::difference_type>::value), ""); + } #endif } diff --git a/test/std/containers/sequences/vector.bool/assign_copy.pass.cpp b/test/std/containers/sequences/vector.bool/assign_copy.pass.cpp index 9501799ae3d0b..54b7e84bb0920 100644 --- a/test/std/containers/sequences/vector.bool/assign_copy.pass.cpp +++ b/test/std/containers/sequences/vector.bool/assign_copy.pass.cpp @@ -19,22 +19,22 @@ int main() { { - std::vector<bool, test_allocator<bool> > l(3, 2, test_allocator<bool>(5)); + std::vector<bool, test_allocator<bool> > l(3, true, test_allocator<bool>(5)); std::vector<bool, test_allocator<bool> > l2(l, test_allocator<bool>(3)); l2 = l; assert(l2 == l); assert(l2.get_allocator() == test_allocator<bool>(3)); } { - std::vector<bool, other_allocator<bool> > l(3, 2, other_allocator<bool>(5)); + std::vector<bool, other_allocator<bool> > l(3, true, other_allocator<bool>(5)); std::vector<bool, other_allocator<bool> > l2(l, other_allocator<bool>(3)); l2 = l; assert(l2 == l); assert(l2.get_allocator() == other_allocator<bool>(5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { - std::vector<bool, min_allocator<bool> > l(3, 2, min_allocator<bool>()); + std::vector<bool, min_allocator<bool> > l(3, true, min_allocator<bool>()); std::vector<bool, min_allocator<bool> > l2(l, min_allocator<bool>()); l2 = l; assert(l2 == l); diff --git a/test/std/containers/sequences/vector.bool/assign_initializer_list.pass.cpp b/test/std/containers/sequences/vector.bool/assign_initializer_list.pass.cpp index 2925fbc66745b..ac7a2ce38adfa 100644 --- a/test/std/containers/sequences/vector.bool/assign_initializer_list.pass.cpp +++ b/test/std/containers/sequences/vector.bool/assign_initializer_list.pass.cpp @@ -28,7 +28,7 @@ int main() assert(d[2] == false); assert(d[3] == true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> d; d.assign({true, false, false, true}); diff --git a/test/std/containers/sequences/vector.bool/assign_move.pass.cpp b/test/std/containers/sequences/vector.bool/assign_move.pass.cpp index df98c817fd593..f07c1d90059dd 100644 --- a/test/std/containers/sequences/vector.bool/assign_move.pass.cpp +++ b/test/std/containers/sequences/vector.bool/assign_move.pass.cpp @@ -61,7 +61,7 @@ int main() assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool> > l(min_allocator<bool>{}); std::vector<bool, min_allocator<bool> > lo(min_allocator<bool>{}); diff --git a/test/std/containers/sequences/vector.bool/capacity.pass.cpp b/test/std/containers/sequences/vector.bool/capacity.pass.cpp index 63bff25f9f9ac..3cbb09fe4ef0c 100644 --- a/test/std/containers/sequences/vector.bool/capacity.pass.cpp +++ b/test/std/containers/sequences/vector.bool/capacity.pass.cpp @@ -29,7 +29,7 @@ int main() v.push_back(0); assert(v.capacity() >= 101); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> v; assert(v.capacity() == 0); 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 07824098fc6f7..983d363d1940a 100644 --- a/test/std/containers/sequences/vector.bool/construct_default.pass.cpp +++ b/test/std/containers/sequences/vector.bool/construct_default.pass.cpp @@ -29,12 +29,12 @@ test0() static_assert((noexcept(C()) == noexcept(typename C::allocator_type())), "" ); #endif C c; - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.empty()); assert(c.get_allocator() == typename C::allocator_type()); #if TEST_STD_VER >= 11 C c1 = {}; - assert(c1.__invariants()); + LIBCPP_ASSERT(c1.__invariants()); assert(c1.empty()); assert(c1.get_allocator() == typename C::allocator_type()); #endif @@ -50,7 +50,7 @@ test1(const typename C::allocator_type& a) 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()); + LIBCPP_ASSERT(c.__invariants()); assert(c.empty()); assert(c.get_allocator() == a); } diff --git a/test/std/containers/sequences/vector.bool/construct_iter_iter.pass.cpp b/test/std/containers/sequences/vector.bool/construct_iter_iter.pass.cpp index 94e6801825d81..3d11239702c9c 100644 --- a/test/std/containers/sequences/vector.bool/construct_iter_iter.pass.cpp +++ b/test/std/containers/sequences/vector.bool/construct_iter_iter.pass.cpp @@ -15,6 +15,7 @@ #include <vector> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "min_allocator.h" @@ -23,7 +24,7 @@ void test(Iterator first, Iterator last) { C c(first, last); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == std::distance(first, last)); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i, ++first) assert(*i == *first); @@ -38,7 +39,7 @@ int main() test<std::vector<bool> >(bidirectional_iterator<const bool*>(a), bidirectional_iterator<const bool*>(an)); test<std::vector<bool> >(random_access_iterator<const bool*>(a), random_access_iterator<const bool*>(an)); test<std::vector<bool> >(a, an); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<std::vector<bool, min_allocator<bool>> >(input_iterator<const bool*>(a), input_iterator<const bool*>(an)); test<std::vector<bool, min_allocator<bool>> >(forward_iterator<const bool*>(a), forward_iterator<const bool*>(an)); test<std::vector<bool, min_allocator<bool>> >(bidirectional_iterator<const bool*>(a), bidirectional_iterator<const bool*>(an)); diff --git a/test/std/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp b/test/std/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp index ea9d41d342f8d..196694d739980 100644 --- a/test/std/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp +++ b/test/std/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp @@ -16,6 +16,7 @@ #include <vector> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "min_allocator.h" @@ -24,7 +25,7 @@ void test(Iterator first, Iterator last, const typename C::allocator_type& a) { C c(first, last, a); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == std::distance(first, last)); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i, ++first) assert(*i == *first); @@ -42,7 +43,7 @@ int main() test<std::vector<bool> >(random_access_iterator<const bool*>(a), random_access_iterator<const bool*>(an), alloc); test<std::vector<bool> >(a, an, alloc); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { min_allocator<bool> alloc; test<std::vector<bool, min_allocator<bool>> >(input_iterator<const bool*>(a), input_iterator<const bool*>(an), alloc); diff --git a/test/std/containers/sequences/vector.bool/construct_size.pass.cpp b/test/std/containers/sequences/vector.bool/construct_size.pass.cpp index 93ecbe87c380f..271e4ee33aa42 100644 --- a/test/std/containers/sequences/vector.bool/construct_size.pass.cpp +++ b/test/std/containers/sequences/vector.bool/construct_size.pass.cpp @@ -15,22 +15,22 @@ #include <vector> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" #include "test_allocator.h" template <class C> void -test2(typename C::size_type n, typename C::allocator_type const& a = typename C::allocator_type ()) +test2(typename C::size_type n, + typename C::allocator_type const& a = typename C::allocator_type ()) { -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER >= 14 C c(n, a); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == n); assert(c.get_allocator() == a); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i) assert(*i == typename C::value_type()); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #endif } @@ -39,7 +39,7 @@ void test1(typename C::size_type n) { C c(n); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == n); assert(c.get_allocator() == typename C::allocator_type()); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i) @@ -57,7 +57,7 @@ test(typename C::size_type n) int main() { test<std::vector<bool> >(50); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<std::vector<bool, min_allocator<bool>> >(50); test2<std::vector<bool, test_allocator<bool>> >( 100, test_allocator<bool>(23)); #endif diff --git a/test/std/containers/sequences/vector.bool/construct_size_value.pass.cpp b/test/std/containers/sequences/vector.bool/construct_size_value.pass.cpp index fc772f10dfc43..c66fd49728998 100644 --- a/test/std/containers/sequences/vector.bool/construct_size_value.pass.cpp +++ b/test/std/containers/sequences/vector.bool/construct_size_value.pass.cpp @@ -15,6 +15,7 @@ #include <vector> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class C> @@ -22,7 +23,7 @@ void test(typename C::size_type n, const typename C::value_type& x) { C c(n, x); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == n); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i) assert(*i == x); @@ -30,8 +31,8 @@ test(typename C::size_type n, const typename C::value_type& x) int main() { - test<std::vector<bool> >(50, 3); -#if __cplusplus >= 201103L - test<std::vector<bool, min_allocator<bool>> >(50, 3); + test<std::vector<bool> >(50, true); +#if TEST_STD_VER >= 11 + test<std::vector<bool, min_allocator<bool>> >(50, true); #endif } diff --git a/test/std/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp b/test/std/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp index 6cca948ed834f..2ef501271f52b 100644 --- a/test/std/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp +++ b/test/std/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp @@ -15,6 +15,7 @@ #include <vector> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class C> @@ -23,7 +24,7 @@ test(typename C::size_type n, const typename C::value_type& x, const typename C::allocator_type& a) { C c(n, x, a); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(a == c.get_allocator()); assert(c.size() == n); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i) @@ -32,8 +33,8 @@ test(typename C::size_type n, const typename C::value_type& x, int main() { - test<std::vector<bool> >(50, 3, std::allocator<bool>()); -#if __cplusplus >= 201103L - test<std::vector<bool, min_allocator<bool>> >(50, 3, min_allocator<bool>()); + test<std::vector<bool> >(50, true, std::allocator<bool>()); +#if TEST_STD_VER >= 11 + test<std::vector<bool, min_allocator<bool>> >(50, true, min_allocator<bool>()); #endif } diff --git a/test/std/containers/sequences/vector.bool/copy.pass.cpp b/test/std/containers/sequences/vector.bool/copy.pass.cpp index 58822782ff8b9..b3cf9b551f960 100644 --- a/test/std/containers/sequences/vector.bool/copy.pass.cpp +++ b/test/std/containers/sequences/vector.bool/copy.pass.cpp @@ -14,6 +14,8 @@ #include <vector> #include <cassert> + +#include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" @@ -23,7 +25,7 @@ test(const C& x) { unsigned s = x.size(); C c(x); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == s); assert(c == x); } @@ -36,27 +38,25 @@ int main() test(std::vector<bool>(a, an)); } { - std::vector<bool, test_allocator<bool> > v(3, 2, test_allocator<bool>(5)); + std::vector<bool, test_allocator<bool> > v(3, true, test_allocator<bool>(5)); std::vector<bool, test_allocator<bool> > v2 = v; assert(v2 == v); assert(v2.get_allocator() == v.get_allocator()); } -#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE +#if TEST_STD_VER >= 11 { - std::vector<bool, other_allocator<bool> > v(3, 2, other_allocator<bool>(5)); + std::vector<bool, other_allocator<bool> > v(3, true, other_allocator<bool>(5)); std::vector<bool, other_allocator<bool> > v2 = v; assert(v2 == v); assert(v2.get_allocator() == other_allocator<bool>(-2)); } -#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE -#if __cplusplus >= 201103L { bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}; bool* an = a + sizeof(a)/sizeof(a[0]); test(std::vector<bool, min_allocator<bool>>(a, an)); } { - std::vector<bool, min_allocator<bool> > v(3, 2, min_allocator<bool>()); + std::vector<bool, min_allocator<bool> > v(3, true, min_allocator<bool>()); std::vector<bool, min_allocator<bool> > v2 = v; assert(v2 == v); assert(v2.get_allocator() == v.get_allocator()); diff --git a/test/std/containers/sequences/vector.bool/copy_alloc.pass.cpp b/test/std/containers/sequences/vector.bool/copy_alloc.pass.cpp index 2f0192b995ad7..aa8646a9b8191 100644 --- a/test/std/containers/sequences/vector.bool/copy_alloc.pass.cpp +++ b/test/std/containers/sequences/vector.bool/copy_alloc.pass.cpp @@ -13,6 +13,8 @@ #include <vector> #include <cassert> + +#include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" @@ -22,7 +24,7 @@ test(const C& x, const typename C::allocator_type& a) { unsigned s = x.size(); C c(x, a); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == s); assert(c == x); } @@ -30,30 +32,30 @@ test(const C& x, const typename C::allocator_type& a) int main() { { - int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0}; - int* an = a + sizeof(a)/sizeof(a[0]); + bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}; + bool* an = a + sizeof(a)/sizeof(a[0]); test(std::vector<bool>(a, an), std::allocator<bool>()); } { - std::vector<bool, test_allocator<bool> > l(3, 2, test_allocator<bool>(5)); + std::vector<bool, test_allocator<bool> > l(3, true, test_allocator<bool>(5)); std::vector<bool, test_allocator<bool> > l2(l, test_allocator<bool>(3)); assert(l2 == l); assert(l2.get_allocator() == test_allocator<bool>(3)); } { - std::vector<bool, other_allocator<bool> > l(3, 2, other_allocator<bool>(5)); + std::vector<bool, other_allocator<bool> > l(3, true, other_allocator<bool>(5)); std::vector<bool, other_allocator<bool> > l2(l, other_allocator<bool>(3)); assert(l2 == l); assert(l2.get_allocator() == other_allocator<bool>(3)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { - int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0}; - int* an = a + sizeof(a)/sizeof(a[0]); + bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}; + bool* an = a + sizeof(a)/sizeof(a[0]); test(std::vector<bool, min_allocator<bool>>(a, an), min_allocator<bool>()); } { - std::vector<bool, min_allocator<bool> > l(3, 2, min_allocator<bool>()); + std::vector<bool, min_allocator<bool> > l(3, true, min_allocator<bool>()); std::vector<bool, min_allocator<bool> > l2(l, min_allocator<bool>()); assert(l2 == l); assert(l2.get_allocator() == min_allocator<bool>()); diff --git a/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp b/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp index b94588ead93be..4f860dabac952 100644 --- a/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp +++ b/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp @@ -14,9 +14,12 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <vector> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" template <class T> @@ -28,14 +31,13 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::vector<bool> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::vector<bool, test_allocator<bool>> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::vector<bool, other_allocator<bool>> C; @@ -45,5 +47,4 @@ int main() typedef std::vector<bool, some_alloc<bool>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/vector.bool/dtor_noexcept.pass.cpp b/test/std/containers/sequences/vector.bool/dtor_noexcept.pass.cpp index 682e74ef03c20..bd2534ad3de7f 100644 --- a/test/std/containers/sequences/vector.bool/dtor_noexcept.pass.cpp +++ b/test/std/containers/sequences/vector.bool/dtor_noexcept.pass.cpp @@ -11,13 +11,13 @@ // ~vector<bool>() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <vector> #include <cassert> #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_alloc { @@ -26,11 +26,8 @@ struct some_alloc ~some_alloc() noexcept(false); }; -#endif - int main() { -#if __has_feature(cxx_noexcept) { typedef std::vector<bool> C; static_assert(std::is_nothrow_destructible<C>::value, ""); @@ -47,5 +44,4 @@ int main() typedef std::vector<bool, some_alloc<bool>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/vector.bool/emplace.pass.cpp b/test/std/containers/sequences/vector.bool/emplace.pass.cpp index f3fd1e9926f03..ccdce913c73cd 100644 --- a/test/std/containers/sequences/vector.bool/emplace.pass.cpp +++ b/test/std/containers/sequences/vector.bool/emplace.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <vector> // vector<bool> @@ -18,11 +19,10 @@ int main() { -#if _LIBCPP_STD_VER > 11 { typedef std::vector<bool> C; C c; - + C::iterator i = c.emplace(c.cbegin()); assert(i == c.begin()); assert(c.size() == 1); @@ -64,5 +64,4 @@ int main() assert(c[1] == true); assert(c.back() == true); } -#endif } diff --git a/test/std/containers/sequences/vector.bool/emplace_back.pass.cpp b/test/std/containers/sequences/vector.bool/emplace_back.pass.cpp index 57aa47822f8ad..2950ee3882f1f 100644 --- a/test/std/containers/sequences/vector.bool/emplace_back.pass.cpp +++ b/test/std/containers/sequences/vector.bool/emplace_back.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <vector> // vector.bool @@ -19,7 +20,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 { typedef std::vector<bool> C; C c; @@ -39,7 +39,7 @@ int main() { typedef std::vector<bool, min_allocator<bool>> C; C c; - + c.emplace_back(); assert(c.size() == 1); assert(c.front() == false); @@ -53,5 +53,4 @@ int main() assert(c[1] == true); assert(c.back() == true); } -#endif } diff --git a/test/std/containers/sequences/vector.bool/erase_iter.pass.cpp b/test/std/containers/sequences/vector.bool/erase_iter.pass.cpp index cbf26dd570a50..04e3dd7c25f15 100644 --- a/test/std/containers/sequences/vector.bool/erase_iter.pass.cpp +++ b/test/std/containers/sequences/vector.bool/erase_iter.pass.cpp @@ -40,7 +40,7 @@ int main() assert(l1.size() == 0); assert(distance(l1.begin(), l1.end()) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> l1(a1, a1+3); std::vector<bool, min_allocator<bool>>::const_iterator i = l1.begin(); diff --git a/test/std/containers/sequences/vector.bool/erase_iter_iter.pass.cpp b/test/std/containers/sequences/vector.bool/erase_iter_iter.pass.cpp index 2c2c4cc48616b..2b9f0e31c2fae 100644 --- a/test/std/containers/sequences/vector.bool/erase_iter_iter.pass.cpp +++ b/test/std/containers/sequences/vector.bool/erase_iter_iter.pass.cpp @@ -50,7 +50,7 @@ int main() assert(distance(l1.cbegin(), l1.cend()) == 0); assert(i == l1.begin()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> l1(a1, a1+3); std::vector<bool, min_allocator<bool>>::iterator i = l1.erase(l1.cbegin(), l1.cbegin()); diff --git a/test/std/containers/sequences/vector.bool/initializer_list.pass.cpp b/test/std/containers/sequences/vector.bool/initializer_list.pass.cpp index b9b4686544973..07bae0eb70897 100644 --- a/test/std/containers/sequences/vector.bool/initializer_list.pass.cpp +++ b/test/std/containers/sequences/vector.bool/initializer_list.pass.cpp @@ -27,7 +27,7 @@ int main() assert(d[2] == false); assert(d[3] == true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> d = {true, false, false, true}; assert(d.size() == 4); diff --git a/test/std/containers/sequences/vector.bool/initializer_list_alloc.pass.cpp b/test/std/containers/sequences/vector.bool/initializer_list_alloc.pass.cpp index aea3ad763cde8..5f7f5144f8413 100644 --- a/test/std/containers/sequences/vector.bool/initializer_list_alloc.pass.cpp +++ b/test/std/containers/sequences/vector.bool/initializer_list_alloc.pass.cpp @@ -29,7 +29,7 @@ int main() assert(d[2] == false); assert(d[3] == true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> d({true, false, false, true}, min_allocator<bool>()); assert(d.get_allocator() == min_allocator<bool>()); diff --git a/test/std/containers/sequences/vector.bool/insert_iter_initializer_list.pass.cpp b/test/std/containers/sequences/vector.bool/insert_iter_initializer_list.pass.cpp index c081cc81c5922..3a176d94e860e 100644 --- a/test/std/containers/sequences/vector.bool/insert_iter_initializer_list.pass.cpp +++ b/test/std/containers/sequences/vector.bool/insert_iter_initializer_list.pass.cpp @@ -39,7 +39,7 @@ int main() assert(d[12] == true); assert(d[13] == true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> d(10, true); std::vector<bool, min_allocator<bool>>::iterator i = d.insert(d.cbegin() + 2, {false, true, true, false}); diff --git a/test/std/containers/sequences/vector.bool/insert_iter_iter_iter.pass.cpp b/test/std/containers/sequences/vector.bool/insert_iter_iter_iter.pass.cpp index e51f8b589c7f7..89fe7a76d4090 100644 --- a/test/std/containers/sequences/vector.bool/insert_iter_iter_iter.pass.cpp +++ b/test/std/containers/sequences/vector.bool/insert_iter_iter_iter.pass.cpp @@ -89,7 +89,7 @@ int main() for (; j < v.size(); ++j) assert(v[j] == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> v(100); bool a[] = {1, 0, 0, 1, 1}; diff --git a/test/std/containers/sequences/vector.bool/insert_iter_size_value.pass.cpp b/test/std/containers/sequences/vector.bool/insert_iter_size_value.pass.cpp index 710ad4885f099..35c57cbd8e42e 100644 --- a/test/std/containers/sequences/vector.bool/insert_iter_size_value.pass.cpp +++ b/test/std/containers/sequences/vector.bool/insert_iter_size_value.pass.cpp @@ -63,7 +63,7 @@ int main() for (++j; j < v.size(); ++j) assert(v[j] == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> v(100); std::vector<bool, min_allocator<bool>>::iterator i = v.insert(v.cbegin() + 10, 5, 1); diff --git a/test/std/containers/sequences/vector.bool/insert_iter_value.pass.cpp b/test/std/containers/sequences/vector.bool/insert_iter_value.pass.cpp index 51c4626de0d02..78ffe7ba73cd5 100644 --- a/test/std/containers/sequences/vector.bool/insert_iter_value.pass.cpp +++ b/test/std/containers/sequences/vector.bool/insert_iter_value.pass.cpp @@ -60,7 +60,7 @@ int main() for (++j; j < v.size(); ++j) assert(v[j] == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> v(100); std::vector<bool, min_allocator<bool>>::iterator i = v.insert(v.cbegin() + 10, 1); diff --git a/test/std/containers/sequences/vector.bool/iterators.pass.cpp b/test/std/containers/sequences/vector.bool/iterators.pass.cpp index c54fa4a80a95d..882ac9be4a5d5 100644 --- a/test/std/containers/sequences/vector.bool/iterators.pass.cpp +++ b/test/std/containers/sequences/vector.bool/iterators.pass.cpp @@ -58,7 +58,7 @@ int main() C::iterator i; C::const_iterator j; } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef bool T; typedef std::vector<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/vector.bool/move.pass.cpp b/test/std/containers/sequences/vector.bool/move.pass.cpp index e877292ced770..f3a11ec562c0d 100644 --- a/test/std/containers/sequences/vector.bool/move.pass.cpp +++ b/test/std/containers/sequences/vector.bool/move.pass.cpp @@ -45,7 +45,7 @@ int main() assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool> > l(min_allocator<bool>{}); std::vector<bool, min_allocator<bool> > lo(min_allocator<bool>{}); diff --git a/test/std/containers/sequences/vector.bool/move_alloc.pass.cpp b/test/std/containers/sequences/vector.bool/move_alloc.pass.cpp index deee932619711..7aaa7c55550b2 100644 --- a/test/std/containers/sequences/vector.bool/move_alloc.pass.cpp +++ b/test/std/containers/sequences/vector.bool/move_alloc.pass.cpp @@ -58,7 +58,7 @@ int main() assert(!l.empty()); assert(l2.get_allocator() == other_allocator<bool>(4)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool> > l(min_allocator<bool>{}); std::vector<bool, min_allocator<bool> > lo(min_allocator<bool>{}); diff --git a/test/std/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp b/test/std/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp index 4dd871c9447ed..fe53fbfc17e09 100644 --- a/test/std/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp +++ b/test/std/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp @@ -16,6 +16,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <vector> #include <cassert> @@ -32,7 +34,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -45,7 +47,7 @@ template <class T> struct some_alloc3 { typedef T value_type; - + some_alloc3() {} some_alloc3(const some_alloc3&); void deallocate(void*, unsigned) {} @@ -56,7 +58,6 @@ struct some_alloc3 int main() { -#if __has_feature(cxx_noexcept) { typedef std::vector<bool> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); @@ -87,6 +88,4 @@ int main() static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } #endif - -#endif } 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 132186b555f25..2153c7956bfc6 100644 --- a/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp +++ b/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp @@ -14,6 +14,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <vector> #include <cassert> @@ -28,7 +30,6 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::vector<bool> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); @@ -50,5 +51,4 @@ int main() static_assert(!std::is_nothrow_move_constructible<C>::value, ""); #endif } -#endif } diff --git a/test/std/containers/sequences/vector.bool/op_equal_initializer_list.pass.cpp b/test/std/containers/sequences/vector.bool/op_equal_initializer_list.pass.cpp index ef3dc5d10796c..4b959cf00ad34 100644 --- a/test/std/containers/sequences/vector.bool/op_equal_initializer_list.pass.cpp +++ b/test/std/containers/sequences/vector.bool/op_equal_initializer_list.pass.cpp @@ -28,7 +28,7 @@ int main() assert(d[2] == false); assert(d[3] == true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> d; d = {true, false, false, true}; diff --git a/test/std/containers/sequences/vector.bool/push_back.pass.cpp b/test/std/containers/sequences/vector.bool/push_back.pass.cpp index c6b0fbf418536..3897a438b445f 100644 --- a/test/std/containers/sequences/vector.bool/push_back.pass.cpp +++ b/test/std/containers/sequences/vector.bool/push_back.pass.cpp @@ -31,7 +31,7 @@ int main() assert(c[j] == a[j]); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { bool a[] = {0, 1, 1, 0, 1, 0, 0}; const unsigned N = sizeof(a)/sizeof(a[0]); diff --git a/test/std/containers/sequences/vector.bool/reference.swap.pass.cpp b/test/std/containers/sequences/vector.bool/reference.swap.pass.cpp new file mode 100644 index 0000000000000..06351e418ac45 --- /dev/null +++ b/test/std/containers/sequences/vector.bool/reference.swap.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. +// +//===----------------------------------------------------------------------===// + +// <vector> +// vector<bool> + +// static void swap(reference x, reference y) noexcept; + +#include <vector> +#include <cassert> + +#include "test_macros.h" + +int main() +{ + + bool a[] = {false, true, false, true}; + bool* an = a + sizeof(a)/sizeof(a[0]); + + std::vector<bool> v(a, an); + std::vector<bool>::reference r1 = v[0]; + std::vector<bool>::reference r2 = v[3]; + +#if TEST_STD_VER >= 11 + static_assert((noexcept(v.swap(r1,r2))), ""); +#endif + + assert(!r1); + assert( r2); + v.swap(r1, r2); + assert( r1); + assert(!r2); +} diff --git a/test/std/containers/sequences/vector.bool/reserve.pass.cpp b/test/std/containers/sequences/vector.bool/reserve.pass.cpp index be717a3be8a8e..489ca95ee7894 100644 --- a/test/std/containers/sequences/vector.bool/reserve.pass.cpp +++ b/test/std/containers/sequences/vector.bool/reserve.pass.cpp @@ -34,7 +34,7 @@ int main() assert(v.size() == 100); assert(v.capacity() >= 150); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> v; v.reserve(10); diff --git a/test/std/containers/sequences/vector.bool/resize_size.pass.cpp b/test/std/containers/sequences/vector.bool/resize_size.pass.cpp index f75720c94ea39..bc51e0bbba27a 100644 --- a/test/std/containers/sequences/vector.bool/resize_size.pass.cpp +++ b/test/std/containers/sequences/vector.bool/resize_size.pass.cpp @@ -32,7 +32,7 @@ int main() assert(v.size() == 300); assert(v.capacity() >= 400); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> v(100); v.resize(50); diff --git a/test/std/containers/sequences/vector.bool/resize_size_value.pass.cpp b/test/std/containers/sequences/vector.bool/resize_size_value.pass.cpp index 8cecf44d2fb0f..9190007326987 100644 --- a/test/std/containers/sequences/vector.bool/resize_size_value.pass.cpp +++ b/test/std/containers/sequences/vector.bool/resize_size_value.pass.cpp @@ -33,7 +33,7 @@ int main() for (unsigned i = 50; i < 200; ++i) assert(v[i] == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> v(100); v.resize(50, 1); diff --git a/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp b/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp index 1f9fcac3d9bf5..03997cbec71e6 100644 --- a/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp +++ b/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp @@ -26,7 +26,7 @@ int main() assert(v.capacity() >= 101); assert(v.size() >= 101); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> v(100); v.push_back(1); diff --git a/test/std/containers/sequences/vector.bool/swap.pass.cpp b/test/std/containers/sequences/vector.bool/swap.pass.cpp index a92c6a6c165fe..81af528f2a9ae 100644 --- a/test/std/containers/sequences/vector.bool/swap.pass.cpp +++ b/test/std/containers/sequences/vector.bool/swap.pass.cpp @@ -62,7 +62,7 @@ int main() assert(v[0] == false); assert(v[1] == true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<bool, min_allocator<bool>> v1(100); std::vector<bool, min_allocator<bool>> v2(200); 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 6f36473fa989b..7ba44453b371b 100644 --- a/test/std/containers/sequences/vector.bool/swap_noexcept.pass.cpp +++ b/test/std/containers/sequences/vector.bool/swap_noexcept.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <vector> // void swap(vector& c) @@ -22,13 +24,14 @@ #include <vector> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -40,7 +43,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -51,7 +54,6 @@ struct some_alloc2 int main() { -#if __has_feature(cxx_noexcept) { typedef std::vector<bool> C; C c1, c2; @@ -85,6 +87,4 @@ int main() static_assert( noexcept(swap(c1, c2)), ""); } #endif - -#endif } diff --git a/test/std/containers/sequences/vector.bool/types.pass.cpp b/test/std/containers/sequences/vector.bool/types.pass.cpp index b266b3bbb927e..4e8edc8891bd5 100644 --- a/test/std/containers/sequences/vector.bool/types.pass.cpp +++ b/test/std/containers/sequences/vector.bool/types.pass.cpp @@ -46,7 +46,15 @@ test() static_assert((std::is_same<typename C::allocator_type, Allocator>::value), ""); static_assert((std::is_same<typename C::size_type, typename std::allocator_traits<Allocator>::size_type>::value), ""); static_assert((std::is_same<typename C::difference_type, typename std::allocator_traits<Allocator>::difference_type>::value), ""); - static_assert((std::is_same< + + static_assert((std::is_signed<typename C::difference_type>::value), ""); + static_assert((std::is_unsigned<typename C::size_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::iterator>::difference_type>::value), ""); + static_assert((std::is_same<typename C::difference_type, + typename std::iterator_traits<typename C::const_iterator>::difference_type>::value), ""); + + static_assert((std::is_same< typename std::iterator_traits<typename C::iterator>::iterator_category, std::random_access_iterator_tag>::value), ""); static_assert((std::is_same< @@ -66,7 +74,7 @@ int main() test<std::allocator<bool> >(); static_assert((std::is_same<std::vector<bool>::allocator_type, std::allocator<bool> >::value), ""); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<min_allocator<bool> >(); #endif } diff --git a/test/std/containers/sequences/vector.bool/vector_bool.pass.cpp b/test/std/containers/sequences/vector.bool/vector_bool.pass.cpp index a78f4fd590beb..4f82792fa1fde 100644 --- a/test/std/containers/sequences/vector.bool/vector_bool.pass.cpp +++ b/test/std/containers/sequences/vector.bool/vector_bool.pass.cpp @@ -31,18 +31,18 @@ int main() typedef std::hash<T> H; static_assert((std::is_same<H::argument_type, T>::value), "" ); static_assert((std::is_same<H::result_type, std::size_t>::value), "" ); - + bool ba[] = {true, false, true, true, false}; T vb(std::begin(ba), std::end(ba)); H h; assert(h(vb) != 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::vector<bool, min_allocator<bool>> T; typedef std::hash<T> H; - static_assert((std::is_base_of<std::unary_function<T, std::size_t>, - H>::value), ""); + static_assert((std::is_same<H::argument_type, T>::value), "" ); + static_assert((std::is_same<H::result_type, std::size_t>::value), "" ); bool ba[] = {true, false, true, true, false}; T vb(std::begin(ba), std::end(ba)); H h; diff --git a/test/std/containers/sequences/vector/contiguous.pass.cpp b/test/std/containers/sequences/vector/contiguous.pass.cpp index 32f3807783358..70084246eae9f 100644 --- a/test/std/containers/sequences/vector/contiguous.pass.cpp +++ b/test/std/containers/sequences/vector/contiguous.pass.cpp @@ -40,7 +40,7 @@ int main() test_contiguous(C(A(3))); test_contiguous(C(7, 9.0, A(5))); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef double T; typedef min_allocator<T> A; diff --git a/test/std/containers/sequences/vector/iterators.pass.cpp b/test/std/containers/sequences/vector/iterators.pass.cpp index 75a08287a863b..8dc14977f2820 100644 --- a/test/std/containers/sequences/vector/iterators.pass.cpp +++ b/test/std/containers/sequences/vector/iterators.pass.cpp @@ -77,7 +77,7 @@ int main() C::iterator i; C::const_iterator j; } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::vector<T, min_allocator<T>> C; diff --git a/test/std/containers/sequences/vector/types.pass.cpp b/test/std/containers/sequences/vector/types.pass.cpp index 0fbc7e38b1a2b..2080ac09fc5ab 100644 --- a/test/std/containers/sequences/vector/types.pass.cpp +++ b/test/std/containers/sequences/vector/types.pass.cpp @@ -45,6 +45,9 @@ test() { typedef std::vector<T, Allocator> C; +// TODO: These tests should use allocator_traits to get stuff, rather than +// blindly pulling typedefs out of the allocator. This is why we can't call +// test<int, min_allocator<int>>() below. static_assert((std::is_same<typename C::value_type, T>::value), ""); static_assert((std::is_same<typename C::value_type, typename Allocator::value_type>::value), ""); static_assert((std::is_same<typename C::allocator_type, Allocator>::value), ""); @@ -54,6 +57,14 @@ test() static_assert((std::is_same<typename C::const_reference, typename Allocator::const_reference>::value), ""); static_assert((std::is_same<typename C::pointer, typename Allocator::pointer>::value), ""); static_assert((std::is_same<typename C::const_pointer, typename Allocator::const_pointer>::value), ""); + + static_assert((std::is_signed<typename C::difference_type>::value), ""); + static_assert((std::is_unsigned<typename C::size_type>::value), ""); +// static_assert((std::is_same<typename C::difference_type, +// typename std::iterator_traits<typename C::iterator>::difference_type>::value), ""); +// static_assert((std::is_same<typename C::difference_type, +// typename std::iterator_traits<typename C::const_iterator>::difference_type>::value), ""); + static_assert((std::is_same< typename std::iterator_traits<typename C::iterator>::iterator_category, std::random_access_iterator_tag>::value), ""); @@ -75,12 +86,23 @@ int main() test<Copyable, test_allocator<Copyable> >(); static_assert((std::is_same<std::vector<char>::allocator_type, std::allocator<char> >::value), ""); -#if __cplusplus >= 201103L - static_assert((std::is_same<std::vector<int, min_allocator<int>>::value_type, int>::value), ""); - static_assert((std::is_same<std::vector<int, min_allocator<int>>::allocator_type, min_allocator<int> >::value), ""); - static_assert((std::is_same<std::vector<int, min_allocator<int>>::reference, int&>::value), ""); - static_assert((std::is_same<std::vector<int, min_allocator<int>>::const_reference, const int&>::value), ""); - static_assert((std::is_same<std::vector<int, min_allocator<int>>::pointer, min_pointer<int>>::value), ""); - static_assert((std::is_same<std::vector<int, min_allocator<int>>::const_pointer, min_pointer<const int>>::value), ""); +#if TEST_STD_VER >= 11 + { + + typedef std::vector<int, min_allocator<int> > C; + static_assert((std::is_same<C::value_type, int>::value), ""); + static_assert((std::is_same<C::allocator_type, min_allocator<int> >::value), ""); + static_assert((std::is_same<C::reference, int&>::value), ""); + static_assert((std::is_same<C::const_reference, const int&>::value), ""); + static_assert((std::is_same<C::pointer, min_pointer<int>>::value), ""); + static_assert((std::is_same<C::const_pointer, min_pointer<const int>>::value), ""); + + static_assert((std::is_signed<typename C::difference_type>::value), ""); + static_assert((std::is_unsigned<typename C::size_type>::value), ""); +// static_assert((std::is_same<typename C::difference_type, +// typename std::iterator_traits<typename C::iterator>::difference_type>::value), ""); +// static_assert((std::is_same<typename C::difference_type, +// typename std::iterator_traits<typename C::const_iterator>::difference_type>::value), ""); + } #endif } diff --git a/test/std/containers/sequences/vector/vector.capacity/capacity.pass.cpp b/test/std/containers/sequences/vector/vector.capacity/capacity.pass.cpp index 21082c839f56c..a87b84061030c 100644 --- a/test/std/containers/sequences/vector/vector.capacity/capacity.pass.cpp +++ b/test/std/containers/sequences/vector/vector.capacity/capacity.pass.cpp @@ -22,27 +22,27 @@ int main() { std::vector<int> v; assert(v.capacity() == 0); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { std::vector<int> v(100); assert(v.capacity() == 100); v.push_back(0); assert(v.capacity() > 101); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> v; assert(v.capacity() == 0); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { std::vector<int, min_allocator<int>> v(100); assert(v.capacity() == 100); v.push_back(0); assert(v.capacity() > 101); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp b/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp index 4df5702f2ad2c..d04e43db508d5 100644 --- a/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp +++ b/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp @@ -23,7 +23,7 @@ int main() std::vector<int> v; v.reserve(10); assert(v.capacity() >= 10); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { std::vector<int> v(100); @@ -34,7 +34,7 @@ int main() v.reserve(150); assert(v.size() == 100); assert(v.capacity() == 150); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { std::vector<int, stack_allocator<int, 250> > v(100); @@ -45,14 +45,14 @@ int main() v.reserve(150); assert(v.size() == 100); assert(v.capacity() == 150); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> v; v.reserve(10); assert(v.capacity() >= 10); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { std::vector<int, min_allocator<int>> v(100); @@ -63,7 +63,7 @@ int main() v.reserve(150); assert(v.size() == 100); assert(v.capacity() == 150); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/std/containers/sequences/vector/vector.capacity/resize_size.pass.cpp b/test/std/containers/sequences/vector/vector.capacity/resize_size.pass.cpp index c7988d62060a4..ce74cf9b7c239 100644 --- a/test/std/containers/sequences/vector/vector.capacity/resize_size.pass.cpp +++ b/test/std/containers/sequences/vector/vector.capacity/resize_size.pass.cpp @@ -26,22 +26,22 @@ int main() v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v.resize(200); assert(v.size() == 200); assert(v.capacity() >= 200); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { std::vector<MoveOnly, stack_allocator<MoveOnly, 300> > v(100); v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v.resize(200); assert(v.size() == 200); assert(v.capacity() >= 200); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES { @@ -49,35 +49,35 @@ int main() v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v.resize(200); assert(v.size() == 200); assert(v.capacity() >= 200); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { std::vector<int, stack_allocator<int, 300> > v(100); v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v.resize(200); assert(v.size() == 200); assert(v.capacity() >= 200); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<MoveOnly, min_allocator<MoveOnly>> v(100); v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v.resize(200); assert(v.size() == 200); assert(v.capacity() >= 200); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/std/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp b/test/std/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp index de5126b03d104..3e7df312731fd 100644 --- a/test/std/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp +++ b/test/std/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp @@ -28,7 +28,7 @@ int main() v.resize(200, 1); assert(v.size() == 200); assert(v.capacity() >= 200); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); for (unsigned i = 0; i < 50; ++i) assert(v[i] == 0); for (unsigned i = 50; i < 200; ++i) @@ -42,20 +42,20 @@ int main() v.resize(200, 1); assert(v.size() == 200); assert(v.capacity() >= 200); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> v(100); v.resize(50, 1); assert(v.size() == 50); assert(v.capacity() == 100); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert((v == std::vector<int, min_allocator<int>>(50))); v.resize(200, 1); assert(v.size() == 200); assert(v.capacity() >= 200); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); for (unsigned i = 0; i < 50; ++i) assert(v[i] == 0); for (unsigned i = 50; i < 200; ++i) @@ -66,11 +66,11 @@ int main() v.resize(50, 1); assert(v.size() == 50); assert(v.capacity() == 100); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v.resize(200, 1); assert(v.size() == 200); assert(v.capacity() >= 200); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp b/test/std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp index 49ab9cc71debc..10ce33f43bd21 100644 --- a/test/std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp +++ b/test/std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp @@ -22,41 +22,41 @@ int main() { std::vector<int> v(100); v.push_back(1); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v.shrink_to_fit(); assert(v.capacity() == 101); assert(v.size() == 101); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { std::vector<int, stack_allocator<int, 401> > v(100); v.push_back(1); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v.shrink_to_fit(); assert(v.capacity() == 101); assert(v.size() == 101); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } #ifndef _LIBCPP_NO_EXCEPTIONS { std::vector<int, stack_allocator<int, 400> > v(100); v.push_back(1); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v.shrink_to_fit(); - assert(v.capacity() == 200); + LIBCPP_ASSERT(v.capacity() == 200); // assumes libc++'s 2x growth factor assert(v.size() == 101); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> v(100); v.push_back(1); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v.shrink_to_fit(); assert(v.capacity() == 101); assert(v.size() == 101); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/std/containers/sequences/vector/vector.capacity/swap.pass.cpp b/test/std/containers/sequences/vector/vector.capacity/swap.pass.cpp index f3d9289c36eb9..59529a6dfd363 100644 --- a/test/std/containers/sequences/vector/vector.capacity/swap.pass.cpp +++ b/test/std/containers/sequences/vector/vector.capacity/swap.pass.cpp @@ -22,29 +22,29 @@ int main() { std::vector<int> v1(100); std::vector<int> v2(200); - assert(is_contiguous_container_asan_correct(v1)); - assert(is_contiguous_container_asan_correct(v2)); + assert(is_contiguous_container_asan_correct(v1)); + assert(is_contiguous_container_asan_correct(v2)); v1.swap(v2); assert(v1.size() == 200); assert(v1.capacity() == 200); - assert(is_contiguous_container_asan_correct(v1)); + assert(is_contiguous_container_asan_correct(v1)); assert(v2.size() == 100); assert(v2.capacity() == 100); - assert(is_contiguous_container_asan_correct(v2)); + assert(is_contiguous_container_asan_correct(v2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> v1(100); std::vector<int, min_allocator<int>> v2(200); - assert(is_contiguous_container_asan_correct(v1)); - assert(is_contiguous_container_asan_correct(v2)); + assert(is_contiguous_container_asan_correct(v1)); + assert(is_contiguous_container_asan_correct(v2)); v1.swap(v2); assert(v1.size() == 200); assert(v1.capacity() == 200); - assert(is_contiguous_container_asan_correct(v1)); + assert(is_contiguous_container_asan_correct(v1)); assert(v2.size() == 100); assert(v2.capacity() == 100); - assert(is_contiguous_container_asan_correct(v2)); + assert(is_contiguous_container_asan_correct(v2)); } #endif } diff --git a/test/std/containers/sequences/vector/vector.cons/assign_copy.pass.cpp b/test/std/containers/sequences/vector/vector.cons/assign_copy.pass.cpp index 6f02c3b7bc2b4..d15d24dd969f9 100644 --- a/test/std/containers/sequences/vector/vector.cons/assign_copy.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/assign_copy.pass.cpp @@ -32,7 +32,7 @@ int main() assert(l2 == l); assert(l2.get_allocator() == other_allocator<int>(5)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int> > l(3, 2, min_allocator<int>()); std::vector<int, min_allocator<int> > l2(l, min_allocator<int>()); 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 3cb0b3b095f03..222fa9c78f921 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 @@ -23,7 +23,7 @@ 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(is_contiguous_container_asan_correct(v)); assert(v[0] == 3); assert(v[1] == 4); assert(v[2] == 5); @@ -42,7 +42,7 @@ int main() test(d2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::vector<int, min_allocator<int>> V; V d1; diff --git a/test/std/containers/sequences/vector/vector.cons/assign_move.pass.cpp b/test/std/containers/sequences/vector/vector.cons/assign_move.pass.cpp index 8c8b0a04715be..acbee97bcd1c5 100644 --- a/test/std/containers/sequences/vector/vector.cons/assign_move.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/assign_move.pass.cpp @@ -29,72 +29,72 @@ int main() l.push_back(i); lo.push_back(i); } - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector<MoveOnly, test_allocator<MoveOnly> > l2(test_allocator<MoveOnly>(5)); l2 = std::move(l); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); - assert(is_contiguous_container_asan_correct(l2)); + assert(is_contiguous_container_asan_correct(l2)); } { std::vector<MoveOnly, test_allocator<MoveOnly> > l(test_allocator<MoveOnly>(5)); std::vector<MoveOnly, test_allocator<MoveOnly> > lo(test_allocator<MoveOnly>(5)); - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector<MoveOnly, test_allocator<MoveOnly> > l2(test_allocator<MoveOnly>(6)); l2 = std::move(l); assert(l2 == lo); assert(!l.empty()); assert(l2.get_allocator() == test_allocator<MoveOnly>(6)); - assert(is_contiguous_container_asan_correct(l2)); + assert(is_contiguous_container_asan_correct(l2)); } { std::vector<MoveOnly, other_allocator<MoveOnly> > l(other_allocator<MoveOnly>(5)); std::vector<MoveOnly, other_allocator<MoveOnly> > lo(other_allocator<MoveOnly>(5)); - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector<MoveOnly, other_allocator<MoveOnly> > l2(other_allocator<MoveOnly>(6)); l2 = std::move(l); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); - assert(is_contiguous_container_asan_correct(l2)); + assert(is_contiguous_container_asan_correct(l2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{}); std::vector<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{}); - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector<MoveOnly, min_allocator<MoveOnly> > l2(min_allocator<MoveOnly>{}); l2 = std::move(l); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); - assert(is_contiguous_container_asan_correct(l2)); + assert(is_contiguous_container_asan_correct(l2)); } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 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 index e1b30bf11304d..8e5d2766c775d 100644 --- 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 @@ -26,7 +26,7 @@ void test ( Vec &v ) { v.assign(5, 6); assert(v.size() == 5); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(std::all_of(v.begin(), v.end(), is6)); } @@ -41,7 +41,7 @@ int main() test(d2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::vector<int, min_allocator<int>> V; V d1; 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 5e87c07ef70a9..e0542e751f449 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 @@ -32,16 +32,16 @@ test0() static_assert((noexcept(C()) == noexcept(typename C::allocator_type())), "" ); #endif C c; - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.empty()); assert(c.get_allocator() == typename C::allocator_type()); - assert(is_contiguous_container_asan_correct(c)); + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); #if TEST_STD_VER >= 11 C c1 = {}; - assert(c1.__invariants()); + LIBCPP_ASSERT(c1.__invariants()); assert(c1.empty()); assert(c1.get_allocator() == typename C::allocator_type()); - assert(is_contiguous_container_asan_correct(c1)); + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c1)); #endif } @@ -55,10 +55,10 @@ test1(const typename C::allocator_type& a) 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()); + LIBCPP_ASSERT(c.__invariants()); assert(c.empty()); assert(c.get_allocator() == a); - assert(is_contiguous_container_asan_correct(c)); + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); } int main() diff --git a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp index 36e231acce126..5542e91059d69 100644 --- a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp @@ -14,6 +14,7 @@ #include <vector> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "../../../stack_allocator.h" #include "min_allocator.h" @@ -24,9 +25,9 @@ void test(Iterator first, Iterator last) { C c(first, last); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == std::distance(first, last)); - assert(is_contiguous_container_asan_correct(c)); + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i, ++first) assert(*i == *first); } @@ -46,7 +47,7 @@ int main() test<std::vector<int, stack_allocator<int, 18> > >(bidirectional_iterator<const int*>(a), bidirectional_iterator<const int*>(an)); test<std::vector<int, stack_allocator<int, 18> > >(random_access_iterator<const int*>(a), random_access_iterator<const int*>(an)); test<std::vector<int, stack_allocator<int, 18> > >(a, an); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<std::vector<int, min_allocator<int>> >(input_iterator<const int*>(a), input_iterator<const int*>(an)); test<std::vector<int, min_allocator<int>> >(forward_iterator<const int*>(a), forward_iterator<const int*>(an)); test<std::vector<int, min_allocator<int>> >(bidirectional_iterator<const int*>(a), bidirectional_iterator<const int*>(an)); diff --git a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp index 7fa748a90d712..f40088ea3e861 100644 --- a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp @@ -15,6 +15,7 @@ #include <vector> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "../../../stack_allocator.h" #include "min_allocator.h" @@ -25,19 +26,19 @@ void test(Iterator first, Iterator last, const A& a) { C c(first, last, a); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == std::distance(first, last)); - assert(is_contiguous_container_asan_correct(c)); + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i, ++first) assert(*i == *first); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 template <class T> struct implicit_conv_allocator : min_allocator<T> { - implicit_conv_allocator(void* p) {} + implicit_conv_allocator(void*) {} implicit_conv_allocator(const implicit_conv_allocator&) = default; }; @@ -55,7 +56,7 @@ int main() test<std::vector<int> >(random_access_iterator<const int*>(a), random_access_iterator<const int*>(an), alloc); test<std::vector<int> >(a, an, alloc); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0}; int* an = a + sizeof(a)/sizeof(a[0]); diff --git a/test/std/containers/sequences/vector/vector.cons/construct_size.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_size.pass.cpp index e03389593f167..46e5ecdc9a568 100644 --- a/test/std/containers/sequences/vector/vector.cons/construct_size.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/construct_size.pass.cpp @@ -14,6 +14,7 @@ #include <vector> #include <cassert> +#include "test_macros.h" #include "DefaultOnly.h" #include "min_allocator.h" #include "test_allocator.h" @@ -23,16 +24,14 @@ template <class C> void test2(typename C::size_type n, typename C::allocator_type const& a = typename C::allocator_type ()) { -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER >= 14 C c(n, a); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == n); assert(c.get_allocator() == a); - assert(is_contiguous_container_asan_correct(c)); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i) assert(*i == typename C::value_type()); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #endif } @@ -41,14 +40,14 @@ void test1(typename C::size_type n) { C c(n); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == n); assert(c.get_allocator() == typename C::allocator_type()); - assert(is_contiguous_container_asan_correct(c)); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); +#if TEST_STD_VER >= 11 for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i) assert(*i == typename C::value_type()); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif } template <class C> @@ -64,7 +63,7 @@ int main() test<std::vector<int> >(50); test<std::vector<DefaultOnly> >(500); assert(DefaultOnly::count == 0); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<std::vector<int, min_allocator<int>> >(50); test<std::vector<DefaultOnly, min_allocator<DefaultOnly>> >(500); test2<std::vector<DefaultOnly, test_allocator<DefaultOnly>> >( 100, test_allocator<DefaultOnly>(23)); diff --git a/test/std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp index 5b6c498570446..d3774d1a6595b 100644 --- a/test/std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp @@ -14,6 +14,7 @@ #include <vector> #include <cassert> +#include "test_macros.h" #include "../../../stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -23,9 +24,9 @@ void test(typename C::size_type n, const typename C::value_type& x) { C c(n, x); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == n); - assert(is_contiguous_container_asan_correct(c)); + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i) assert(*i == x); } @@ -34,7 +35,7 @@ int main() { test<std::vector<int> >(50, 3); test<std::vector<int, stack_allocator<int, 50> > >(50, 5); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<std::vector<int, min_allocator<int>> >(50, 3); #endif } diff --git a/test/std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp index c62b84104aba7..4713aa1570622 100644 --- a/test/std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp @@ -13,6 +13,8 @@ #include <vector> #include <cassert> + +#include "test_macros.h" #include "min_allocator.h" #include "asan_testing.h" @@ -22,10 +24,10 @@ test(typename C::size_type n, const typename C::value_type& x, const typename C::allocator_type& a) { C c(n, x, a); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(a == c.get_allocator()); assert(c.size() == n); - assert(is_contiguous_container_asan_correct(c)); + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i) assert(*i == x); } @@ -33,7 +35,7 @@ test(typename C::size_type n, const typename C::value_type& x, int main() { test<std::vector<int> >(50, 3, std::allocator<int>()); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<std::vector<int, min_allocator<int>> >(50, 3, min_allocator<int>()); #endif } diff --git a/test/std/containers/sequences/vector/vector.cons/copy.pass.cpp b/test/std/containers/sequences/vector/vector.cons/copy.pass.cpp index 677963deeb845..105217bbf15cd 100644 --- a/test/std/containers/sequences/vector/vector.cons/copy.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/copy.pass.cpp @@ -13,6 +13,8 @@ #include <vector> #include <cassert> + +#include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -23,10 +25,10 @@ test(const C& x) { unsigned s = x.size(); C c(x); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == s); assert(c == x); - assert(is_contiguous_container_asan_correct(c)); + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); } int main() @@ -39,26 +41,24 @@ int main() { std::vector<int, test_allocator<int> > v(3, 2, test_allocator<int>(5)); std::vector<int, test_allocator<int> > v2 = v; - assert(is_contiguous_container_asan_correct(v)); - assert(is_contiguous_container_asan_correct(v2)); + assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v2)); assert(v2 == v); assert(v2.get_allocator() == v.get_allocator()); - assert(is_contiguous_container_asan_correct(v)); - assert(is_contiguous_container_asan_correct(v2)); + assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v2)); } -#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE +#if TEST_STD_VER >= 11 { std::vector<int, other_allocator<int> > v(3, 2, other_allocator<int>(5)); std::vector<int, other_allocator<int> > v2 = v; - assert(is_contiguous_container_asan_correct(v)); - assert(is_contiguous_container_asan_correct(v2)); + assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v2)); assert(v2 == v); assert(v2.get_allocator() == other_allocator<int>(-2)); - assert(is_contiguous_container_asan_correct(v)); - assert(is_contiguous_container_asan_correct(v2)); + assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v2)); } -#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE -#if __cplusplus >= 201103L { int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0}; int* an = a + sizeof(a)/sizeof(a[0]); @@ -67,12 +67,12 @@ int main() { std::vector<int, min_allocator<int> > v(3, 2, min_allocator<int>()); std::vector<int, min_allocator<int> > v2 = v; - assert(is_contiguous_container_asan_correct(v)); - assert(is_contiguous_container_asan_correct(v2)); + assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v2)); assert(v2 == v); assert(v2.get_allocator() == v.get_allocator()); - assert(is_contiguous_container_asan_correct(v)); - assert(is_contiguous_container_asan_correct(v2)); + assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v2)); } #endif } diff --git a/test/std/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp b/test/std/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp index 128328c2a7d26..47259c747332d 100644 --- a/test/std/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp @@ -13,6 +13,8 @@ #include <vector> #include <cassert> + +#include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -23,10 +25,10 @@ test(const C& x, const typename C::allocator_type& a) { unsigned s = x.size(); C c(x, a); - assert(c.__invariants()); + LIBCPP_ASSERT(c.__invariants()); assert(c.size() == s); assert(c == x); - assert(is_contiguous_container_asan_correct(c)); + LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); } int main() @@ -48,7 +50,7 @@ int main() assert(l2 == l); assert(l2.get_allocator() == other_allocator<int>(3)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0}; int* an = a + sizeof(a)/sizeof(a[0]); 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 60f7b72c9477b..b244f75f21d4f 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 @@ -14,6 +14,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <vector> #include <cassert> @@ -30,7 +32,6 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::vector<MoveOnly> C; static_assert(std::is_nothrow_default_constructible<C>::value, ""); @@ -47,5 +48,4 @@ int main() typedef std::vector<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp b/test/std/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp index 0e2cae9ee935e..bd538120442d0 100644 --- a/test/std/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp @@ -11,14 +11,14 @@ // ~vector() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <vector> #include <cassert> #include "MoveOnly.h" #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_alloc { @@ -27,11 +27,8 @@ struct some_alloc ~some_alloc() noexcept(false); }; -#endif - int main() { -#if __has_feature(cxx_noexcept) { typedef std::vector<MoveOnly> C; static_assert(std::is_nothrow_destructible<C>::value, ""); @@ -48,5 +45,4 @@ int main() typedef std::vector<MoveOnly, some_alloc<MoveOnly>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/sequences/vector/vector.cons/initializer_list.pass.cpp b/test/std/containers/sequences/vector/vector.cons/initializer_list.pass.cpp index 7eb834ff38778..408bcc3b14990 100644 --- a/test/std/containers/sequences/vector/vector.cons/initializer_list.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/initializer_list.pass.cpp @@ -22,17 +22,17 @@ int main() { std::vector<int> d = {3, 4, 5, 6}; assert(d.size() == 4); - assert(is_contiguous_container_asan_correct(d)); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); assert(d[3] == 6); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> d = {3, 4, 5, 6}; assert(d.size() == 4); - assert(is_contiguous_container_asan_correct(d)); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); diff --git a/test/std/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp b/test/std/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp index 5d7ae884e3826..f4c3b5c1e8e0a 100644 --- a/test/std/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp @@ -25,18 +25,18 @@ int main() std::vector<int, test_allocator<int>> d({3, 4, 5, 6}, test_allocator<int>(3)); assert(d.get_allocator() == test_allocator<int>(3)); assert(d.size() == 4); - assert(is_contiguous_container_asan_correct(d)); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); assert(d[3] == 6); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> d({3, 4, 5, 6}, min_allocator<int>()); assert(d.get_allocator() == min_allocator<int>()); assert(d.size() == 4); - assert(is_contiguous_container_asan_correct(d)); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); diff --git a/test/std/containers/sequences/vector/vector.cons/move.pass.cpp b/test/std/containers/sequences/vector/vector.cons/move.pass.cpp index fb419d825d2b6..d51b364f3ba0b 100644 --- a/test/std/containers/sequences/vector/vector.cons/move.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/move.pass.cpp @@ -24,79 +24,79 @@ int main() { std::vector<MoveOnly, test_allocator<MoveOnly> > l(test_allocator<MoveOnly>(5)); std::vector<MoveOnly, test_allocator<MoveOnly> > lo(test_allocator<MoveOnly>(5)); - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector<MoveOnly, test_allocator<MoveOnly> > l2 = std::move(l); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); - assert(is_contiguous_container_asan_correct(l2)); + assert(is_contiguous_container_asan_correct(l2)); } { std::vector<MoveOnly, other_allocator<MoveOnly> > l(other_allocator<MoveOnly>(5)); std::vector<MoveOnly, other_allocator<MoveOnly> > lo(other_allocator<MoveOnly>(5)); - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector<MoveOnly, other_allocator<MoveOnly> > l2 = std::move(l); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); - assert(is_contiguous_container_asan_correct(l2)); + assert(is_contiguous_container_asan_correct(l2)); } { int a1[] = {1, 3, 7, 9, 10}; std::vector<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0])); - assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c1)); std::vector<int>::const_iterator i = c1.begin(); std::vector<int> c2 = std::move(c1); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c2)); std::vector<int>::iterator j = c2.erase(i); assert(*j == 3); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{}); std::vector<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{}); - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector<MoveOnly, min_allocator<MoveOnly> > l2 = std::move(l); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); - assert(is_contiguous_container_asan_correct(l2)); + assert(is_contiguous_container_asan_correct(l2)); } { int a1[] = {1, 3, 7, 9, 10}; std::vector<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0])); - assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c1)); std::vector<int, min_allocator<int>>::const_iterator i = c1.begin(); std::vector<int, min_allocator<int>> c2 = std::move(c1); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c2)); std::vector<int, min_allocator<int>>::iterator j = c2.erase(i); assert(*j == 3); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c2)); } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES diff --git a/test/std/containers/sequences/vector/vector.cons/move_alloc.pass.cpp b/test/std/containers/sequences/vector/vector.cons/move_alloc.pass.cpp index aef96917cb32e..fcdd35ae1157e 100644 --- a/test/std/containers/sequences/vector/vector.cons/move_alloc.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/move_alloc.pass.cpp @@ -24,75 +24,75 @@ int main() { std::vector<MoveOnly, test_allocator<MoveOnly> > l(test_allocator<MoveOnly>(5)); std::vector<MoveOnly, test_allocator<MoveOnly> > lo(test_allocator<MoveOnly>(5)); - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector<MoveOnly, test_allocator<MoveOnly> > l2(std::move(l), test_allocator<MoveOnly>(6)); assert(l2 == lo); assert(!l.empty()); assert(l2.get_allocator() == test_allocator<MoveOnly>(6)); - assert(is_contiguous_container_asan_correct(l2)); + assert(is_contiguous_container_asan_correct(l2)); } { std::vector<MoveOnly, test_allocator<MoveOnly> > l(test_allocator<MoveOnly>(5)); std::vector<MoveOnly, test_allocator<MoveOnly> > lo(test_allocator<MoveOnly>(5)); - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector<MoveOnly, test_allocator<MoveOnly> > l2(std::move(l), test_allocator<MoveOnly>(5)); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == test_allocator<MoveOnly>(5)); - assert(is_contiguous_container_asan_correct(l2)); + assert(is_contiguous_container_asan_correct(l2)); } { std::vector<MoveOnly, other_allocator<MoveOnly> > l(other_allocator<MoveOnly>(5)); std::vector<MoveOnly, other_allocator<MoveOnly> > lo(other_allocator<MoveOnly>(5)); - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector<MoveOnly, other_allocator<MoveOnly> > l2(std::move(l), other_allocator<MoveOnly>(4)); assert(l2 == lo); assert(!l.empty()); assert(l2.get_allocator() == other_allocator<MoveOnly>(4)); - assert(is_contiguous_container_asan_correct(l2)); + assert(is_contiguous_container_asan_correct(l2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{}); std::vector<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{}); - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } - assert(is_contiguous_container_asan_correct(l)); - assert(is_contiguous_container_asan_correct(lo)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector<MoveOnly, min_allocator<MoveOnly> > l2(std::move(l), min_allocator<MoveOnly>()); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == min_allocator<MoveOnly>()); - assert(is_contiguous_container_asan_correct(l2)); + assert(is_contiguous_container_asan_correct(l2)); } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES diff --git a/test/std/containers/sequences/vector/vector.cons/move_assign_noexcept.pass.cpp b/test/std/containers/sequences/vector/vector.cons/move_assign_noexcept.pass.cpp index c09224497966e..14ca7155b5a17 100644 --- a/test/std/containers/sequences/vector/vector.cons/move_assign_noexcept.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/move_assign_noexcept.pass.cpp @@ -16,6 +16,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <vector> #include <cassert> @@ -33,7 +35,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -46,7 +48,7 @@ template <class T> struct some_alloc3 { typedef T value_type; - + some_alloc3() {} some_alloc3(const some_alloc3&); void deallocate(void*, unsigned) {} @@ -58,7 +60,6 @@ struct some_alloc3 int main() { -#if __has_feature(cxx_noexcept) { typedef std::vector<MoveOnly> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); @@ -91,6 +92,4 @@ int main() static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } #endif - -#endif } 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 b7bbfaa421c48..a1e3a632f1f28 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 @@ -14,6 +14,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <vector> #include <cassert> @@ -29,7 +31,6 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::vector<MoveOnly> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); @@ -51,5 +52,4 @@ int main() static_assert(!std::is_nothrow_move_constructible<C>::value, ""); #endif } -#endif } diff --git a/test/std/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp b/test/std/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp index 592b714627677..4e5a204136839 100644 --- a/test/std/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp @@ -24,18 +24,18 @@ int main() std::vector<int> d; d = {3, 4, 5, 6}; assert(d.size() == 4); - assert(is_contiguous_container_asan_correct(d)); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); assert(d[3] == 6); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> d; d = {3, 4, 5, 6}; assert(d.size() == 4); - assert(is_contiguous_container_asan_correct(d)); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); diff --git a/test/std/containers/sequences/vector/vector.data/data.pass.cpp b/test/std/containers/sequences/vector/vector.data/data.pass.cpp index aed56bc09310e..f6c0575d958cd 100644 --- a/test/std/containers/sequences/vector/vector.data/data.pass.cpp +++ b/test/std/containers/sequences/vector/vector.data/data.pass.cpp @@ -17,28 +17,47 @@ #include "min_allocator.h" #include "asan_testing.h" +struct Nasty { + Nasty() : i_(0) {} + Nasty(int i) : i_(i) {} + ~Nasty() {} + + Nasty * operator&() const { assert(false); return nullptr; } + int i_; + }; + int main() { { std::vector<int> v; assert(v.data() == 0); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { std::vector<int> v(100); - assert(v.data() == &v.front()); - assert(is_contiguous_container_asan_correct(v)); + assert(v.data() == std::addressof(v.front())); + assert(is_contiguous_container_asan_correct(v)); + } + { + std::vector<Nasty> v(100); + assert(v.data() == std::addressof(v.front())); + assert(is_contiguous_container_asan_correct(v)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> v; assert(v.data() == 0); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { std::vector<int, min_allocator<int>> v(100); - assert(v.data() == &v.front()); - assert(is_contiguous_container_asan_correct(v)); + assert(v.data() == std::addressof(v.front())); + assert(is_contiguous_container_asan_correct(v)); + } + { + std::vector<Nasty, min_allocator<Nasty>> v(100); + assert(v.data() == std::addressof(v.front())); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/std/containers/sequences/vector/vector.data/data_const.pass.cpp b/test/std/containers/sequences/vector/vector.data/data_const.pass.cpp index cb6062694e40e..c97ad29708b81 100644 --- a/test/std/containers/sequences/vector/vector.data/data_const.pass.cpp +++ b/test/std/containers/sequences/vector/vector.data/data_const.pass.cpp @@ -17,28 +17,47 @@ #include "min_allocator.h" #include "asan_testing.h" +struct Nasty { + Nasty() : i_(0) {} + Nasty(int i) : i_(i) {} + ~Nasty() {} + + Nasty * operator&() const { assert(false); return nullptr; } + int i_; + }; + int main() { { const std::vector<int> v; assert(v.data() == 0); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { const std::vector<int> v(100); - assert(v.data() == &v.front()); - assert(is_contiguous_container_asan_correct(v)); + assert(v.data() == std::addressof(v.front())); + assert(is_contiguous_container_asan_correct(v)); + } + { + std::vector<Nasty> v(100); + assert(v.data() == std::addressof(v.front())); + assert(is_contiguous_container_asan_correct(v)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { const std::vector<int, min_allocator<int>> v; assert(v.data() == 0); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { const std::vector<int, min_allocator<int>> v(100); assert(v.data() == &v.front()); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); + } + { + std::vector<Nasty, min_allocator<Nasty>> v(100); + assert(v.data() == std::addressof(v.front())); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/std/containers/sequences/vector/vector.modifiers/emplace.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/emplace.pass.cpp index 8af6bdacd0a8c..8bcc23979668b 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/emplace.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/emplace.pass.cpp @@ -67,7 +67,7 @@ int main() assert(c.size() == 1); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); i = c.emplace(c.cend(), 3, 4.5); assert(i == c.end()-1); assert(c.size() == 2); @@ -75,7 +75,7 @@ int main() assert(c.front().getd() == 3.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); i = c.emplace(c.cbegin()+1, 4, 6.5); assert(i == c.begin()+1); assert(c.size() == 3); @@ -85,7 +85,7 @@ int main() assert(c[1].getd() == 6.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); } { std::vector<A, stack_allocator<A, 7> > c; @@ -94,7 +94,7 @@ int main() assert(c.size() == 1); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); i = c.emplace(c.cend(), 3, 4.5); assert(i == c.end()-1); assert(c.size() == 2); @@ -102,7 +102,7 @@ int main() assert(c.front().getd() == 3.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); i = c.emplace(c.cbegin()+1, 4, 6.5); assert(i == c.begin()+1); assert(c.size() == 3); @@ -112,7 +112,7 @@ int main() assert(c[1].getd() == 6.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); } #if _LIBCPP_DEBUG >= 1 { @@ -122,7 +122,7 @@ int main() assert(false); } #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<A, min_allocator<A>> c; std::vector<A, min_allocator<A>>::iterator i = c.emplace(c.cbegin(), 2, 3.5); diff --git a/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp index bbf91a4255d78..61ccade76b02a 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp @@ -15,6 +15,7 @@ #include <cassert> #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "test_allocator.h" #include "asan_testing.h" #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -62,14 +63,14 @@ int main() assert(c.size() == 1); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); c.emplace_back(3, 4.5); assert(c.size() == 2); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); } { std::vector<A, stack_allocator<A, 4> > c; @@ -77,30 +78,38 @@ int main() assert(c.size() == 1); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); c.emplace_back(3, 4.5); assert(c.size() == 2); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<A, min_allocator<A>> c; c.emplace_back(2, 3.5); assert(c.size() == 1); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); c.emplace_back(3, 4.5); assert(c.size() == 2); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); + } + { + std::vector<Tag_X, TaggingAllocator<Tag_X>> c; + c.emplace_back(); + assert(c.size() == 1); + c.emplace_back(1, 2, 3); + assert(c.size() == 2); + assert(is_contiguous_container_asan_correct(c)); } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES diff --git a/test/std/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp index 85a47073bcb2e..7e4aed8c1b5e8 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp @@ -23,39 +23,39 @@ int main() { std::vector<int> v; v.reserve(3); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v = { 1, 2, 3 }; v.emplace(v.begin(), v.back()); assert(v[0] == 3); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { std::vector<int> v; v.reserve(4); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v = { 1, 2, 3 }; v.emplace(v.begin(), v.back()); assert(v[0] == 3); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> v; v.reserve(3); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v = { 1, 2, 3 }; v.emplace(v.begin(), v.back()); assert(v[0] == 3); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } { std::vector<int, min_allocator<int>> v; v.reserve(4); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); v = { 1, 2, 3 }; v.emplace(v.begin(), v.back()); assert(v[0] == 3); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); } #endif #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS diff --git a/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp index 4fa07b729a75a..dbdccf13b72ec 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp @@ -24,7 +24,7 @@ int main() int a1[] = {1, 2, 3}; std::vector<int> l1(a1, a1+3); std::vector<int>::const_iterator i = l1.begin(); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); ++i; std::vector<int>::iterator j = l1.erase(i); assert(l1.size() == 2); @@ -32,25 +32,25 @@ int main() assert(*j == 3); assert(*l1.begin() == 1); assert(*next(l1.begin()) == 3); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); j = l1.erase(j); assert(j == l1.end()); assert(l1.size() == 1); assert(distance(l1.begin(), l1.end()) == 1); assert(*l1.begin() == 1); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); j = l1.erase(l1.begin()); assert(j == l1.end()); assert(l1.size() == 0); assert(distance(l1.begin(), l1.end()) == 0); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 2, 3}; std::vector<int, min_allocator<int>> l1(a1, a1+3); std::vector<int, min_allocator<int>>::const_iterator i = l1.begin(); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); ++i; std::vector<int, min_allocator<int>>::iterator j = l1.erase(i); assert(l1.size() == 2); @@ -58,18 +58,18 @@ int main() assert(*j == 3); assert(*l1.begin() == 1); assert(*next(l1.begin()) == 3); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); j = l1.erase(j); assert(j == l1.end()); assert(l1.size() == 1); assert(distance(l1.begin(), l1.end()) == 1); assert(*l1.begin() == 1); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); j = l1.erase(l1.begin()); assert(j == l1.end()); assert(l1.size() == 0); assert(distance(l1.begin(), l1.end()) == 0); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); } #endif } diff --git a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_db1.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_db1.pass.cpp index 0478d24c79f6f..b2c22d6ae696a 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_db1.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_db1.pass.cpp @@ -31,7 +31,7 @@ int main() l1.erase(i); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 2, 3}; std::vector<int, min_allocator<int>> l1(a1, a1+3); diff --git a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_db2.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_db2.pass.cpp index c394f197402b1..da0b6d4a059bb 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_db2.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_db2.pass.cpp @@ -32,7 +32,7 @@ int main() l1.erase(i); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 2, 3}; std::vector<int, min_allocator<int>> l1(a1, a1+3); diff --git a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp index 2e81d133cde00..f7fa0dba27e8f 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp @@ -23,106 +23,106 @@ int main() int a1[] = {1, 2, 3}; { std::vector<int> l1(a1, a1+3); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); std::vector<int>::iterator i = l1.erase(l1.cbegin(), l1.cbegin()); assert(l1.size() == 3); assert(distance(l1.cbegin(), l1.cend()) == 3); assert(i == l1.begin()); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector<int> l1(a1, a1+3); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); std::vector<int>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin())); assert(l1.size() == 2); assert(distance(l1.cbegin(), l1.cend()) == 2); assert(i == l1.begin()); assert(l1 == std::vector<int>(a1+1, a1+3)); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector<int> l1(a1, a1+3); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); std::vector<int>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 2)); assert(l1.size() == 1); assert(distance(l1.cbegin(), l1.cend()) == 1); assert(i == l1.begin()); assert(l1 == std::vector<int>(a1+2, a1+3)); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector<int> l1(a1, a1+3); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); std::vector<int>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 3)); assert(l1.size() == 0); assert(distance(l1.cbegin(), l1.cend()) == 0); assert(i == l1.begin()); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector<std::vector<int> > outer(2, std::vector<int>(1)); - assert(is_contiguous_container_asan_correct(outer)); - assert(is_contiguous_container_asan_correct(outer[0])); - assert(is_contiguous_container_asan_correct(outer[1])); + assert(is_contiguous_container_asan_correct(outer)); + assert(is_contiguous_container_asan_correct(outer[0])); + assert(is_contiguous_container_asan_correct(outer[1])); outer.erase(outer.begin(), outer.begin()); assert(outer.size() == 2); assert(outer[0].size() == 1); assert(outer[1].size() == 1); - assert(is_contiguous_container_asan_correct(outer)); - assert(is_contiguous_container_asan_correct(outer[0])); - assert(is_contiguous_container_asan_correct(outer[1])); + assert(is_contiguous_container_asan_correct(outer)); + assert(is_contiguous_container_asan_correct(outer[0])); + assert(is_contiguous_container_asan_correct(outer[1])); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> l1(a1, a1+3); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), l1.cbegin()); assert(l1.size() == 3); assert(distance(l1.cbegin(), l1.cend()) == 3); assert(i == l1.begin()); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector<int, min_allocator<int>> l1(a1, a1+3); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin())); assert(l1.size() == 2); assert(distance(l1.cbegin(), l1.cend()) == 2); assert(i == l1.begin()); assert((l1 == std::vector<int, min_allocator<int>>(a1+1, a1+3))); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector<int, min_allocator<int>> l1(a1, a1+3); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 2)); assert(l1.size() == 1); assert(distance(l1.cbegin(), l1.cend()) == 1); assert(i == l1.begin()); assert((l1 == std::vector<int, min_allocator<int>>(a1+2, a1+3))); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector<int, min_allocator<int>> l1(a1, a1+3); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 3)); assert(l1.size() == 0); assert(distance(l1.cbegin(), l1.cend()) == 0); assert(i == l1.begin()); - assert(is_contiguous_container_asan_correct(l1)); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector<std::vector<int, min_allocator<int>>, min_allocator<std::vector<int, min_allocator<int>>>> outer(2, std::vector<int, min_allocator<int>>(1)); - assert(is_contiguous_container_asan_correct(outer)); - assert(is_contiguous_container_asan_correct(outer[0])); - assert(is_contiguous_container_asan_correct(outer[1])); + assert(is_contiguous_container_asan_correct(outer)); + assert(is_contiguous_container_asan_correct(outer[0])); + assert(is_contiguous_container_asan_correct(outer[1])); outer.erase(outer.begin(), outer.begin()); assert(outer.size() == 2); assert(outer[0].size() == 1); assert(outer[1].size() == 1); - assert(is_contiguous_container_asan_correct(outer)); - assert(is_contiguous_container_asan_correct(outer[0])); - assert(is_contiguous_container_asan_correct(outer[1])); + assert(is_contiguous_container_asan_correct(outer)); + assert(is_contiguous_container_asan_correct(outer[0])); + assert(is_contiguous_container_asan_correct(outer[1])); } #endif } diff --git a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db1.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db1.pass.cpp index af6d0f757892a..14d3ca803ca31 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db1.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db1.pass.cpp @@ -31,7 +31,7 @@ int main() std::vector<int>::iterator i = l1.erase(l2.cbegin(), l1.cbegin()+1); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 2, 3}; std::vector<int, min_allocator<int>> l1(a1, a1+3); diff --git a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db2.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db2.pass.cpp index eee2c66c5c8ca..04c040a8f7977 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db2.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db2.pass.cpp @@ -31,7 +31,7 @@ int main() std::vector<int>::iterator i = l1.erase(l1.cbegin(), l2.cbegin()+1); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 2, 3}; std::vector<int, min_allocator<int>> l1(a1, a1+3); diff --git a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db3.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db3.pass.cpp index 505067d05a1af..ba183a83f0b1d 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db3.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db3.pass.cpp @@ -31,7 +31,7 @@ int main() std::vector<int>::iterator i = l1.erase(l2.cbegin(), l2.cbegin()+1); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 2, 3}; std::vector<int, min_allocator<int>> l1(a1, a1+3); diff --git a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db4.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db4.pass.cpp index c7e4131cb49ce..0fb8071fc679e 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db4.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter_db4.pass.cpp @@ -30,7 +30,7 @@ int main() std::vector<int>::iterator i = l1.erase(l1.cbegin()+1, l1.cbegin()); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 2, 3}; std::vector<int, min_allocator<int>> l1(a1, a1+3); diff --git a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp index 30b8017880136..b0fe123aac480 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp @@ -24,7 +24,7 @@ int main() std::vector<int> d(10, 1); std::vector<int>::iterator i = d.insert(d.cbegin() + 2, {3, 4, 5, 6}); assert(d.size() == 14); - assert(is_contiguous_container_asan_correct(d)); + assert(is_contiguous_container_asan_correct(d)); assert(i == d.begin() + 2); assert(d[0] == 1); assert(d[1] == 1); @@ -41,12 +41,12 @@ int main() assert(d[12] == 1); assert(d[13] == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> d(10, 1); std::vector<int, min_allocator<int>>::iterator i = d.insert(d.cbegin() + 2, {3, 4, 5, 6}); assert(d.size() == 14); - assert(is_contiguous_container_asan_correct(d)); + assert(is_contiguous_container_asan_correct(d)); assert(i == d.begin() + 2); assert(d[0] == 1); assert(d[1] == 1); diff --git a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp index 782437be87f82..b8953021187f5 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp @@ -32,7 +32,7 @@ int main() std::vector<int>::iterator i = v.insert(v.cbegin() + 10, input_iterator<const int*>(a), input_iterator<const int*>(a+N)); assert(v.size() == 100 + N); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -49,7 +49,7 @@ int main() std::vector<int>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a), forward_iterator<const int*>(a+N)); assert(v.size() == 100 + N); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -102,7 +102,7 @@ int main() std::vector<int>::iterator i = v.insert(v.cbegin() + 10, input_iterator<const int*>(a), input_iterator<const int*>(a+N)); assert(v.size() == 100 + N); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -119,7 +119,7 @@ int main() std::vector<int>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a), forward_iterator<const int*>(a+N)); assert(v.size() == 100 + N); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -140,7 +140,7 @@ int main() assert(false); } #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> v(100); int a[] = {1, 2, 3, 4, 5}; @@ -148,7 +148,7 @@ int main() std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, input_iterator<const int*>(a), input_iterator<const int*>(a+N)); assert(v.size() == 100 + N); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -165,7 +165,7 @@ int main() std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a), forward_iterator<const int*>(a+N)); assert(v.size() == 100 + N); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) diff --git a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp index e12ec45febfc2..e1ad6be054e5c 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp @@ -29,7 +29,7 @@ int main() std::vector<MoveOnly> v(100); std::vector<MoveOnly>::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3)); assert(v.size() == 101); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -42,7 +42,7 @@ int main() std::vector<MoveOnly, stack_allocator<MoveOnly, 300> > v(100); std::vector<MoveOnly, stack_allocator<MoveOnly, 300> >::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3)); assert(v.size() == 101); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -59,12 +59,12 @@ int main() assert(false); } #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<MoveOnly, min_allocator<MoveOnly>> v(100); std::vector<MoveOnly, min_allocator<MoveOnly>>::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3)); assert(v.size() == 101); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) diff --git a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp index 6997284f258c1..ed4d6c976e9cf 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp @@ -27,7 +27,7 @@ int main() std::vector<int> v(100); std::vector<int>::iterator i = v.insert(v.cbegin() + 10, 5, 1); assert(v.size() == 105); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -43,7 +43,7 @@ int main() size_t sz = v.size(); std::vector<int>::iterator i = v.insert(v.cbegin() + 10, 5, 1); assert(v.size() == sz + 5); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -59,7 +59,7 @@ int main() size_t sz = v.size(); std::vector<int>::iterator i = v.insert(v.cbegin() + 10, 5, 1); assert(v.size() == sz + 5); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -73,7 +73,7 @@ int main() std::vector<int, stack_allocator<int, 300> > v(100); std::vector<int, stack_allocator<int, 300> >::iterator i = v.insert(v.cbegin() + 10, 5, 1); assert(v.size() == 105); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -91,12 +91,12 @@ int main() assert(false); } #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> v(100); std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, 5, 1); assert(v.size() == 105); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -110,7 +110,7 @@ int main() std::vector<int, min_allocator<int>> v(100); std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, 5, 1); assert(v.size() == 105); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) diff --git a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp index 782e752157a77..ba030e9e3fb78 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp @@ -27,7 +27,7 @@ int main() std::vector<int> v(100); std::vector<int>::iterator i = v.insert(v.cbegin() + 10, 1); assert(v.size() == 101); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -42,7 +42,7 @@ int main() size_t sz = v.size(); std::vector<int>::iterator i = v.insert(v.cbegin() + 10, 1); assert(v.size() == sz + 1); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -58,7 +58,7 @@ int main() size_t sz = v.size(); std::vector<int>::iterator i = v.insert(v.cbegin() + 10, 1); assert(v.size() == sz + 1); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -71,7 +71,7 @@ int main() std::vector<int, stack_allocator<int, 300> > v(100); std::vector<int, stack_allocator<int, 300> >::iterator i = v.insert(v.cbegin() + 10, 1); assert(v.size() == 101); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -89,12 +89,12 @@ int main() assert(false); } #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> v(100); std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, 1); assert(v.size() == 101); - assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) diff --git a/test/std/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp index 62fa60103baa6..c81e41904fc8e 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp @@ -37,9 +37,9 @@ int main() #if _LIBCPP_DEBUG >= 1 c.pop_back(); assert(false); -#endif +#endif } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> c; c.push_back(1); @@ -49,7 +49,7 @@ int main() #if _LIBCPP_DEBUG >= 1 c.pop_back(); assert(false); -#endif +#endif } -#endif +#endif } diff --git a/test/std/containers/sequences/vector/vector.modifiers/push_back.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/push_back.pass.cpp index eeeba6242d935..bef3b9c8d17dd 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/push_back.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/push_back.pass.cpp @@ -23,27 +23,27 @@ int main() std::vector<int> c; c.push_back(0); assert(c.size() == 1); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(1); assert(c.size() == 2); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(2); assert(c.size() == 3); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(3); assert(c.size() == 4); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(4); assert(c.size() == 5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); } @@ -51,56 +51,56 @@ int main() std::vector<int, stack_allocator<int, 15> > c; c.push_back(0); assert(c.size() == 1); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(1); assert(c.size() == 2); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(2); assert(c.size() == 3); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(3); assert(c.size() == 4); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(4); assert(c.size() == 5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<int, min_allocator<int>> c; c.push_back(0); assert(c.size() == 1); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(1); assert(c.size() == 2); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(2); assert(c.size() == 3); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(3); assert(c.size() == 4); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(4); assert(c.size() == 5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); } diff --git a/test/std/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp index 785225357d4b7..5fa93aab89c72 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp @@ -31,7 +31,7 @@ class CMyClass { private: int fMagicValue; int fTag; - + private: static int kStartedConstructionMagicValue; private: static int kFinishedConstructionMagicValue; }; @@ -73,8 +73,8 @@ int main() vec.push_back(instance); std::vector<CMyClass> vec2(vec); - assert(is_contiguous_container_asan_correct(vec)); - assert(is_contiguous_container_asan_correct(vec2)); + assert(is_contiguous_container_asan_correct(vec)); + assert(is_contiguous_container_asan_correct(vec2)); gCopyConstructorShouldThow = true; try { @@ -82,6 +82,6 @@ int main() } catch (...) { assert(vec==vec2); - assert(is_contiguous_container_asan_correct(vec)); + assert(is_contiguous_container_asan_correct(vec)); } } diff --git a/test/std/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp index b143cd773b422..64762eb374e8a 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp @@ -25,27 +25,27 @@ int main() std::vector<MoveOnly> c; c.push_back(MoveOnly(0)); assert(c.size() == 1); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(1)); assert(c.size() == 2); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(2)); assert(c.size() == 3); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(3)); assert(c.size() == 4); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(4)); assert(c.size() == 5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); } @@ -53,56 +53,56 @@ int main() std::vector<MoveOnly, stack_allocator<MoveOnly, 15> > c; c.push_back(MoveOnly(0)); assert(c.size() == 1); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(1)); assert(c.size() == 2); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(2)); assert(c.size() == 3); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(3)); assert(c.size() == 4); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(4)); assert(c.size() == 5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::vector<MoveOnly, min_allocator<MoveOnly>> c; c.push_back(MoveOnly(0)); assert(c.size() == 1); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(1)); assert(c.size() == 2); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(2)); assert(c.size() == 3); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(3)); assert(c.size() == 4); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(4)); assert(c.size() == 5); - assert(is_contiguous_container_asan_correct(c)); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); } diff --git a/test/std/containers/sequences/vector/vector.special/db_swap_1.pass.cpp b/test/std/containers/sequences/vector/vector.special/db_swap_1.pass.cpp index e7f6a0011e1a1..1bb761181422d 100644 --- a/test/std/containers/sequences/vector/vector.special/db_swap_1.pass.cpp +++ b/test/std/containers/sequences/vector/vector.special/db_swap_1.pass.cpp @@ -37,7 +37,7 @@ int main() c1.erase(i1); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; diff --git a/test/std/containers/sequences/vector/vector.special/swap.pass.cpp b/test/std/containers/sequences/vector/vector.special/swap.pass.cpp index 96aaf7131f533..3d01129fa0087 100644 --- a/test/std/containers/sequences/vector/vector.special/swap.pass.cpp +++ b/test/std/containers/sequences/vector/vector.special/swap.pass.cpp @@ -26,56 +26,56 @@ int main() int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0])); std::vector<int> c2(a2, a2+sizeof(a2)/sizeof(a2[0])); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert(c1 == std::vector<int>(a2, a2+sizeof(a2)/sizeof(a2[0]))); assert(c2 == std::vector<int>(a1, a1+sizeof(a1)/sizeof(a1[0]))); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector<int> c1(a1, a1); std::vector<int> c2(a2, a2+sizeof(a2)/sizeof(a2[0])); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert(c1 == std::vector<int>(a2, a2+sizeof(a2)/sizeof(a2[0]))); assert(c2.empty()); assert(distance(c2.begin(), c2.end()) == 0); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0])); std::vector<int> c2(a2, a2); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert(c1.empty()); assert(distance(c1.begin(), c1.end()) == 0); assert(c2 == std::vector<int>(a1, a1+sizeof(a1)/sizeof(a1[0]))); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector<int> c1(a1, a1); std::vector<int> c2(a2, a2); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert(c1.empty()); assert(distance(c1.begin(), c1.end()) == 0); assert(c2.empty()); assert(distance(c2.begin(), c2.end()) == 0); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } #ifndef _LIBCPP_DEBUG_LEVEL // This test known to result in undefined behavior detected by _LIBCPP_DEBUG_LEVEL >= 1 @@ -98,72 +98,72 @@ int main() typedef other_allocator<int> A; std::vector<int, A> c1(a1, a1+sizeof(a1)/sizeof(a1[0]), A(1)); std::vector<int, A> c2(a2, a2+sizeof(a2)/sizeof(a2[0]), A(2)); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert((c1 == std::vector<int, A>(a2, a2+sizeof(a2)/sizeof(a2[0])))); assert(c1.get_allocator() == A(2)); assert((c2 == std::vector<int, A>(a1, a1+sizeof(a1)/sizeof(a1[0])))); assert(c2.get_allocator() == A(1)); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0])); std::vector<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0])); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert((c1 == std::vector<int, min_allocator<int>>(a2, a2+sizeof(a2)/sizeof(a2[0])))); assert((c2 == std::vector<int, min_allocator<int>>(a1, a1+sizeof(a1)/sizeof(a1[0])))); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector<int, min_allocator<int>> c1(a1, a1); std::vector<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0])); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert((c1 == std::vector<int, min_allocator<int>>(a2, a2+sizeof(a2)/sizeof(a2[0])))); assert(c2.empty()); assert(distance(c2.begin(), c2.end()) == 0); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0])); std::vector<int, min_allocator<int>> c2(a2, a2); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert(c1.empty()); assert(distance(c1.begin(), c1.end()) == 0); assert((c2 == std::vector<int, min_allocator<int>>(a1, a1+sizeof(a1)/sizeof(a1[0])))); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector<int, min_allocator<int>> c1(a1, a1); std::vector<int, min_allocator<int>> c2(a2, a2); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert(c1.empty()); assert(distance(c1.begin(), c1.end()) == 0); assert(c2.empty()); assert(distance(c2.begin(), c2.end()) == 0); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } #ifndef _LIBCPP_DEBUG_LEVEL // This test known to result in undefined behavior detected by _LIBCPP_DEBUG_LEVEL >= 1 @@ -173,15 +173,15 @@ int main() typedef min_allocator<int> A; std::vector<int, A> c1(a1, a1+sizeof(a1)/sizeof(a1[0]), A()); std::vector<int, A> c2(a2, a2+sizeof(a2)/sizeof(a2[0]), A()); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert((c1 == std::vector<int, A>(a2, a2+sizeof(a2)/sizeof(a2[0])))); assert(c1.get_allocator() == A()); assert((c2 == std::vector<int, A>(a1, a1+sizeof(a1)/sizeof(a1[0])))); assert(c2.get_allocator() == A()); - assert(is_contiguous_container_asan_correct(c1)); - assert(is_contiguous_container_asan_correct(c2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } #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 1d00ff387480c..89fa301ad9bd8 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <vector> // void swap(vector& c) @@ -22,6 +24,7 @@ #include <vector> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -29,7 +32,7 @@ template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -41,7 +44,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -52,7 +55,6 @@ struct some_alloc2 int main() { -#if __has_feature(cxx_noexcept) { typedef std::vector<MoveOnly> C; C c1, c2; @@ -86,6 +88,4 @@ int main() static_assert( noexcept(swap(c1, c2)), ""); } #endif - -#endif } diff --git a/test/std/containers/set_allocator_requirement_test_templates.h b/test/std/containers/set_allocator_requirement_test_templates.h new file mode 100644 index 0000000000000..2e3346f47e2d2 --- /dev/null +++ b/test/std/containers/set_allocator_requirement_test_templates.h @@ -0,0 +1,354 @@ +//===----------------------------------------------------------------------===// +// +// 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 SET_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H +#define SET_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H + +// <set> +// <unordered_set> + +// class set +// class unordered_set + +// insert(...); +// emplace(...); +// emplace_hint(...); + + +#include <cassert> + +#include "test_macros.h" +#include "count_new.hpp" +#include "container_test_types.h" +#include "assert_checkpoint.h" + + +template <class Container> +void testSetInsert() +{ + typedef typename Container::value_type ValueTp; + typedef Container C; + typedef std::pair<typename C::iterator, bool> R; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::insert(const value_type&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&>(); + assert(c.insert(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + assert(c.insert(v2).second == false); + } + } + { + CHECKPOINT("Testing C::insert(value_type&)"); + Container c; + ValueTp v(42); + cc->expect<const ValueTp&>(); + assert(c.insert(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + assert(c.insert(v2).second == false); + } + } + { + CHECKPOINT("Testing C::insert(value_type&&)"); + Container c; + ValueTp v(42); + cc->expect<ValueTp&&>(); + assert(c.insert(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + assert(c.insert(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::insert(const value_type&&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&>(); + assert(c.insert(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + assert(c.insert(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)"); + Container c; + std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) }; + cc->expect<ValueTp const&>(2); + c.insert(il); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(il); + } + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); + Container c; + const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) }; + cc->expect<ValueTp const&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(std::begin(ValueList), std::end(ValueList)); + } + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); + Container c; + ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; + cc->expect<ValueTp&&>(3); + c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), + std::move_iterator<ValueTp*>(std::end(ValueList))); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp ValueList2[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; + c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)), + std::move_iterator<ValueTp*>(std::end(ValueList2))); + } + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); + Container c; + ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; + cc->expect<ValueTp const&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(std::begin(ValueList), std::end(ValueList)); + } + } +} + + +template <class Container> +void testSetEmplace() +{ + typedef typename Container::value_type ValueTp; + typedef Container C; + typedef std::pair<typename C::iterator, bool> R; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::emplace(const value_type&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&>(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + assert(c.emplace(v2).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(value_type&)"); + Container c; + ValueTp v(42); + cc->expect<ValueTp&>(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + assert(c.emplace(v2).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(value_type&&)"); + Container c; + ValueTp v(42); + cc->expect<ValueTp&&>(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + assert(c.emplace(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(const value_type&&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&&>(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + assert(c.emplace(std::move(v2)).second == false); + } + } +} + + +template <class Container> +void testSetEmplaceHint() +{ + typedef typename Container::value_type ValueTp; + + typedef Container C; + typedef typename C::iterator It; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::emplace_hint(p, const value_type&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&>(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, value_type&)"); + Container c; + ValueTp v(42); + cc->expect<ValueTp&>(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, value_type&&)"); + Container c; + ValueTp v(42); + cc->expect<ValueTp&&>(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, const value_type&&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&&>(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } +} + + +template <class Container> +void testMultisetInsert() +{ + typedef typename Container::value_type ValueTp; + typedef Container C; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::insert(const value_type&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&>(); + c.insert(v); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(value_type&)"); + Container c; + ValueTp v(42); + cc->expect<const ValueTp&>(); + c.insert(v); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(value_type&&)"); + Container c; + ValueTp v(42); + cc->expect<ValueTp&&>(); + c.insert(std::move(v)); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)"); + Container c; + std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) }; + cc->expect<ValueTp const&>(2); + c.insert(il); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); + Container c; + const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) }; + cc->expect<ValueTp const&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); + Container c; + ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; + cc->expect<ValueTp&&>(3); + c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), + std::move_iterator<ValueTp*>(std::end(ValueList))); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); + Container c; + ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; + cc->expect<ValueTp&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + } +} + +#endif diff --git a/test/std/containers/unord/iterator_difference_type.pass.cpp b/test/std/containers/unord/iterator_difference_type.pass.cpp new file mode 100644 index 0000000000000..35bcc27944db7 --- /dev/null +++ b/test/std/containers/unord/iterator_difference_type.pass.cpp @@ -0,0 +1,154 @@ +//===----------------------------------------------------------------------===// +// +// 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 <unordered_map> +#include <unordered_set> +#include <type_traits> + +#include "test_macros.h" +#include "min_allocator.h" +#include "test_allocator.h" + + +template <class Map, class ValueTp, class PtrT, class CPtrT> +void testUnorderedMap() { + typedef typename Map::difference_type Diff; + { + typedef typename Map::iterator It; + static_assert((std::is_same<typename It::value_type, ValueTp>::value), ""); + static_assert((std::is_same<typename It::reference, ValueTp&>::value), ""); + static_assert((std::is_same<typename It::pointer, PtrT>::value), ""); + static_assert((std::is_same<typename It::difference_type, Diff>::value), ""); + } + { + typedef typename Map::const_iterator It; + static_assert((std::is_same<typename It::value_type, ValueTp>::value), ""); + static_assert((std::is_same<typename It::reference, ValueTp const&>::value), ""); + static_assert((std::is_same<typename It::pointer, CPtrT>::value), ""); + static_assert((std::is_same<typename It::difference_type, Diff>::value), ""); + } + { + typedef typename Map::local_iterator It; + static_assert((std::is_same<typename It::value_type, ValueTp>::value), ""); + static_assert((std::is_same<typename It::reference, ValueTp&>::value), ""); + static_assert((std::is_same<typename It::pointer, PtrT>::value), ""); + static_assert((std::is_same<typename It::difference_type, Diff>::value), ""); + } + { + typedef typename Map::const_local_iterator It; + static_assert((std::is_same<typename It::value_type, ValueTp>::value), ""); + static_assert((std::is_same<typename It::reference, ValueTp const&>::value), ""); + static_assert((std::is_same<typename It::pointer, CPtrT>::value), ""); + static_assert((std::is_same<typename It::difference_type, Diff>::value), ""); + } +} + + +template <class Set, class ValueTp, class CPtrT> +void testUnorderedSet() { + static_assert((std::is_same<typename Set::iterator, + typename Set::const_iterator>::value), ""); + static_assert((std::is_same<typename Set::local_iterator, + typename Set::const_local_iterator>::value), ""); + typedef typename Set::difference_type Diff; + { + typedef typename Set::iterator It; + static_assert((std::is_same<typename It::value_type, ValueTp>::value), ""); + static_assert((std::is_same<typename It::reference, ValueTp const&>::value), ""); + static_assert((std::is_same<typename It::pointer, CPtrT>::value), ""); + static_assert((std::is_same<typename It::difference_type, Diff>::value), ""); + + } + { + typedef typename Set::local_iterator It; + static_assert((std::is_same<typename It::value_type, ValueTp>::value), ""); + static_assert((std::is_same<typename It::reference, ValueTp const&>::value), ""); + static_assert((std::is_same<typename It::pointer, CPtrT>::value), ""); + static_assert((std::is_same<typename It::difference_type, Diff>::value), ""); + } +} + +int main() { + { + typedef std::unordered_map<int, int> Map; + typedef std::pair<const int, int> ValueTp; + testUnorderedMap<Map, ValueTp, ValueTp*, ValueTp const*>(); + } + { + typedef std::pair<const int, int> ValueTp; + typedef test_allocator<ValueTp> Alloc; + typedef std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, Alloc> Map; + testUnorderedMap<Map, ValueTp, ValueTp*, ValueTp const*>(); + } +#if TEST_STD_VER >= 11 + { + typedef std::pair<const int, int> ValueTp; + typedef min_allocator<ValueTp> Alloc; + typedef std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, Alloc> Map; + testUnorderedMap<Map, ValueTp, min_pointer<ValueTp>, min_pointer<const ValueTp>>(); + } +#endif + { + typedef std::unordered_multimap<int, int> Map; + typedef std::pair<const int, int> ValueTp; + testUnorderedMap<Map, ValueTp, ValueTp*, ValueTp const*>(); + } + { + typedef std::pair<const int, int> ValueTp; + typedef test_allocator<ValueTp> Alloc; + typedef std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, Alloc> Map; + testUnorderedMap<Map, ValueTp, ValueTp*, ValueTp const*>(); + } +#if TEST_STD_VER >= 11 + { + typedef std::pair<const int, int> ValueTp; + typedef min_allocator<ValueTp> Alloc; + typedef std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, Alloc> Map; + testUnorderedMap<Map, ValueTp, min_pointer<ValueTp>, min_pointer<const ValueTp>>(); + } +#endif + { + typedef int ValueTp; + typedef std::unordered_set<ValueTp> Set; + testUnorderedSet<Set, ValueTp, ValueTp const*>(); + } + { + typedef int ValueTp; + typedef test_allocator<ValueTp> Alloc; + typedef std::unordered_set<ValueTp, std::hash<ValueTp>, std::equal_to<ValueTp>, Alloc> Set; + testUnorderedSet<Set, ValueTp, ValueTp const*>(); + } +#if TEST_STD_VER >= 11 + { + typedef int ValueTp; + typedef min_allocator<ValueTp> Alloc; + typedef std::unordered_set<ValueTp, std::hash<ValueTp>, std::equal_to<ValueTp>, Alloc> Set; + testUnorderedSet<Set, ValueTp, min_pointer<const ValueTp>>(); + } +#endif + { + typedef int ValueTp; + typedef std::unordered_multiset<ValueTp> Set; + testUnorderedSet<Set, ValueTp, ValueTp const*>(); + } + { + typedef int ValueTp; + typedef test_allocator<ValueTp> Alloc; + typedef std::unordered_multiset<ValueTp, std::hash<ValueTp>, std::equal_to<ValueTp>, Alloc> Set; + testUnorderedSet<Set, ValueTp, ValueTp const*>(); + } +#if TEST_STD_VER >= 11 + { + typedef int ValueTp; + typedef min_allocator<ValueTp> Alloc; + typedef std::unordered_multiset<ValueTp, std::hash<ValueTp>, std::equal_to<ValueTp>, Alloc> Set; + testUnorderedSet<Set, ValueTp, min_pointer<const ValueTp>>(); + } +#endif +} diff --git a/test/std/containers/unord/unord.map/bucket.pass.cpp b/test/std/containers/unord/unord.map/bucket.pass.cpp index 6837294e35bcc..1abb58070afdf 100644 --- a/test/std/containers/unord/unord.map/bucket.pass.cpp +++ b/test/std/containers/unord/unord.map/bucket.pass.cpp @@ -45,7 +45,7 @@ int main() for (size_t i = 0; i < 13; ++i) assert(c.bucket(i) == i % bc); } -#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; diff --git a/test/std/containers/unord/unord.map/bucket_size.pass.cpp b/test/std/containers/unord/unord.map/bucket_size.pass.cpp index f3ab8fff4e436..4344508b73345 100644 --- a/test/std/containers/unord/unord.map/bucket_size.pass.cpp +++ b/test/std/containers/unord/unord.map/bucket_size.pass.cpp @@ -47,7 +47,7 @@ int main() assert(c.bucket_size(3) == 1); assert(c.bucket_size(4) == 1); } -#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; diff --git a/test/std/containers/unord/unord.map/count.pass.cpp b/test/std/containers/unord/unord.map/count.pass.cpp index 50abb53464ec8..68661b56de1ca 100644 --- a/test/std/containers/unord/unord.map/count.pass.cpp +++ b/test/std/containers/unord/unord.map/count.pass.cpp @@ -41,7 +41,7 @@ int main() assert(c.count(30) == 1); assert(c.count(5) == 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; diff --git a/test/std/containers/unord/unord.map/eq.pass.cpp b/test/std/containers/unord/unord.map/eq.pass.cpp index 9258378eb09a3..5dcea6a73f287 100644 --- a/test/std/containers/unord/unord.map/eq.pass.cpp +++ b/test/std/containers/unord/unord.map/eq.pass.cpp @@ -91,7 +91,7 @@ int main() assert( (c1 == c2)); assert(!(c1 != c2)); } -#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; diff --git a/test/std/containers/unord/unord.map/equal_range_const.pass.cpp b/test/std/containers/unord/unord.map/equal_range_const.pass.cpp index fe166c965b165..46e04fde2b323 100644 --- a/test/std/containers/unord/unord.map/equal_range_const.pass.cpp +++ b/test/std/containers/unord/unord.map/equal_range_const.pass.cpp @@ -46,7 +46,7 @@ int main() r = c.equal_range(5); assert(std::distance(r.first, r.second) == 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; diff --git a/test/std/containers/unord/unord.map/equal_range_non_const.pass.cpp b/test/std/containers/unord/unord.map/equal_range_non_const.pass.cpp index 9e8d1a9644c52..8d7f34a0b1f29 100644 --- a/test/std/containers/unord/unord.map/equal_range_non_const.pass.cpp +++ b/test/std/containers/unord/unord.map/equal_range_non_const.pass.cpp @@ -46,7 +46,7 @@ int main() r = c.equal_range(5); assert(std::distance(r.first, r.second) == 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; diff --git a/test/std/containers/unord/unord.map/find_const.pass.cpp b/test/std/containers/unord/unord.map/find_const.pass.cpp index 120efa3061b1b..0f0ea68bd7204 100644 --- a/test/std/containers/unord/unord.map/find_const.pass.cpp +++ b/test/std/containers/unord/unord.map/find_const.pass.cpp @@ -44,7 +44,7 @@ int main() i = c.find(5); assert(i == c.cend()); } -#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; diff --git a/test/std/containers/unord/unord.map/find_non_const.pass.cpp b/test/std/containers/unord/unord.map/find_non_const.pass.cpp index 7582a796dd7c5..cbce62daba165 100644 --- a/test/std/containers/unord/unord.map/find_non_const.pass.cpp +++ b/test/std/containers/unord/unord.map/find_non_const.pass.cpp @@ -44,7 +44,7 @@ int main() i = c.find(5); assert(i == c.end()); } -#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; diff --git a/test/std/containers/unord/unord.map/incomplete_type.pass.cpp b/test/std/containers/unord/unord.map/incomplete_type.pass.cpp new file mode 100644 index 0000000000000..d51b1d8d181f6 --- /dev/null +++ b/test/std/containers/unord/unord.map/incomplete_type.pass.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. +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// Check that std::unordered_map and it's iterators can be instantiated with an incomplete +// type. + +#include <unordered_map> + +template <class Tp> +struct MyHash { + MyHash() {} + std::size_t operator()(Tp const&) const {return 42;} +}; + +struct A { + typedef std::unordered_map<A, A, MyHash<A> > Map; + Map m; + Map::iterator it; + Map::const_iterator cit; + Map::local_iterator lit; + Map::const_local_iterator clit; +}; + +inline bool operator==(A const& L, A const& R) { return &L == &R; } + +int main() { + A a; +} diff --git a/test/std/containers/unord/unord.map/iterators.pass.cpp b/test/std/containers/unord/unord.map/iterators.pass.cpp index 47b1d73866840..31f4254ea3f89 100644 --- a/test/std/containers/unord/unord.map/iterators.pass.cpp +++ b/test/std/containers/unord/unord.map/iterators.pass.cpp @@ -66,7 +66,7 @@ int main() assert(std::distance(c.cbegin(), c.cend()) == c.size()); C::const_iterator i; } -#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; @@ -116,7 +116,7 @@ int main() C::const_iterator cii{}; assert ( ii1 == ii2 ); assert ( ii1 == ii4 ); - + assert (!(ii1 != ii2 )); assert ( (ii1 == cii )); diff --git a/test/std/containers/unord/unord.map/local_iterators.pass.cpp b/test/std/containers/unord/unord.map/local_iterators.pass.cpp index 770b1ace7a3e2..33a428a4f6542 100644 --- a/test/std/containers/unord/unord.map/local_iterators.pass.cpp +++ b/test/std/containers/unord/unord.map/local_iterators.pass.cpp @@ -220,7 +220,7 @@ int main() assert(i->first == 4); assert(i->second == "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; 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 b19a6e6cfa08d..d9e1d057af03d 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,6 +16,11 @@ // 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> diff --git a/test/std/containers/unord/unord.map/max_size.pass.cpp b/test/std/containers/unord/unord.map/max_size.pass.cpp index 7d5ae3a8e46d7..9c1ca18c3054e 100644 --- a/test/std/containers/unord/unord.map/max_size.pass.cpp +++ b/test/std/containers/unord/unord.map/max_size.pass.cpp @@ -26,7 +26,7 @@ int main() std::unordered_map<int, int> u; assert(u.max_size() > 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, int>>> u; diff --git a/test/std/containers/unord/unord.map/rehash.pass.cpp b/test/std/containers/unord/unord.map/rehash.pass.cpp index e1a882c69ffd5..fce751593a5e1 100644 --- a/test/std/containers/unord/unord.map/rehash.pass.cpp +++ b/test/std/containers/unord/unord.map/rehash.pass.cpp @@ -68,7 +68,7 @@ int main() assert(c.bucket_count() == 31); test(c); } -#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; diff --git a/test/std/containers/unord/unord.map/reserve.pass.cpp b/test/std/containers/unord/unord.map/reserve.pass.cpp index bef237f960af1..5999801a3923f 100644 --- a/test/std/containers/unord/unord.map/reserve.pass.cpp +++ b/test/std/containers/unord/unord.map/reserve.pass.cpp @@ -74,7 +74,7 @@ int main() assert(c.bucket_count() >= 16); test(c); } -#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; diff --git a/test/std/containers/unord/unord.map/types.pass.cpp b/test/std/containers/unord/unord.map/types.pass.cpp index b53ff8e1540ae..ecdc53c542cd4 100644 --- a/test/std/containers/unord/unord.map/types.pass.cpp +++ b/test/std/containers/unord/unord.map/types.pass.cpp @@ -50,7 +50,7 @@ int main() static_assert((std::is_same<C::size_type, std::size_t>::value), ""); static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), ""); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<char, short, std::hash<char>, std::equal_to<char>, min_allocator<std::pair<const char, short>>> C; diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp index 0fc76db0fb2f2..3c3ec058ead7f 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp @@ -45,7 +45,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, @@ -72,7 +72,7 @@ int main() typedef test_hash<std::hash<T>> HF; typedef test_compare<std::equal_to<T>> Comp; typedef std::unordered_map<T, T, HF, Comp, A> C; - + A a(10); C c(2, a); assert(c.bucket_count() == 2); diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp index fa0105604f154..ee85750f5c364 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp @@ -135,7 +135,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<std::pair<const int, std::string> > A; typedef std::unordered_map<int, std::string, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_init.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_init.pass.cpp index 3a854e1065431..e4da30bb4efd1 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_init.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_init.pass.cpp @@ -59,7 +59,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<std::pair<const int, std::string> > A; typedef std::unordered_map<int, std::string, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_move.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_move.pass.cpp index dd57c58214fa1..fe3eaee4642bf 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_move.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_move.pass.cpp @@ -165,7 +165,7 @@ int main() assert(c.max_load_factor() == 1); assert(c0.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<std::pair<const int, std::string> > A; typedef std::unordered_map<int, std::string, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/compare_copy_constructible.fail.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/compare_copy_constructible.fail.cpp new file mode 100644 index 0000000000000..417120b9eb0ec --- /dev/null +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/compare_copy_constructible.fail.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// The test requires access control SFINAE. + +// <unordered_map> + +// Check that std::unordered_map fails to instantiate if the comparison predicate is +// not copy-constructible. This is LWG issue 2436 + +#include <unordered_map> + +template <class T> +struct Comp { + bool operator () (const T& lhs, const T& rhs) const { return lhs == rhs; } + + Comp () {} +private: + Comp (const Comp &); // declared but not defined + }; + + +int main() { + std::unordered_map<int, int, std::hash<int>, Comp<int> > m; +} diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/copy.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/copy.pass.cpp index 447bcab12e6af..0590d12818b34 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/copy.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/copy.pass.cpp @@ -108,7 +108,7 @@ int main() assert(c.max_load_factor() == 1); } #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp index 7e9125381cab1..cb60807cc0e77 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp @@ -67,7 +67,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp index a0825db1ecd2d..537343a59f7c5 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp @@ -45,7 +45,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp index 30e0dc1705a31..939e0bcd4e69a 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp @@ -17,9 +17,12 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <unordered_map> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" #include "../../../test_hash.h" @@ -30,6 +33,7 @@ struct some_comp typedef T value_type; some_comp(); some_comp(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -42,15 +46,14 @@ struct some_hash int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_map<MoveOnly, MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>, @@ -66,5 +69,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp index 7fb4200605cf3..3585fe7b881a1 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp @@ -11,19 +11,20 @@ // ~unordered_map() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <unordered_map> #include <cassert> #include "MoveOnly.h" #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_comp { typedef T value_type; ~some_comp() noexcept(false); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -35,11 +36,8 @@ struct some_hash ~some_hash() noexcept(false); }; -#endif - int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_map<MoveOnly, MoveOnly> C; static_assert(std::is_nothrow_destructible<C>::value, ""); @@ -63,5 +61,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/hash_copy_constructible.fail.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/hash_copy_constructible.fail.cpp new file mode 100644 index 0000000000000..709b56de24536 --- /dev/null +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/hash_copy_constructible.fail.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// The test requires access control SFINAE. + +// <unordered_map> + +// Check that std::unordered_map fails to instantiate if the hash function is +// not copy-constructible. This is mentioned in LWG issue 2436 + +#include <unordered_map> + +template <class T> +struct Hash { + std::size_t operator () (const T& lhs) const { return 0; } + + Hash () {} +private: + Hash (const Hash &); // declared but not defined +}; + + +int main() { + std::unordered_map<int, int, Hash<int> > m; +} diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/init.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/init.pass.cpp index dbc48f816c8b6..e980b68b57c18 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/init.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/init.pass.cpp @@ -59,7 +59,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/init_size.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/init_size.pass.cpp index b60fb2cad90cd..07e77e33504f7 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/init_size.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/init_size.pass.cpp @@ -62,7 +62,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash.pass.cpp index f3c086f78876f..01aca134a6043 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash.pass.cpp @@ -63,7 +63,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal.pass.cpp index f71c48a70136c..08efdbd3591f4 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal.pass.cpp @@ -65,7 +65,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp index c028316767159..02cf5e12eb018 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp @@ -66,7 +66,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp index 72a634f0a93dd..ea204373890d5 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp @@ -111,7 +111,7 @@ int main() assert(c0.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<int, std::string> P; typedef min_allocator<std::pair<const int, std::string>> A; diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp index fc3fc6f05f8a0..61c2969d93371 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp @@ -17,6 +17,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <unordered_map> #include <cassert> @@ -28,6 +30,7 @@ struct some_comp { typedef T value_type; some_comp& operator=(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -41,7 +44,6 @@ struct some_hash int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_map<MoveOnly, MoveOnly> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); @@ -65,5 +67,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp index f292011cd7b60..16dc3dc6d4fad 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp @@ -15,6 +15,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <unordered_map> #include <cassert> @@ -26,6 +28,7 @@ struct some_comp { typedef T value_type; some_comp(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -38,7 +41,6 @@ struct some_hash int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_map<MoveOnly, MoveOnly> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); @@ -62,5 +64,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/range.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/range.pass.cpp index c1784d63b2939..d2a18fa45f11d 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/range.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/range.pass.cpp @@ -63,7 +63,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/range_size.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/range_size.pass.cpp index b63c47a57dfac..9af18ab61f419 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/range_size.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/range_size.pass.cpp @@ -66,7 +66,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash.pass.cpp index 675949e9d9be3..e23208dba991b 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash.pass.cpp @@ -68,7 +68,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal.pass.cpp index d55359f7aa063..d296bab327413 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal.pass.cpp @@ -69,7 +69,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp index 61f9f21ad25b3..638efcfebb77a 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp @@ -71,7 +71,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/size.fail.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/size.fail.cpp index 0a3ae3a117f17..d2551861ec895 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/size.fail.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/size.fail.cpp @@ -45,7 +45,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/size.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/size.pass.cpp index 708dc2362739b..465dea21bce16 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/size.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/size.pass.cpp @@ -45,7 +45,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash.pass.cpp index 6c975ec72030e..f70ad7a1e5bcb 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash.pass.cpp @@ -47,7 +47,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal.pass.cpp index 8b2bb317987ec..184d77d69d5f0 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal.pass.cpp @@ -48,7 +48,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp index bcf7b91503add..56eb59ddba9bd 100644 --- a/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp @@ -49,7 +49,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.map/unord.map.elem/at.pass.cpp b/test/std/containers/unord/unord.map/unord.map.elem/at.pass.cpp index 04ce91f699174..5504d33f299b4 100644 --- a/test/std/containers/unord/unord.map/unord.map.elem/at.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.elem/at.pass.cpp @@ -77,7 +77,7 @@ int main() } assert(c.size() == 4); } -#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; diff --git a/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp b/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp index c072248f866af..7bc59447a5e6b 100644 --- a/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp @@ -14,13 +14,20 @@ // class unordered_map // mapped_type& operator[](const key_type& k); +// mapped_type& operator[](key_type&& k); #include <unordered_map> #include <string> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "min_allocator.h" +#include "count_new.hpp" + +#if TEST_STD_VER >= 11 +#include "container_test_types.h" +#endif int main() { @@ -44,7 +51,7 @@ int main() assert(c.size() == 5); assert(c.at(11) == "eleven"); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if TEST_STD_VER >= 11 { typedef std::unordered_map<MoveOnly, std::string> C; typedef std::pair<int, std::string> P; @@ -65,8 +72,6 @@ int main() assert(c.size() == 5); assert(c.at(11) == "eleven"); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L { typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; @@ -88,7 +93,7 @@ int main() assert(c.size() == 5); assert(c.at(11) == "eleven"); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { typedef std::unordered_map<MoveOnly, std::string, std::hash<MoveOnly>, std::equal_to<MoveOnly>, min_allocator<std::pair<const MoveOnly, std::string>>> C; @@ -110,6 +115,50 @@ int main() assert(c.size() == 5); assert(c.at(11) == "eleven"); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + using Container = TCT::unordered_map<>; + using Key = Container::key_type; + using MappedType = Container::mapped_type; + using ValueTp = Container::value_type; + ConstructController* cc = getConstructController(); + cc->reset(); + { + Container c; + const Key k(1); + cc->expect<std::piecewise_construct_t const&, std::tuple<Key const&>&&, std::tuple<>&&>(); + MappedType& mref = c[k]; + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + MappedType& mref2 = c[k]; + assert(&mref == &mref2); + } + } + { + Container c; + Key k(1); + cc->expect<std::piecewise_construct_t const&, std::tuple<Key const&>&&, std::tuple<>&&>(); + MappedType& mref = c[k]; + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + MappedType& mref2 = c[k]; + assert(&mref == &mref2); + } + } + { + Container c; + Key k(1); + cc->expect<std::piecewise_construct_t const&, std::tuple<Key &&>&&, std::tuple<>&&>(); + MappedType& mref = c[std::move(k)]; + assert(!cc->unchecked()); + { + Key k2(1); + DisableAllocationGuard g; + MappedType& mref2 = c[std::move(k2)]; + assert(&mref == &mref2); + } + } + } #endif } diff --git a/test/std/containers/unord/unord.map/unord.map.elem/index_tuple.pass.cpp b/test/std/containers/unord/unord.map/unord.map.elem/index_tuple.pass.cpp index c319b5c30b2c6..f2c694e86f74c 100644 --- a/test/std/containers/unord/unord.map/unord.map.elem/index_tuple.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.elem/index_tuple.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <unordered_map> // template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, @@ -18,9 +20,6 @@ // http://llvm.org/bugs/show_bug.cgi?id=16542 #include <unordered_map> - -#ifndef _LIBCPP_HAS_NO_VARIADICS - #include <tuple> using namespace std; @@ -30,12 +29,8 @@ struct my_hash size_t operator()(const tuple<int,int>&) const {return 0;} }; -#endif - int main() { -#ifndef _LIBCPP_HAS_NO_VARIADICS unordered_map<tuple<int,int>, size_t, my_hash> m; m[make_tuple(2,3)]=7; -#endif } diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/clear.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/clear.pass.cpp index 9f320e9494798..106423ebfbe92 100644 --- a/test/std/containers/unord/unord.map/unord.map.modifiers/clear.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.modifiers/clear.pass.cpp @@ -39,7 +39,7 @@ int main() c.clear(); 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; diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/emplace.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/emplace.pass.cpp index 5de74d2e6c92e..26f7161664642 100644 --- a/test/std/containers/unord/unord.map/unord.map.modifiers/emplace.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.modifiers/emplace.pass.cpp @@ -49,7 +49,7 @@ int main() assert(r.first->first == 5); assert(r.first->second == Emplaceable(6, 7)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, Emplaceable, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, Emplaceable>>> C; diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/emplace_hint.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/emplace_hint.pass.cpp index 21a4689658ae3..477f2cf02e760 100644 --- a/test/std/containers/unord/unord.map/unord.map.modifiers/emplace_hint.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.modifiers/emplace_hint.pass.cpp @@ -51,7 +51,7 @@ int main() assert(r->first == 5); assert(r->second == Emplaceable(6, 7)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<int, Emplaceable, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, Emplaceable>>> C; diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp index f0664c3c3ffc1..820b12a9bf8bb 100644 --- a/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp @@ -58,7 +58,7 @@ int main() assert(c.size() == 0); assert(k == c.end()); } -#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; diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp new file mode 100644 index 0000000000000..00c47182c9252 --- /dev/null +++ b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.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. +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// class unordered_map + +// insert(...); +// emplace(...); + +// UNSUPPORTED: c++98, c++03 + + +#include <unordered_map> + +#include "container_test_types.h" +#include "../../../map_allocator_requirement_test_templates.h" + +int main() +{ + testMapInsert<TCT::unordered_map<> >(); + testMapInsertHint<TCT::unordered_map<> >(); + testMapEmplace<TCT::unordered_map<> >(); + testMapEmplaceHint<TCT::unordered_map<> >(); +} diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_const_lvalue.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_const_lvalue.pass.cpp index a16f097b4c01f..fe2b24707fb33 100644 --- a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_const_lvalue.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_const_lvalue.pass.cpp @@ -18,69 +18,64 @@ #include <unordered_map> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" -int main() + +template <class Container> +void do_insert_cv_test() { - { - typedef std::unordered_map<double, int> C; - typedef std::pair<C::iterator, bool> R; - typedef C::value_type P; - C c; - R r = c.insert(P(3.5, 3)); - assert(r.second); - assert(c.size() == 1); - assert(r.first->first == 3.5); - assert(r.first->second == 3); + typedef Container M; + typedef std::pair<typename M::iterator, bool> R; + typedef typename M::value_type VT; + M m; - r = c.insert(P(3.5, 4)); - assert(!r.second); - assert(c.size() == 1); - assert(r.first->first == 3.5); - assert(r.first->second == 3); + const VT v1(2.5, 2); + R r = m.insert(v1); + assert(r.second); + assert(m.size() == 1); + assert(r.first->first == 2.5); + assert(r.first->second == 2); - r = c.insert(P(4.5, 4)); - assert(r.second); - assert(c.size() == 2); - assert(r.first->first == 4.5); - assert(r.first->second == 4); + r = m.insert(VT(2.5, 3)); // test rvalue insertion works in C++03 + assert(!r.second); + assert(m.size() == 1); + assert(r.first->first == 2.5); + assert(r.first->second == 2); - r = c.insert(P(5.5, 4)); - assert(r.second); - assert(c.size() == 3); - assert(r.first->first == 5.5); - assert(r.first->second == 4); - } -#if __cplusplus >= 201103L - { - typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>, - min_allocator<std::pair<const double, int>>> C; - typedef std::pair<C::iterator, bool> R; - typedef C::value_type P; - C c; - R r = c.insert(P(3.5, 3)); - assert(r.second); - assert(c.size() == 1); - assert(r.first->first == 3.5); - assert(r.first->second == 3); + const VT v2(1.5, 1); + r = m.insert(v2); + assert(r.second); + assert(m.size() == 2); + assert(r.first->first == 1.5); + assert(r.first->second == 1); - r = c.insert(P(3.5, 4)); - assert(!r.second); - assert(c.size() == 1); - assert(r.first->first == 3.5); - assert(r.first->second == 3); + const VT v3(3.5, 3); + r = m.insert(v3); + assert(r.second); + assert(m.size() == 3); + assert(r.first->first == 3.5); + assert(r.first->second == 3); - r = c.insert(P(4.5, 4)); - assert(r.second); - assert(c.size() == 2); - assert(r.first->first == 4.5); - assert(r.first->second == 4); + const VT v4(3.5, 4); + r = m.insert(v4); + assert(!r.second); + assert(m.size() == 3); + assert(r.first->first == 3.5); + assert(r.first->second == 3); +} - r = c.insert(P(5.5, 4)); - assert(r.second); - assert(c.size() == 3); - assert(r.first->first == 5.5); - assert(r.first->second == 4); +int main() +{ + { + typedef std::unordered_map<double, int> M; + do_insert_cv_test<M>(); + } +#if TEST_STD_VER >= 11 + { + typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>, + min_allocator<std::pair<const double, int>>> M; + do_insert_cv_test<M>(); } #endif } diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_const_lvalue.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_const_lvalue.pass.cpp index 981b8fb18a0a2..d40a8a61a3d42 100644 --- a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_const_lvalue.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_const_lvalue.pass.cpp @@ -52,7 +52,7 @@ int main() assert(r->first == 5.5); assert(r->second == 4); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>, min_allocator<std::pair<const double, int>>> C; diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_rvalue.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_rvalue.pass.cpp index 1618c1019e1c1..04d01eb466e72 100644 --- a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_rvalue.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_rvalue.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <unordered_map> // template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, @@ -55,7 +57,6 @@ int main() assert(r->first == 5.5); assert(r->second == 4); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::unordered_map<MoveOnly, MoveOnly> C; typedef C::iterator R; @@ -82,8 +83,6 @@ int main() assert(r->first == 5); assert(r->second == 4); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L { typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>, min_allocator<std::pair<const double, int>>> C; @@ -111,7 +110,6 @@ int main() assert(r->first == 5.5); assert(r->second == 4); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, min_allocator<std::pair<const MoveOnly, MoveOnly>>> C; @@ -139,7 +137,31 @@ int main() assert(r->first == 5); assert(r->second == 4); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef std::unordered_map<double, MoveOnly> C; + typedef C::iterator R; + C c; + C::const_iterator e = c.end(); + R r = c.insert(e, {3.5, 3}); + assert(c.size() == 1); + assert(r->first == 3.5); + assert(r->second == 3); + + r = c.insert(c.end(), {3.5, 4}); + assert(c.size() == 1); + assert(r->first == 3.5); + assert(r->second == 3); + + r = c.insert(c.end(), {4.5, 4}); + assert(c.size() == 2); + assert(r->first == 4.5); + assert(r->second == 4); + + r = c.insert(c.end(), {5.5, 4}); + assert(c.size() == 3); + assert(r->first == 5.5); + assert(r->second == 4); + } #if _LIBCPP_DEBUG >= 1 { typedef std::unordered_map<double, int> C; @@ -152,5 +174,4 @@ int main() assert(false); } #endif -#endif } diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_init.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_init.pass.cpp index 81e8a468d83fb..a4d8b5d410b4c 100644 --- a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_init.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_init.pass.cpp @@ -45,7 +45,7 @@ int main() 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; diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_range.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_range.pass.cpp index fc44e7828ffa1..b722b4a5ba026 100644 --- a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_range.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_range.pass.cpp @@ -45,7 +45,7 @@ int main() 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; diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_rvalue.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_rvalue.pass.cpp index f53dc6c7e97a8..faf5b046b5d83 100644 --- a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_rvalue.pass.cpp +++ b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_rvalue.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <unordered_map> // template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, @@ -54,7 +56,6 @@ int main() assert(r.first->first == 5.5); assert(r.first->second == 4); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::unordered_map<MoveOnly, MoveOnly> C; typedef std::pair<C::iterator, bool> R; @@ -84,8 +85,6 @@ int main() assert(r.first->first == 5); assert(r.first->second == 4); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L { typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>, min_allocator<std::pair<const double, int>>> C; @@ -116,7 +115,6 @@ int main() assert(r.first->first == 5.5); assert(r.first->second == 4); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, min_allocator<std::pair<const MoveOnly, MoveOnly>>> C; @@ -147,6 +145,32 @@ int main() assert(r.first->first == 5); assert(r.first->second == 4); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#endif + { + typedef std::unordered_map<double, MoveOnly> C; + typedef std::pair<C::iterator, bool> R; + C c; + R r = c.insert({3.5, 3}); + assert(r.second); + assert(c.size() == 1); + assert(r.first->first == 3.5); + assert(r.first->second == 3); + + r = c.insert({3.5, 4}); + assert(!r.second); + assert(c.size() == 1); + assert(r.first->first == 3.5); + assert(r.first->second == 3); + + r = c.insert({4.5, 4}); + assert(r.second); + assert(c.size() == 2); + assert(r.first->first == 4.5); + assert(r.first->second == 4); + + r = c.insert({5.5, 4}); + assert(r.second); + assert(c.size() == 3); + assert(r.first->first == 5.5); + assert(r.first->second == 4); + } } 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 index eabcf2e85db2e..adc4d6944ecb0 100644 --- 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 @@ -22,7 +22,6 @@ // 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> 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 1056c231f0db3..f8f17ffec57af 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <unordered_map> // void swap(unordered_map& c) @@ -26,6 +28,7 @@ #include <unordered_map> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -33,20 +36,20 @@ template <class T> struct some_comp { typedef T value_type; - + some_comp() {} some_comp(const some_comp&) {} + bool operator()(const T&, const T&) const { return false; } }; 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; + bool operator()(const T&, const T&) const { return false; } }; #if TEST_STD_VER >= 14 @@ -79,7 +82,7 @@ template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -91,7 +94,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -104,7 +107,7 @@ template <class T> struct some_alloc3 { typedef T value_type; - + some_alloc3() {} some_alloc3(const some_alloc3&); void deallocate(void*, unsigned) {} @@ -116,7 +119,6 @@ struct some_alloc3 int main() { -#if __has_feature(cxx_noexcept) typedef std::pair<const MoveOnly, MoveOnly> MapType; { typedef std::unordered_map<MoveOnly, MoveOnly> C; @@ -195,5 +197,4 @@ int main() static_assert( noexcept(swap(c1, c2)), ""); } #endif -#endif } diff --git a/test/std/containers/unord/unord.multimap/bucket.pass.cpp b/test/std/containers/unord/unord.multimap/bucket.pass.cpp index be5acc1963082..415dce11c1288 100644 --- a/test/std/containers/unord/unord.multimap/bucket.pass.cpp +++ b/test/std/containers/unord/unord.multimap/bucket.pass.cpp @@ -45,7 +45,7 @@ int main() for (size_t i = 0; i < 13; ++i) assert(c.bucket(i) == i % bc); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/bucket_size.pass.cpp b/test/std/containers/unord/unord.multimap/bucket_size.pass.cpp index a02f72efc6c26..3bc3f5876fe61 100644 --- a/test/std/containers/unord/unord.multimap/bucket_size.pass.cpp +++ b/test/std/containers/unord/unord.multimap/bucket_size.pass.cpp @@ -49,7 +49,7 @@ int main() assert(c.bucket_size(5) == 0); assert(c.bucket_size(6) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/count.pass.cpp b/test/std/containers/unord/unord.multimap/count.pass.cpp index efaf02e3a572b..c93a2237c480d 100644 --- a/test/std/containers/unord/unord.multimap/count.pass.cpp +++ b/test/std/containers/unord/unord.multimap/count.pass.cpp @@ -44,7 +44,7 @@ int main() assert(c.count(50) == 3); assert(c.count(5) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/db_iterators_7.pass.cpp b/test/std/containers/unord/unord.multimap/db_iterators_7.pass.cpp index b6ba8d6194a4a..8a23edd174b00 100644 --- a/test/std/containers/unord/unord.multimap/db_iterators_7.pass.cpp +++ b/test/std/containers/unord/unord.multimap/db_iterators_7.pass.cpp @@ -36,7 +36,7 @@ int main() ++i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/db_iterators_8.pass.cpp b/test/std/containers/unord/unord.multimap/db_iterators_8.pass.cpp index f5ea5089349b2..e5a9ce961530a 100644 --- a/test/std/containers/unord/unord.multimap/db_iterators_8.pass.cpp +++ b/test/std/containers/unord/unord.multimap/db_iterators_8.pass.cpp @@ -34,7 +34,7 @@ int main() C::value_type j = *i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/db_local_iterators_7.pass.cpp b/test/std/containers/unord/unord.multimap/db_local_iterators_7.pass.cpp index 93cbd5433f476..2bd161f75072b 100644 --- a/test/std/containers/unord/unord.multimap/db_local_iterators_7.pass.cpp +++ b/test/std/containers/unord/unord.multimap/db_local_iterators_7.pass.cpp @@ -34,7 +34,7 @@ int main() ++i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/db_local_iterators_8.pass.cpp b/test/std/containers/unord/unord.multimap/db_local_iterators_8.pass.cpp index 159ae49635323..78b40e14e7a15 100644 --- a/test/std/containers/unord/unord.multimap/db_local_iterators_8.pass.cpp +++ b/test/std/containers/unord/unord.multimap/db_local_iterators_8.pass.cpp @@ -33,7 +33,7 @@ int main() C::value_type j = *i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/eq.pass.cpp b/test/std/containers/unord/unord.multimap/eq.pass.cpp index 3604e7792c13f..f95bea3daef33 100644 --- a/test/std/containers/unord/unord.multimap/eq.pass.cpp +++ b/test/std/containers/unord/unord.multimap/eq.pass.cpp @@ -100,7 +100,7 @@ int main() assert( (c1 == c2)); assert(!(c1 != c2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/equal_range_const.pass.cpp b/test/std/containers/unord/unord.multimap/equal_range_const.pass.cpp index 67613b094bfcd..382ed7c9831d1 100644 --- a/test/std/containers/unord/unord.multimap/equal_range_const.pass.cpp +++ b/test/std/containers/unord/unord.multimap/equal_range_const.pass.cpp @@ -57,7 +57,7 @@ int main() assert(r.first->first == 50); assert(r.first->second == "fiftyB"); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/equal_range_non_const.pass.cpp b/test/std/containers/unord/unord.multimap/equal_range_non_const.pass.cpp index eb4c019af9518..17eb14e442626 100644 --- a/test/std/containers/unord/unord.multimap/equal_range_non_const.pass.cpp +++ b/test/std/containers/unord/unord.multimap/equal_range_non_const.pass.cpp @@ -57,7 +57,7 @@ int main() assert(r.first->first == 50); assert(r.first->second == "fiftyB"); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/find_const.pass.cpp b/test/std/containers/unord/unord.multimap/find_const.pass.cpp index bc2650d111f3d..70c2b45efbd49 100644 --- a/test/std/containers/unord/unord.multimap/find_const.pass.cpp +++ b/test/std/containers/unord/unord.multimap/find_const.pass.cpp @@ -44,7 +44,7 @@ int main() i = c.find(5); assert(i == c.cend()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/find_non_const.pass.cpp b/test/std/containers/unord/unord.multimap/find_non_const.pass.cpp index 5a128c0f37e16..0510d14419d5f 100644 --- a/test/std/containers/unord/unord.multimap/find_non_const.pass.cpp +++ b/test/std/containers/unord/unord.multimap/find_non_const.pass.cpp @@ -44,7 +44,7 @@ int main() i = c.find(5); assert(i == c.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/incomplete.pass.cpp b/test/std/containers/unord/unord.multimap/incomplete.pass.cpp new file mode 100644 index 0000000000000..7822224e7366d --- /dev/null +++ b/test/std/containers/unord/unord.multimap/incomplete.pass.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. +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// Check that std::unordered_multimap and it's iterators can be instantiated with an incomplete +// type. + +#include <unordered_map> + +template <class Tp> +struct MyHash { + MyHash() {} + std::size_t operator()(Tp const&) const {return 42;} +}; + +struct A { + typedef std::unordered_multimap<A, A, MyHash<A> > Map; + Map m; + Map::iterator it; + Map::const_iterator cit; + Map::local_iterator lit; + Map::const_local_iterator clit; +}; + +inline bool operator==(A const& L, A const& R) { return &L == &R; } + +int main() { + A a; +} diff --git a/test/std/containers/unord/unord.multimap/iterators.pass.cpp b/test/std/containers/unord/unord.multimap/iterators.pass.cpp index 1831cf1149b13..cc75bb10a811d 100644 --- a/test/std/containers/unord/unord.multimap/iterators.pass.cpp +++ b/test/std/containers/unord/unord.multimap/iterators.pass.cpp @@ -69,7 +69,7 @@ int main() assert(std::distance(c.cbegin(), c.cend()) == c.size()); C::const_iterator i; } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/load_factor.pass.cpp b/test/std/containers/unord/unord.multimap/load_factor.pass.cpp index 52b3f03d88a1e..9c42435946ffa 100644 --- a/test/std/containers/unord/unord.multimap/load_factor.pass.cpp +++ b/test/std/containers/unord/unord.multimap/load_factor.pass.cpp @@ -48,7 +48,7 @@ int main() const C c; assert(c.load_factor() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/local_iterators.pass.cpp b/test/std/containers/unord/unord.multimap/local_iterators.pass.cpp index 35e4c772fd337..504fe54de830d 100644 --- a/test/std/containers/unord/unord.multimap/local_iterators.pass.cpp +++ b/test/std/containers/unord/unord.multimap/local_iterators.pass.cpp @@ -284,7 +284,7 @@ int main() j = c.cend(b); assert(std::distance(i, j) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/max_bucket_count.pass.cpp b/test/std/containers/unord/unord.multimap/max_bucket_count.pass.cpp index 23b90579ec417..a2ab399d34697 100644 --- a/test/std/containers/unord/unord.multimap/max_bucket_count.pass.cpp +++ b/test/std/containers/unord/unord.multimap/max_bucket_count.pass.cpp @@ -30,7 +30,7 @@ int main() const C c; assert(c.max_bucket_count() > 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/max_load_factor.pass.cpp b/test/std/containers/unord/unord.multimap/max_load_factor.pass.cpp index 39b7feeba4e5a..b0b2b664f0988 100644 --- a/test/std/containers/unord/unord.multimap/max_load_factor.pass.cpp +++ b/test/std/containers/unord/unord.multimap/max_load_factor.pass.cpp @@ -42,7 +42,7 @@ int main() c.max_load_factor(2.5); assert(c.max_load_factor() == 2.5); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/max_size.pass.cpp b/test/std/containers/unord/unord.multimap/max_size.pass.cpp index caba5932b23c4..3bf1f1496f682 100644 --- a/test/std/containers/unord/unord.multimap/max_size.pass.cpp +++ b/test/std/containers/unord/unord.multimap/max_size.pass.cpp @@ -26,7 +26,7 @@ int main() std::unordered_multimap<int, int> u; assert(u.max_size() > 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, int>>> u; diff --git a/test/std/containers/unord/unord.multimap/rehash.pass.cpp b/test/std/containers/unord/unord.multimap/rehash.pass.cpp index 5ef21d3bc4cef..c099abe2ac053 100644 --- a/test/std/containers/unord/unord.multimap/rehash.pass.cpp +++ b/test/std/containers/unord/unord.multimap/rehash.pass.cpp @@ -97,7 +97,7 @@ int main() assert(c.bucket_count() == 31); test(c); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/reserve.pass.cpp b/test/std/containers/unord/unord.multimap/reserve.pass.cpp index 388b1f67e450b..3f76da11e3d9e 100644 --- a/test/std/containers/unord/unord.multimap/reserve.pass.cpp +++ b/test/std/containers/unord/unord.multimap/reserve.pass.cpp @@ -76,7 +76,7 @@ int main() assert(c.bucket_count() >= 16); test(c); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/swap_member.pass.cpp b/test/std/containers/unord/unord.multimap/swap_member.pass.cpp index 225eccd4793f2..4653cc32ef36f 100644 --- a/test/std/containers/unord/unord.multimap/swap_member.pass.cpp +++ b/test/std/containers/unord/unord.multimap/swap_member.pass.cpp @@ -396,7 +396,7 @@ int main() 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; diff --git a/test/std/containers/unord/unord.multimap/types.pass.cpp b/test/std/containers/unord/unord.multimap/types.pass.cpp index 55ae749746c17..e141234904e44 100644 --- a/test/std/containers/unord/unord.multimap/types.pass.cpp +++ b/test/std/containers/unord/unord.multimap/types.pass.cpp @@ -50,7 +50,7 @@ int main() static_assert((std::is_same<C::size_type, std::size_t>::value), ""); static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), ""); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<char, short, std::hash<char>, std::equal_to<char>, min_allocator<std::pair<const char, short>>> C; diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp index dc41fad29af87..6eb258db49605 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp @@ -45,7 +45,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, @@ -72,7 +72,7 @@ int main() typedef test_hash<std::hash<T>> HF; typedef test_compare<std::equal_to<T>> Comp; typedef std::unordered_multimap<T, T, HF, Comp, A> C; - + A a(10); C c(2, a); assert(c.bucket_count() == 2); diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp index df566b396f992..5634a79eff336 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp @@ -163,7 +163,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<std::pair<const int, std::string> > A; typedef std::unordered_multimap<int, std::string, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_init.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_init.pass.cpp index 2d3c1434d69fd..0d3b4453dd44a 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_init.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_init.pass.cpp @@ -84,7 +84,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<std::pair<const int, std::string> > A; typedef std::unordered_multimap<int, std::string, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_move.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_move.pass.cpp index 0c43fa8f06ed6..ed8d792e81788 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_move.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_move.pass.cpp @@ -223,7 +223,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<std::pair<const int, std::string> > A; typedef std::unordered_multimap<int, std::string, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/compare_copy_constructible.fail.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/compare_copy_constructible.fail.cpp new file mode 100644 index 0000000000000..d3e31484c8b77 --- /dev/null +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/compare_copy_constructible.fail.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// The test requires access control SFINAE. + +// <unordered_map> + +// Check that std::unordered_multimap fails to instantiate if the comparison predicate is +// not copy-constructible. This is LWG issue 2436 + +#include <unordered_map> + +template <class T> +struct Comp { + bool operator () (const T& lhs, const T& rhs) const { return lhs == rhs; } + + Comp () {} +private: + Comp (const Comp &); // declared but not defined + }; + + +int main() { + std::unordered_multimap<int, int, std::hash<int>, Comp<int> > m; +} diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy.pass.cpp index 06adfd7cfe052..7b0adda182cb9 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy.pass.cpp @@ -136,7 +136,7 @@ int main() assert(c.max_load_factor() == 1); } #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp index 0fb508f1f124c..e759267b45b1e 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp @@ -81,7 +81,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp index 1884065ce0c8b..f361b2c3dfdda 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp @@ -45,7 +45,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp index fac3cec63d709..e404612a754e2 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp @@ -17,9 +17,12 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <unordered_map> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" #include "../../../test_hash.h" @@ -30,6 +33,7 @@ struct some_comp typedef T value_type; some_comp(); some_comp(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -42,15 +46,14 @@ struct some_hash int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_multimap<MoveOnly, MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>, @@ -66,5 +69,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp index 2207851967910..2797f8dcfb04e 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp @@ -11,19 +11,20 @@ // ~unordered_multimap() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <unordered_map> #include <cassert> #include "MoveOnly.h" #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_comp { typedef T value_type; ~some_comp() noexcept(false); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -35,11 +36,8 @@ struct some_hash ~some_hash() noexcept(false); }; -#endif - int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_multimap<MoveOnly, MoveOnly> C; static_assert(std::is_nothrow_destructible<C>::value, ""); @@ -63,5 +61,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/hash_copy_constructible.fail.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/hash_copy_constructible.fail.cpp new file mode 100644 index 0000000000000..4214f694a20f7 --- /dev/null +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/hash_copy_constructible.fail.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// The test requires access control SFINAE. + +// <unordered_map> + +// Check that std::unordered_multimap fails to instantiate if the hash function is +// not copy-constructible. This is mentioned in LWG issue 2436 + +#include <unordered_map> + +template <class T> +struct Hash { + std::size_t operator () (const T& lhs) const { return 0; } + + Hash () {} +private: + Hash (const Hash &); // declared but not defined + }; + + +int main() { + std::unordered_multimap<int, int, Hash<int> > m; +} diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init.pass.cpp index cc5532adbe085..f6bc3a08cae95 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init.pass.cpp @@ -81,7 +81,7 @@ int main() assert(c.key_eq() == test_compare<std::equal_to<int> >()); assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >())); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size.pass.cpp index 8f6710a933171..5dc4323493e47 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size.pass.cpp @@ -84,7 +84,7 @@ int main() assert(c.key_eq() == test_compare<std::equal_to<int> >()); assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >())); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash.pass.cpp index 0962e9b29f835..8bcbd0bdc3525 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash.pass.cpp @@ -85,7 +85,7 @@ int main() assert(c.key_eq() == test_compare<std::equal_to<int> >()); assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >())); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal.pass.cpp index 324b0a7c1a5ef..8dda376db3f98 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal.pass.cpp @@ -87,7 +87,7 @@ int main() assert(c.key_eq() == test_compare<std::equal_to<int> >(9)); assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >())); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp index 23ae7d19f9c2c..6843613b04819 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp @@ -88,7 +88,7 @@ int main() assert(c.key_eq() == test_compare<std::equal_to<int> >(9)); assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >(10))); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move.pass.cpp index b61735eb02560..58d1424d8b1e6 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move.pass.cpp @@ -128,7 +128,7 @@ int main() assert(c0.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp index 106c29cda8d04..a66e41e8e35ca 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp @@ -159,7 +159,7 @@ int main() assert(c0.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::pair<int, std::string> P; typedef min_allocator<std::pair<const int, std::string>> A; diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp index 47e61ab70b834..eeda7b39e9581 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp @@ -17,6 +17,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <unordered_map> #include <cassert> @@ -28,6 +30,7 @@ struct some_comp { typedef T value_type; some_comp& operator=(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -41,7 +44,6 @@ struct some_hash int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_multimap<MoveOnly, MoveOnly> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); @@ -65,5 +67,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp index 37f17876973a0..965c46499a163 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp @@ -15,6 +15,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <unordered_map> #include <cassert> @@ -26,6 +28,7 @@ struct some_comp { typedef T value_type; some_comp(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -38,7 +41,6 @@ struct some_hash int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_multimap<MoveOnly, MoveOnly> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); @@ -62,5 +64,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range.pass.cpp index bb700ec565dcf..96ad70a56e0f0 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range.pass.cpp @@ -85,7 +85,7 @@ int main() assert(c.key_eq() == test_compare<std::equal_to<int> >()); assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >())); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size.pass.cpp index ad33b13054c7a..15b31b519b740 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size.pass.cpp @@ -88,7 +88,7 @@ int main() assert(c.key_eq() == test_compare<std::equal_to<int> >()); assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >())); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash.pass.cpp index 98644c75e33b5..f565f10c89b55 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash.pass.cpp @@ -90,7 +90,7 @@ int main() assert(c.key_eq() == test_compare<std::equal_to<int> >()); assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >())); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal.pass.cpp index 9a79c30563585..8f86befbe37f5 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal.pass.cpp @@ -91,7 +91,7 @@ int main() assert(c.key_eq() == test_compare<std::equal_to<int> >(9)); assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >())); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp index a5aafb96c7b0f..e8040d88de2aa 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp @@ -93,7 +93,7 @@ int main() assert(c.key_eq() == test_compare<std::equal_to<int> >(9)); assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >(10))); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size.fail.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size.fail.cpp index 44cf84ff323cb..38e6c60df52d2 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size.fail.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size.fail.cpp @@ -45,7 +45,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size.pass.cpp index bd56a41fd71fa..8aad662610ab9 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size.pass.cpp @@ -45,7 +45,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash.pass.cpp index 33460612ce3f1..2cc6c0176e5e0 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash.pass.cpp @@ -47,7 +47,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal.pass.cpp index c2420ce9e6f58..ebfce9fec564c 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal.pass.cpp @@ -48,7 +48,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp index 33886670b3b4c..56e3808984c5e 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp @@ -49,7 +49,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<NotConstructible, NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/clear.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/clear.pass.cpp index 4efcfaa6ce539..891d44911eb05 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/clear.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/clear.pass.cpp @@ -39,7 +39,7 @@ int main() c.clear(); assert(c.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/emplace.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/emplace.pass.cpp index 4f2e8ef061fa9..96678cf33fa57 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/emplace.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/emplace.pass.cpp @@ -46,7 +46,7 @@ int main() assert(r->first == 5); assert(r->second == Emplaceable(6, 7)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, Emplaceable, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, Emplaceable>>> C; diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/emplace_hint.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/emplace_hint.pass.cpp index 4d141ad137c8d..8bccd4013a290 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/emplace_hint.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/emplace_hint.pass.cpp @@ -59,7 +59,7 @@ int main() assert(r->first == 3); assert(r->second == Emplaceable(5, 6)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, Emplaceable, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, Emplaceable>>> C; 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 b31a4e56b31e3..9da1e71cba06c 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 @@ -76,7 +76,7 @@ int main() assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; @@ -123,7 +123,7 @@ int main() assert(std::distance(c.cbegin(), c.cend()) == c.size()); } #endif -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 { // This is LWG #2059 typedef TemplateConstructor T; diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_key.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_key.pass.cpp index 892f8a2475020..f061d858e3f7f 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_key.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_key.pass.cpp @@ -21,12 +21,12 @@ #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()) { if ( *w == *p ) p++; @@ -200,7 +200,7 @@ int main() assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; @@ -372,7 +372,7 @@ int main() m2.insert(std::make_pair(i,j)); } } - + C::iterator i = m2.begin(); int ctr = 0; while (i != m2.end()) { diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp index f60ec071ff70f..110cc4542b42f 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp @@ -98,7 +98,7 @@ int main() assert(c.size() == 0); assert(k == c.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_allocator_requirements.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_allocator_requirements.pass.cpp new file mode 100644 index 0000000000000..30f78936ff92b --- /dev/null +++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_allocator_requirements.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// class unordered_multimap + +// insert(...) + +// UNSUPPORTED: c++98, c++03 + +#include <unordered_map> + +#include "container_test_types.h" +#include "../../../map_allocator_requirement_test_templates.h" + +int main() +{ + testMultimapInsert<TCT::unordered_multimap<> >(); + testMultimapInsertHint<TCT::unordered_multimap<> >(); +} diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_const_lvalue.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_const_lvalue.pass.cpp index e7e7cb03b6d0b..320fbc8fe2eaf 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_const_lvalue.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_const_lvalue.pass.cpp @@ -47,7 +47,7 @@ int main() assert(r->first == 5.5); assert(r->second == 4); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<double, int, std::hash<double>, std::equal_to<double>, min_allocator<std::pair<const double, int>>> C; diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_const_lvalue.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_const_lvalue.pass.cpp index c7cb1f4c014ba..c920ae93553fc 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_const_lvalue.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_const_lvalue.pass.cpp @@ -52,7 +52,7 @@ int main() assert(r->first == 5.5); assert(r->second == 4); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<double, int, std::hash<double>, std::equal_to<double>, min_allocator<std::pair<const double, int>>> C; diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_rvalue.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_rvalue.pass.cpp index 7116fa02b6f5e..d6c0dbdbed07f 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_rvalue.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_rvalue.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <unordered_map> // template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, @@ -55,7 +57,6 @@ int main() assert(r->first == 5.5); assert(r->second == 4); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::unordered_multimap<MoveOnly, MoveOnly> C; typedef C::iterator R; @@ -82,8 +83,6 @@ int main() assert(r->first == 5); assert(r->second == 4); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L { typedef std::unordered_multimap<double, int, std::hash<double>, std::equal_to<double>, min_allocator<std::pair<const double, int>>> C; @@ -111,7 +110,6 @@ int main() assert(r->first == 5.5); assert(r->second == 4); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, min_allocator<std::pair<const MoveOnly, MoveOnly>>> C; @@ -139,7 +137,31 @@ int main() assert(r->first == 5); assert(r->second == 4); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef std::unordered_multimap<double, int> C; + typedef C::iterator R; + C c; + C::const_iterator e = c.end(); + R r = c.insert(e, {3.5, 3}); + assert(c.size() == 1); + assert(r->first == 3.5); + assert(r->second == 3); + + r = c.insert(r, {3.5, 4}); + assert(c.size() == 2); + assert(r->first == 3.5); + assert(r->second == 4); + + r = c.insert(c.end(), {4.5, 4}); + assert(c.size() == 3); + assert(r->first == 4.5); + assert(r->second == 4); + + r = c.insert(c.end(), {5.5, 4}); + assert(c.size() == 4); + assert(r->first == 5.5); + assert(r->second == 4); + } #if _LIBCPP_DEBUG >= 1 { typedef std::unordered_multimap<double, int> C; @@ -152,5 +174,4 @@ int main() assert(false); } #endif -#endif } diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_init.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_init.pass.cpp index 23dbe84a3c514..851b36e51ca4e 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_init.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_init.pass.cpp @@ -70,7 +70,7 @@ int main() assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_range.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_range.pass.cpp index 2820639b4ea05..967ad369da3f5 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_range.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_range.pass.cpp @@ -70,7 +70,7 @@ int main() assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_rvalue.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_rvalue.pass.cpp index 5a98467e9d0f7..6735b8af5a0a8 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_rvalue.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_rvalue.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <unordered_map> // template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, @@ -50,7 +52,6 @@ int main() assert(r->first == 5.5); assert(r->second == 4); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::unordered_multimap<MoveOnly, MoveOnly> C; typedef C::iterator R; @@ -76,8 +77,6 @@ int main() assert(r->first == 5); assert(r->second == 4); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L { typedef std::unordered_multimap<double, int, std::hash<double>, std::equal_to<double>, min_allocator<std::pair<const double, int>>> C; @@ -104,7 +103,6 @@ int main() assert(r->first == 5.5); assert(r->second == 4); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, min_allocator<std::pair<const MoveOnly, MoveOnly>>> C; @@ -131,6 +129,28 @@ int main() assert(r->first == 5); assert(r->second == 4); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#endif + { + typedef std::unordered_multimap<double, MoveOnly> C; + typedef C::iterator R; + C c; + R r = c.insert({3.5, 3}); + assert(c.size() == 1); + assert(r->first == 3.5); + assert(r->second == 3); + + r = c.insert({3.5, 4}); + assert(c.size() == 2); + assert(r->first == 3.5); + assert(r->second == 4); + + r = c.insert({4.5, 4}); + assert(c.size() == 3); + assert(r->first == 4.5); + assert(r->second == 4); + + r = c.insert({5.5, 4}); + assert(c.size() == 4); + assert(r->first == 5.5); + assert(r->second == 4); + } } 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 7c912e01d5725..553131182315f 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <unordered_map> // void swap(unordered_multimap& c) @@ -26,6 +28,7 @@ #include <unordered_map> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -33,20 +36,20 @@ template <class T> struct some_comp { typedef T value_type; - + some_comp() {} some_comp(const some_comp&) {} + bool operator()(const T&, const T&) const { return false; } }; 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; + bool operator()(const T&, const T&) const { return false; } }; #if TEST_STD_VER >= 14 @@ -79,7 +82,7 @@ template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -91,7 +94,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -104,7 +107,7 @@ template <class T> struct some_alloc3 { typedef T value_type; - + some_alloc3() {} some_alloc3(const some_alloc3&); void deallocate(void*, unsigned) {} @@ -115,7 +118,6 @@ struct some_alloc3 int main() { -#if __has_feature(cxx_noexcept) typedef std::pair<const MoveOnly, MoveOnly> V; { typedef std::unordered_multimap<MoveOnly, MoveOnly> C; @@ -193,6 +195,4 @@ int main() static_assert( noexcept(swap(c1, c2)), ""); } #endif - -#endif } diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.swap/swap_non_member.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.swap/swap_non_member.pass.cpp index 0f579e091683f..84911ba01ffb9 100644 --- a/test/std/containers/unord/unord.multimap/unord.multimap.swap/swap_non_member.pass.cpp +++ b/test/std/containers/unord/unord.multimap/unord.multimap.swap/swap_non_member.pass.cpp @@ -395,7 +395,7 @@ int main() 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; diff --git a/test/std/containers/unord/unord.multiset/bucket.pass.cpp b/test/std/containers/unord/unord.multiset/bucket.pass.cpp index 0293133d494ae..30858c79a0483 100644 --- a/test/std/containers/unord/unord.multiset/bucket.pass.cpp +++ b/test/std/containers/unord/unord.multiset/bucket.pass.cpp @@ -44,7 +44,7 @@ int main() for (size_t i = 0; i < 13; ++i) assert(c.bucket(i) == i % bc); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/bucket_count.pass.cpp b/test/std/containers/unord/unord.multiset/bucket_count.pass.cpp index c7842e5c1977e..adde647cb246b 100644 --- a/test/std/containers/unord/unord.multiset/bucket_count.pass.cpp +++ b/test/std/containers/unord/unord.multiset/bucket_count.pass.cpp @@ -47,7 +47,7 @@ int main() 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_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/bucket_size.pass.cpp b/test/std/containers/unord/unord.multiset/bucket_size.pass.cpp index 639d7ac379658..7ca480556349d 100644 --- a/test/std/containers/unord/unord.multiset/bucket_size.pass.cpp +++ b/test/std/containers/unord/unord.multiset/bucket_size.pass.cpp @@ -48,7 +48,7 @@ int main() assert(c.bucket_size(5) == 0); assert(c.bucket_size(6) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/clear.pass.cpp b/test/std/containers/unord/unord.multiset/clear.pass.cpp index 61ca847e7c4a6..57dbb8b1faaa1 100644 --- a/test/std/containers/unord/unord.multiset/clear.pass.cpp +++ b/test/std/containers/unord/unord.multiset/clear.pass.cpp @@ -38,7 +38,7 @@ int main() c.clear(); assert(c.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/count.pass.cpp b/test/std/containers/unord/unord.multiset/count.pass.cpp index e548324d95454..9f61845fa69c4 100644 --- a/test/std/containers/unord/unord.multiset/count.pass.cpp +++ b/test/std/containers/unord/unord.multiset/count.pass.cpp @@ -43,7 +43,7 @@ int main() assert(c.count(50) == 3); assert(c.count(5) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/db_iterators_7.pass.cpp b/test/std/containers/unord/unord.multiset/db_iterators_7.pass.cpp index c8ef2fbca163c..91f083b241d6c 100644 --- a/test/std/containers/unord/unord.multiset/db_iterators_7.pass.cpp +++ b/test/std/containers/unord/unord.multiset/db_iterators_7.pass.cpp @@ -35,7 +35,7 @@ int main() ++i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::unordered_multiset<T, min_allocator<T>> C; diff --git a/test/std/containers/unord/unord.multiset/db_iterators_8.pass.cpp b/test/std/containers/unord/unord.multiset/db_iterators_8.pass.cpp index eef7997879477..3d78ed4c022f3 100644 --- a/test/std/containers/unord/unord.multiset/db_iterators_8.pass.cpp +++ b/test/std/containers/unord/unord.multiset/db_iterators_8.pass.cpp @@ -33,7 +33,7 @@ int main() T j = *i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::unordered_multiset<T, min_allocator<T>> C; diff --git a/test/std/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp b/test/std/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp index c1de95cace718..cf8874803cb70 100644 --- a/test/std/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp +++ b/test/std/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp @@ -34,7 +34,7 @@ int main() ++i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::unordered_multiset<T, min_allocator<T>> C; diff --git a/test/std/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp b/test/std/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp index 962b85298ae1f..46e5ba7d5f845 100644 --- a/test/std/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp +++ b/test/std/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp @@ -33,7 +33,7 @@ int main() T j = *i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::unordered_multiset<T, min_allocator<T>> C; diff --git a/test/std/containers/unord/unord.multiset/emplace.pass.cpp b/test/std/containers/unord/unord.multiset/emplace.pass.cpp index 13787d9b4037c..d8d9e9bc56957 100644 --- a/test/std/containers/unord/unord.multiset/emplace.pass.cpp +++ b/test/std/containers/unord/unord.multiset/emplace.pass.cpp @@ -41,7 +41,7 @@ int main() assert(c.size() == 3); assert(*r == Emplaceable(5, 6)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<Emplaceable, std::hash<Emplaceable>, std::equal_to<Emplaceable>, min_allocator<Emplaceable>> C; diff --git a/test/std/containers/unord/unord.multiset/emplace_hint.pass.cpp b/test/std/containers/unord/unord.multiset/emplace_hint.pass.cpp index 8885cc03cf032..3756476dc8fc7 100644 --- a/test/std/containers/unord/unord.multiset/emplace_hint.pass.cpp +++ b/test/std/containers/unord/unord.multiset/emplace_hint.pass.cpp @@ -46,7 +46,7 @@ int main() assert(c.size() == 3); assert(*r == Emplaceable(5, 6)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<Emplaceable, std::hash<Emplaceable>, std::equal_to<Emplaceable>, min_allocator<Emplaceable>> C; diff --git a/test/std/containers/unord/unord.multiset/eq.pass.cpp b/test/std/containers/unord/unord.multiset/eq.pass.cpp index bbedbc905a4bb..9c59d0cf5e9f2 100644 --- a/test/std/containers/unord/unord.multiset/eq.pass.cpp +++ b/test/std/containers/unord/unord.multiset/eq.pass.cpp @@ -99,7 +99,7 @@ int main() assert( (c1 == c2)); assert(!(c1 != c2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/equal_range_const.pass.cpp b/test/std/containers/unord/unord.multiset/equal_range_const.pass.cpp index a0aaac2bd868d..e89410e61633a 100644 --- a/test/std/containers/unord/unord.multiset/equal_range_const.pass.cpp +++ b/test/std/containers/unord/unord.multiset/equal_range_const.pass.cpp @@ -53,7 +53,7 @@ int main() ++r.first; assert(*r.first == 50); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/equal_range_non_const.pass.cpp b/test/std/containers/unord/unord.multiset/equal_range_non_const.pass.cpp index 73d44f7a56b72..a9373cec65170 100644 --- a/test/std/containers/unord/unord.multiset/equal_range_non_const.pass.cpp +++ b/test/std/containers/unord/unord.multiset/equal_range_non_const.pass.cpp @@ -53,7 +53,7 @@ int main() ++r.first; assert(*r.first == 50); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; 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 d3be2b6d63654..117e8e68efab6 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 @@ -52,7 +52,7 @@ int main() assert(c.count(3) == 1); assert(c.count(4) == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; @@ -76,7 +76,7 @@ int main() assert(c.count(4) == 1); } #endif -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 { // This is LWG #2059 typedef TemplateConstructor T; diff --git a/test/std/containers/unord/unord.multiset/erase_key.pass.cpp b/test/std/containers/unord/unord.multiset/erase_key.pass.cpp index 7c243973f1638..e8ff71d0316b8 100644 --- a/test/std/containers/unord/unord.multiset/erase_key.pass.cpp +++ b/test/std/containers/unord/unord.multiset/erase_key.pass.cpp @@ -21,12 +21,12 @@ #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()) { if ( *w == *p ) p++; @@ -95,7 +95,7 @@ int main() assert(c.erase(3) == 0); assert(c.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; @@ -160,7 +160,7 @@ int main() m.insert(i); m.insert(i); m2.insert(i); m2.insert(i); } - + C::iterator i = m2.begin(); int ctr = 0; while (i != m2.end()) { diff --git a/test/std/containers/unord/unord.multiset/erase_range.pass.cpp b/test/std/containers/unord/unord.multiset/erase_range.pass.cpp index baac08eddc1ea..a4f703df85066 100644 --- a/test/std/containers/unord/unord.multiset/erase_range.pass.cpp +++ b/test/std/containers/unord/unord.multiset/erase_range.pass.cpp @@ -55,7 +55,7 @@ int main() assert(c.size() == 0); assert(k == c.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/find_const.pass.cpp b/test/std/containers/unord/unord.multiset/find_const.pass.cpp index 5caaf207aaf24..505266b1f0225 100644 --- a/test/std/containers/unord/unord.multiset/find_const.pass.cpp +++ b/test/std/containers/unord/unord.multiset/find_const.pass.cpp @@ -42,7 +42,7 @@ int main() i = c.find(5); assert(i == c.cend()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/find_non_const.pass.cpp b/test/std/containers/unord/unord.multiset/find_non_const.pass.cpp index 030487863f98c..32ee79aa7554a 100644 --- a/test/std/containers/unord/unord.multiset/find_non_const.pass.cpp +++ b/test/std/containers/unord/unord.multiset/find_non_const.pass.cpp @@ -42,7 +42,7 @@ int main() i = c.find(5); assert(i == c.cend()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/incomplete.pass.cpp b/test/std/containers/unord/unord.multiset/incomplete.pass.cpp new file mode 100644 index 0000000000000..f6d8dc17c5a2e --- /dev/null +++ b/test/std/containers/unord/unord.multiset/incomplete.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. +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// Check that std::unordered_multiset and it's iterators can be instantiated with an incomplete +// type. + +#include <unordered_set> + +template <class Tp> +struct MyHash { + MyHash() {} + std::size_t operator()(Tp const&) const {return 42;} +}; + +struct A { + typedef std::unordered_multiset<A, MyHash<A> > Map; + Map m; + Map::iterator it; + Map::const_iterator cit; + Map::local_iterator lit; + Map::const_local_iterator clit; +}; + +inline bool operator==(A const& L, A const& R) { return &L == &R; } + +int main() { + A a; +} diff --git a/test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.cpp b/test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.cpp new file mode 100644 index 0000000000000..ad7bc043a5b32 --- /dev/null +++ b/test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.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. +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// class unordered_multiset + +// insert(...) + +// UNSUPPORTED: c++98, c++03 + +#include <unordered_set> +#include "container_test_types.h" +#include "../../set_allocator_requirement_test_templates.h" + +int main() +{ + testMultisetInsert<TCT::unordered_multiset<> >(); +} diff --git a/test/std/containers/unord/unord.multiset/insert_const_lvalue.pass.cpp b/test/std/containers/unord/unord.multiset/insert_const_lvalue.pass.cpp index 0051e497fd7ab..946858ea53dc7 100644 --- a/test/std/containers/unord/unord.multiset/insert_const_lvalue.pass.cpp +++ b/test/std/containers/unord/unord.multiset/insert_const_lvalue.pass.cpp @@ -43,7 +43,7 @@ int main() assert(c.size() == 4); assert(*r == 5.5); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<double, std::hash<double>, std::equal_to<double>, min_allocator<double>> C; diff --git a/test/std/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp b/test/std/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp index 25b4bc1aa04a3..a6ab26659b556 100644 --- a/test/std/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp +++ b/test/std/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp @@ -48,7 +48,7 @@ int main() assert(c.size() == 4); assert(*r == 5.5); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<double, std::hash<double>, std::equal_to<double>, min_allocator<double>> C; diff --git a/test/std/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp b/test/std/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp index 481ec80231c95..f5026e102c422 100644 --- a/test/std/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp +++ b/test/std/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp @@ -73,7 +73,7 @@ int main() assert(*r == 5); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<double, std::hash<double>, std::equal_to<double>, min_allocator<double>> C; diff --git a/test/std/containers/unord/unord.multiset/insert_init.pass.cpp b/test/std/containers/unord/unord.multiset/insert_init.pass.cpp index 6941d86f61973..9010cac99caf5 100644 --- a/test/std/containers/unord/unord.multiset/insert_init.pass.cpp +++ b/test/std/containers/unord/unord.multiset/insert_init.pass.cpp @@ -44,7 +44,7 @@ int main() assert(c.count(3) == 1); assert(c.count(4) == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/insert_range.pass.cpp b/test/std/containers/unord/unord.multiset/insert_range.pass.cpp index 41c9d8136feb2..3d36ff9d4ce1c 100644 --- a/test/std/containers/unord/unord.multiset/insert_range.pass.cpp +++ b/test/std/containers/unord/unord.multiset/insert_range.pass.cpp @@ -44,7 +44,7 @@ int main() assert(c.count(3) == 1); assert(c.count(4) == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/insert_rvalue.pass.cpp b/test/std/containers/unord/unord.multiset/insert_rvalue.pass.cpp index 2718324b4d082..04f9e34164ab7 100644 --- a/test/std/containers/unord/unord.multiset/insert_rvalue.pass.cpp +++ b/test/std/containers/unord/unord.multiset/insert_rvalue.pass.cpp @@ -67,7 +67,7 @@ int main() assert(*r == 5); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<double, std::hash<double>, std::equal_to<double>, min_allocator<double>> C; diff --git a/test/std/containers/unord/unord.multiset/iterators.pass.cpp b/test/std/containers/unord/unord.multiset/iterators.pass.cpp index be95b44517fe0..bf42740c23fb0 100644 --- a/test/std/containers/unord/unord.multiset/iterators.pass.cpp +++ b/test/std/containers/unord/unord.multiset/iterators.pass.cpp @@ -65,7 +65,7 @@ int main() assert(std::distance(c.cbegin(), c.cend()) == c.size()); C::const_iterator i; } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/load_factor.pass.cpp b/test/std/containers/unord/unord.multiset/load_factor.pass.cpp index 2a5724b3d270d..fad1c182e6b7f 100644 --- a/test/std/containers/unord/unord.multiset/load_factor.pass.cpp +++ b/test/std/containers/unord/unord.multiset/load_factor.pass.cpp @@ -47,7 +47,7 @@ int main() const C c; assert(c.load_factor() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/local_iterators.pass.cpp b/test/std/containers/unord/unord.multiset/local_iterators.pass.cpp index 3471707e42a16..8ba9f0f9579d3 100644 --- a/test/std/containers/unord/unord.multiset/local_iterators.pass.cpp +++ b/test/std/containers/unord/unord.multiset/local_iterators.pass.cpp @@ -259,7 +259,7 @@ int main() j = c.cend(b); assert(std::distance(i, j) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/max_bucket_count.pass.cpp b/test/std/containers/unord/unord.multiset/max_bucket_count.pass.cpp index 619a8cf1266fb..510ba5fe4da0f 100644 --- a/test/std/containers/unord/unord.multiset/max_bucket_count.pass.cpp +++ b/test/std/containers/unord/unord.multiset/max_bucket_count.pass.cpp @@ -27,7 +27,7 @@ int main() const C c; assert(c.max_bucket_count() > 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/max_load_factor.pass.cpp b/test/std/containers/unord/unord.multiset/max_load_factor.pass.cpp index 08f52bb70840d..00fe962327f8a 100644 --- a/test/std/containers/unord/unord.multiset/max_load_factor.pass.cpp +++ b/test/std/containers/unord/unord.multiset/max_load_factor.pass.cpp @@ -41,7 +41,7 @@ int main() c.max_load_factor(2.5); assert(c.max_load_factor() == 2.5); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/max_size.pass.cpp b/test/std/containers/unord/unord.multiset/max_size.pass.cpp index a5d0b5538bce7..b26ad73fed2b1 100644 --- a/test/std/containers/unord/unord.multiset/max_size.pass.cpp +++ b/test/std/containers/unord/unord.multiset/max_size.pass.cpp @@ -26,7 +26,7 @@ int main() std::unordered_multiset<int> u; assert(u.max_size() > 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> u; diff --git a/test/std/containers/unord/unord.multiset/rehash.pass.cpp b/test/std/containers/unord/unord.multiset/rehash.pass.cpp index 5c7c6aa8aad33..3ad16a6bcbfe2 100644 --- a/test/std/containers/unord/unord.multiset/rehash.pass.cpp +++ b/test/std/containers/unord/unord.multiset/rehash.pass.cpp @@ -67,7 +67,7 @@ int main() assert(c.bucket_count() == 31); test(c); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/reserve.pass.cpp b/test/std/containers/unord/unord.multiset/reserve.pass.cpp index 1d393a09cde23..52d51011fe363 100644 --- a/test/std/containers/unord/unord.multiset/reserve.pass.cpp +++ b/test/std/containers/unord/unord.multiset/reserve.pass.cpp @@ -73,7 +73,7 @@ int main() assert(c.bucket_count() >= 16); test(c); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.multiset/swap_member.pass.cpp b/test/std/containers/unord/unord.multiset/swap_member.pass.cpp index 275ff4094e810..bc3314c867ebc 100644 --- a/test/std/containers/unord/unord.multiset/swap_member.pass.cpp +++ b/test/std/containers/unord/unord.multiset/swap_member.pass.cpp @@ -386,7 +386,7 @@ int main() 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; diff --git a/test/std/containers/unord/unord.multiset/types.pass.cpp b/test/std/containers/unord/unord.multiset/types.pass.cpp index 5222222d81978..ee5c2c38ac0c3 100644 --- a/test/std/containers/unord/unord.multiset/types.pass.cpp +++ b/test/std/containers/unord/unord.multiset/types.pass.cpp @@ -48,7 +48,7 @@ int main() static_assert((std::is_same<C::size_type, std::size_t>::value), ""); static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), ""); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<short, std::hash<short>, std::equal_to<short>, min_allocator<short>> C; diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/allocator.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/allocator.pass.cpp index ccd21a58b22c2..8d020a52ac043 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/allocator.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/allocator.pass.cpp @@ -43,7 +43,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp index 2042f69fd772c..f219073cffcbe 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp @@ -151,7 +151,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<int> A; typedef std::unordered_multiset<int, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_init.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_init.pass.cpp index 4eaf2c5779f3e..2835cd444c30e 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_init.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_init.pass.cpp @@ -59,7 +59,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<int> A; typedef std::unordered_multiset<int, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp index 4b0e52c5930c8..52d08f3e2293f 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp @@ -170,7 +170,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef test_allocator<int> A; typedef std::unordered_multiset<int, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/compare_copy_constructible.fail.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/compare_copy_constructible.fail.cpp new file mode 100644 index 0000000000000..b38316c37689a --- /dev/null +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/compare_copy_constructible.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. +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// Check that std::unordered_set fails to instantiate if the comparison predicate is +// not copy-constructible. This is LWG issue 2436 + +#include <unordered_set> + +template <class T> +struct Comp { + bool operator () (const T& lhs, const T& rhs) const { return lhs == rhs; } + + Comp () {} +private: + Comp (const Comp &); // declared but not defined + }; + + +int main() { + std::unordered_multiset<int, std::hash<int>, Comp<int> > m; +} diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/copy.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/copy.pass.cpp index a91ee1dae0713..e6042b0d91233 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/copy.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/copy.pass.cpp @@ -121,7 +121,7 @@ int main() assert(c.max_load_factor() == 1); } #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/copy_alloc.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/copy_alloc.pass.cpp index 32c876d328789..5e24f72572521 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/copy_alloc.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/copy_alloc.pass.cpp @@ -73,7 +73,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp index 737ae2dae793e..e741f3208dac2 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp @@ -43,7 +43,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default_noexcept.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default_noexcept.pass.cpp index 391609fd144ad..fba024aed00ef 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default_noexcept.pass.cpp @@ -17,9 +17,12 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <unordered_set> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" #include "../../../test_hash.h" @@ -30,6 +33,7 @@ struct some_comp typedef T value_type; some_comp(); some_comp(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -42,15 +46,14 @@ struct some_hash int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_multiset<MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::unordered_multiset<MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::unordered_multiset<MoveOnly, std::hash<MoveOnly>, @@ -66,5 +69,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/dtor_noexcept.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/dtor_noexcept.pass.cpp index a549288afc144..733484510ef10 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/dtor_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/dtor_noexcept.pass.cpp @@ -11,19 +11,20 @@ // ~unordered_multiset() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <unordered_set> #include <cassert> #include "MoveOnly.h" #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_comp { typedef T value_type; ~some_comp() noexcept(false); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -35,11 +36,8 @@ struct some_hash ~some_hash() noexcept(false); }; -#endif - int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_multiset<MoveOnly> C; static_assert(std::is_nothrow_destructible<C>::value, ""); @@ -63,5 +61,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/hash_copy_constructible.fail.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/hash_copy_constructible.fail.cpp new file mode 100644 index 0000000000000..a43f94ca2af37 --- /dev/null +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/hash_copy_constructible.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. +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// Check that std::unordered_multiset fails to instantiate if the hash function is +// not copy-constructible. This is mentioned in LWG issue 2436 + +#include <unordered_set> + +template <class T> +struct Hash { + std::size_t operator () (const T& lhs) const { return 0; } + + Hash () {} +private: + Hash (const Hash &); // declared but not defined + }; + + +int main() { + std::unordered_multiset<int, Hash<int> > m; +} diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init.pass.cpp index 416c28cf83db4..53a9003b01730 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init.pass.cpp @@ -57,7 +57,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size.pass.cpp index ad42d76db9eea..e5934acc8e7c8 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size.pass.cpp @@ -60,7 +60,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash.pass.cpp index 7cc50fa300675..86253214af9cc 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash.pass.cpp @@ -62,7 +62,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal.pass.cpp index 18d3c8288cd24..47469c0c5b9b7 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal.pass.cpp @@ -63,7 +63,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal_allocator.pass.cpp index 92d9d86040bb1..d72ee6f33f505 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal_allocator.pass.cpp @@ -64,7 +64,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp index 687f2654f86c7..defd90f408b02 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp @@ -103,7 +103,7 @@ int main() assert(c0.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_alloc.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_alloc.pass.cpp index c03c605f40cea..45b4c8b4f5d57 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_alloc.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_alloc.pass.cpp @@ -118,7 +118,7 @@ int main() assert(c0.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int P; typedef min_allocator<int> A; diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.pass.cpp index 2f86f018d9fe7..fbd6df14c0520 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_assign_noexcept.pass.cpp @@ -17,6 +17,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <unordered_set> #include <cassert> @@ -28,6 +30,7 @@ struct some_comp { typedef T value_type; some_comp& operator=(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -41,7 +44,6 @@ struct some_hash int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_multiset<MoveOnly> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); @@ -65,5 +67,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_noexcept.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_noexcept.pass.cpp index 8a4c3c945364b..e84ffb7b2fdec 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_noexcept.pass.cpp @@ -15,6 +15,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <unordered_set> #include <cassert> @@ -26,6 +28,7 @@ struct some_comp { typedef T value_type; some_comp(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -38,7 +41,6 @@ struct some_hash int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_multiset<MoveOnly> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); @@ -62,5 +64,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range.pass.cpp index cd2bb1e7bbcd3..12679ef3e13ee 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range.pass.cpp @@ -60,7 +60,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size.pass.cpp index f2d0db932bd79..c9454cf630dbc 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size.pass.cpp @@ -63,7 +63,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash.pass.cpp index dc40b361d1f3a..5ff61575d994c 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash.pass.cpp @@ -65,7 +65,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal.pass.cpp index c316b7809d539..ecf3176e90a46 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal.pass.cpp @@ -66,7 +66,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal_allocator.pass.cpp index ab76248c326c9..18a092c83f6ae 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal_allocator.pass.cpp @@ -68,7 +68,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size.fail.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size.fail.cpp index e55db7ca2aaf2..215b31fef65f9 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size.fail.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size.fail.cpp @@ -43,7 +43,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size.pass.cpp index 35bfbe331b41e..38211f958c432 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size.pass.cpp @@ -43,7 +43,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash.pass.cpp index 0171ea64ebb18..baeabd1b2d081 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash.pass.cpp @@ -45,7 +45,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal.pass.cpp index 785cdf2463682..380f36df7bf2a 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal.pass.cpp @@ -46,7 +46,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal_allocator.pass.cpp index 50dd3c95ee529..149d045e07a95 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal_allocator.pass.cpp @@ -47,7 +47,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_multiset<NotConstructible, test_hash<std::hash<NotConstructible> >, 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 63642fcd7cca5..df9f18b147e32 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <unordered_set> // void swap(unordered_multiset& c) @@ -26,6 +28,7 @@ #include <unordered_set> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -33,20 +36,20 @@ template <class T> struct some_comp { typedef T value_type; - + some_comp() {} some_comp(const some_comp&) {} + bool operator()(const T&, const T&) const { return false; } }; 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; + bool operator()(const T&, const T&) const { return false; } }; #if TEST_STD_VER >= 14 @@ -60,6 +63,7 @@ struct some_hash typedef T value_type; some_hash() {} some_hash(const some_hash&); + std::size_t operator()(const T&) const { return 0; } }; template <class T> @@ -68,6 +72,7 @@ struct some_hash2 typedef T value_type; some_hash2() {} some_hash2(const some_hash2&); + std::size_t operator()(const T&) const { return 0; } }; #if TEST_STD_VER >= 14 @@ -79,7 +84,7 @@ template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -91,7 +96,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -104,7 +109,7 @@ template <class T> struct some_alloc3 { typedef T value_type; - + some_alloc3() {} some_alloc3(const some_alloc3&); void deallocate(void*, unsigned) {} @@ -115,7 +120,6 @@ struct some_alloc3 int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_multiset<MoveOnly> C; C c1, c2; @@ -193,6 +197,4 @@ int main() static_assert( noexcept(swap(c1, c2)), ""); } #endif - -#endif } diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.swap/swap_non_member.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.swap/swap_non_member.pass.cpp index 624b81c5eb3ec..4b1c129508e17 100644 --- a/test/std/containers/unord/unord.multiset/unord.multiset.swap/swap_non_member.pass.cpp +++ b/test/std/containers/unord/unord.multiset/unord.multiset.swap/swap_non_member.pass.cpp @@ -386,7 +386,7 @@ int main() 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; diff --git a/test/std/containers/unord/unord.set/bucket.pass.cpp b/test/std/containers/unord/unord.set/bucket.pass.cpp index 0dae664e0b23e..9b704ccee0c01 100644 --- a/test/std/containers/unord/unord.set/bucket.pass.cpp +++ b/test/std/containers/unord/unord.set/bucket.pass.cpp @@ -44,7 +44,7 @@ int main() for (size_t i = 0; i < 13; ++i) assert(c.bucket(i) == i % bc); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; typedef int P; diff --git a/test/std/containers/unord/unord.set/bucket_count.pass.cpp b/test/std/containers/unord/unord.set/bucket_count.pass.cpp index caaa5a6011a90..e35e43615dd35 100644 --- a/test/std/containers/unord/unord.set/bucket_count.pass.cpp +++ b/test/std/containers/unord/unord.set/bucket_count.pass.cpp @@ -47,7 +47,7 @@ int main() 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_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; typedef C::const_iterator I; diff --git a/test/std/containers/unord/unord.set/bucket_size.pass.cpp b/test/std/containers/unord/unord.set/bucket_size.pass.cpp index 628d55737a828..2ae618c85e5b0 100644 --- a/test/std/containers/unord/unord.set/bucket_size.pass.cpp +++ b/test/std/containers/unord/unord.set/bucket_size.pass.cpp @@ -46,7 +46,7 @@ int main() assert(c.bucket_size(3) == 1); assert(c.bucket_size(4) == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; typedef int P; diff --git a/test/std/containers/unord/unord.set/clear.pass.cpp b/test/std/containers/unord/unord.set/clear.pass.cpp index 6da15308508c3..8ebf748eb8dac 100644 --- a/test/std/containers/unord/unord.set/clear.pass.cpp +++ b/test/std/containers/unord/unord.set/clear.pass.cpp @@ -38,7 +38,7 @@ int main() c.clear(); assert(c.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; typedef int P; diff --git a/test/std/containers/unord/unord.set/count.pass.cpp b/test/std/containers/unord/unord.set/count.pass.cpp index 83bb8aaa2be03..18cac7cf9b0d6 100644 --- a/test/std/containers/unord/unord.set/count.pass.cpp +++ b/test/std/containers/unord/unord.set/count.pass.cpp @@ -43,7 +43,7 @@ int main() assert(c.count(50) == 1); assert(c.count(5) == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; typedef int P; diff --git a/test/std/containers/unord/unord.set/db_iterators_7.pass.cpp b/test/std/containers/unord/unord.set/db_iterators_7.pass.cpp index 80b1a49c57588..647e30b8089cc 100644 --- a/test/std/containers/unord/unord.set/db_iterators_7.pass.cpp +++ b/test/std/containers/unord/unord.set/db_iterators_7.pass.cpp @@ -35,7 +35,7 @@ int main() ++i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::unordered_set<T, min_allocator<T>> C; diff --git a/test/std/containers/unord/unord.set/db_iterators_8.pass.cpp b/test/std/containers/unord/unord.set/db_iterators_8.pass.cpp index 8b266bbf664f1..4c303194c20e3 100644 --- a/test/std/containers/unord/unord.set/db_iterators_8.pass.cpp +++ b/test/std/containers/unord/unord.set/db_iterators_8.pass.cpp @@ -33,7 +33,7 @@ int main() T j = *i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::unordered_set<T, min_allocator<T>> C; diff --git a/test/std/containers/unord/unord.set/db_local_iterators_7.pass.cpp b/test/std/containers/unord/unord.set/db_local_iterators_7.pass.cpp index b9fcb8c4ae0c3..9dbd43d2f7a8a 100644 --- a/test/std/containers/unord/unord.set/db_local_iterators_7.pass.cpp +++ b/test/std/containers/unord/unord.set/db_local_iterators_7.pass.cpp @@ -34,7 +34,7 @@ int main() ++i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::unordered_set<T, min_allocator<T>> C; diff --git a/test/std/containers/unord/unord.set/db_local_iterators_8.pass.cpp b/test/std/containers/unord/unord.set/db_local_iterators_8.pass.cpp index 74d131b19abe7..1212321fe1d10 100644 --- a/test/std/containers/unord/unord.set/db_local_iterators_8.pass.cpp +++ b/test/std/containers/unord/unord.set/db_local_iterators_8.pass.cpp @@ -33,7 +33,7 @@ int main() T j = *i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int T; typedef std::unordered_set<T, min_allocator<T>> C; diff --git a/test/std/containers/unord/unord.set/emplace.pass.cpp b/test/std/containers/unord/unord.set/emplace.pass.cpp index d105e7ac0f4e0..19af8065819cc 100644 --- a/test/std/containers/unord/unord.set/emplace.pass.cpp +++ b/test/std/containers/unord/unord.set/emplace.pass.cpp @@ -44,7 +44,7 @@ int main() assert(*r.first == Emplaceable(5, 6)); assert(!r.second); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<Emplaceable, std::hash<Emplaceable>, std::equal_to<Emplaceable>, min_allocator<Emplaceable>> C; diff --git a/test/std/containers/unord/unord.set/emplace_hint.pass.cpp b/test/std/containers/unord/unord.set/emplace_hint.pass.cpp index 50b0035165d20..97f3591d012bd 100644 --- a/test/std/containers/unord/unord.set/emplace_hint.pass.cpp +++ b/test/std/containers/unord/unord.set/emplace_hint.pass.cpp @@ -46,7 +46,7 @@ int main() assert(c.size() == 2); assert(*r == Emplaceable(5, 6)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<Emplaceable, std::hash<Emplaceable>, std::equal_to<Emplaceable>, min_allocator<Emplaceable>> C; diff --git a/test/std/containers/unord/unord.set/eq.pass.cpp b/test/std/containers/unord/unord.set/eq.pass.cpp index 54a9c2eced34d..8ff4ac5df37f1 100644 --- a/test/std/containers/unord/unord.set/eq.pass.cpp +++ b/test/std/containers/unord/unord.set/eq.pass.cpp @@ -90,7 +90,7 @@ int main() assert( (c1 == c2)); assert(!(c1 != c2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; typedef int P; diff --git a/test/std/containers/unord/unord.set/equal_range_const.pass.cpp b/test/std/containers/unord/unord.set/equal_range_const.pass.cpp index 4168903e02004..9fa4129c330a1 100644 --- a/test/std/containers/unord/unord.set/equal_range_const.pass.cpp +++ b/test/std/containers/unord/unord.set/equal_range_const.pass.cpp @@ -49,7 +49,7 @@ int main() assert(std::distance(r.first, r.second) == 1); assert(*r.first == 50); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; typedef C::const_iterator I; diff --git a/test/std/containers/unord/unord.set/equal_range_non_const.pass.cpp b/test/std/containers/unord/unord.set/equal_range_non_const.pass.cpp index 5a55083ba8ab9..c6a42aceaaf2e 100644 --- a/test/std/containers/unord/unord.set/equal_range_non_const.pass.cpp +++ b/test/std/containers/unord/unord.set/equal_range_non_const.pass.cpp @@ -49,7 +49,7 @@ int main() assert(std::distance(r.first, r.second) == 1); assert(*r.first == 50); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; typedef C::iterator I; 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 4110953badb64..c78eb138fd90b 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 @@ -51,7 +51,7 @@ int main() assert(c.count(3) == 1); assert(c.count(4) == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; typedef int P; @@ -73,7 +73,7 @@ int main() assert(c.count(4) == 1); } #endif -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 { // This is LWG #2059 typedef TemplateConstructor T; diff --git a/test/std/containers/unord/unord.set/erase_key.pass.cpp b/test/std/containers/unord/unord.set/erase_key.pass.cpp index ca165083b0235..ea0323ba2dac0 100644 --- a/test/std/containers/unord/unord.set/erase_key.pass.cpp +++ b/test/std/containers/unord/unord.set/erase_key.pass.cpp @@ -21,12 +21,12 @@ #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()) { if ( *w == *p ) p++; @@ -95,7 +95,7 @@ int main() assert(c.erase(3) == 0); assert(c.size() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; typedef int P; @@ -159,7 +159,7 @@ int main() m.insert(i); m2.insert(i); } - + C::iterator i = m2.begin(); int ctr = 0; while (i != m2.end()) { diff --git a/test/std/containers/unord/unord.set/erase_range.pass.cpp b/test/std/containers/unord/unord.set/erase_range.pass.cpp index a8a900551c7b8..4e49a86ef836a 100644 --- a/test/std/containers/unord/unord.set/erase_range.pass.cpp +++ b/test/std/containers/unord/unord.set/erase_range.pass.cpp @@ -55,7 +55,7 @@ int main() assert(c.size() == 0); assert(k == c.end()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; typedef int P; diff --git a/test/std/containers/unord/unord.set/find_const.pass.cpp b/test/std/containers/unord/unord.set/find_const.pass.cpp index e2238e5665f9e..bd4542c876bf0 100644 --- a/test/std/containers/unord/unord.set/find_const.pass.cpp +++ b/test/std/containers/unord/unord.set/find_const.pass.cpp @@ -42,7 +42,7 @@ int main() i = c.find(5); assert(i == c.cend()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; typedef int P; diff --git a/test/std/containers/unord/unord.set/find_non_const.pass.cpp b/test/std/containers/unord/unord.set/find_non_const.pass.cpp index 8afe32abd72fd..4c81fc60a393e 100644 --- a/test/std/containers/unord/unord.set/find_non_const.pass.cpp +++ b/test/std/containers/unord/unord.set/find_non_const.pass.cpp @@ -42,7 +42,7 @@ int main() i = c.find(5); assert(i == c.cend()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; typedef int P; diff --git a/test/std/containers/unord/unord.set/incomplete.pass.cpp b/test/std/containers/unord/unord.set/incomplete.pass.cpp new file mode 100644 index 0000000000000..c970c1de5531f --- /dev/null +++ b/test/std/containers/unord/unord.set/incomplete.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. +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// Check that std::unordered_set and it's iterators can be instantiated with an incomplete +// type. + +#include <unordered_set> + +template <class Tp> +struct MyHash { + MyHash() {} + std::size_t operator()(Tp const&) const {return 42;} +}; + +struct A { + typedef std::unordered_set<A, MyHash<A> > Map; + Map m; + Map::iterator it; + Map::const_iterator cit; + Map::local_iterator lit; + Map::const_local_iterator clit; +}; + +inline bool operator==(A const& L, A const& R) { return &L == &R; } + +int main() { + A a; +} diff --git a/test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp b/test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp new file mode 100644 index 0000000000000..e85e94538e741 --- /dev/null +++ b/test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.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. +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// class unordered_set + +// insert(...) +// emplace(...) + +// UNSUPPORTED: c++98, c++03 + +#include <unordered_set> + +#include "container_test_types.h" +#include "../../set_allocator_requirement_test_templates.h" + + +int main() +{ + testSetInsert<TCT::unordered_set<> >(); + testSetEmplace<TCT::unordered_set<> >(); +} diff --git a/test/std/containers/unord/unord.set/insert_const_lvalue.pass.cpp b/test/std/containers/unord/unord.set/insert_const_lvalue.pass.cpp index 321e9054af6cb..fe45b98a33a61 100644 --- a/test/std/containers/unord/unord.set/insert_const_lvalue.pass.cpp +++ b/test/std/containers/unord/unord.set/insert_const_lvalue.pass.cpp @@ -47,7 +47,7 @@ int main() assert(*r.first == 5.5); assert(r.second); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<double, std::hash<double>, std::equal_to<double>, min_allocator<double>> C; diff --git a/test/std/containers/unord/unord.set/insert_hint_const_lvalue.pass.cpp b/test/std/containers/unord/unord.set/insert_hint_const_lvalue.pass.cpp index 1393f54201116..d3bbecc95ad77 100644 --- a/test/std/containers/unord/unord.set/insert_hint_const_lvalue.pass.cpp +++ b/test/std/containers/unord/unord.set/insert_hint_const_lvalue.pass.cpp @@ -48,7 +48,7 @@ int main() assert(c.size() == 3); assert(*r == 5.5); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<double, std::hash<double>, std::equal_to<double>, min_allocator<double>> C; diff --git a/test/std/containers/unord/unord.set/insert_hint_rvalue.pass.cpp b/test/std/containers/unord/unord.set/insert_hint_rvalue.pass.cpp index 3f04dbb89984d..da94bc55382f2 100644 --- a/test/std/containers/unord/unord.set/insert_hint_rvalue.pass.cpp +++ b/test/std/containers/unord/unord.set/insert_hint_rvalue.pass.cpp @@ -73,7 +73,7 @@ int main() assert(*r == 5); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<double, std::hash<double>, std::equal_to<double>, min_allocator<double>> C; diff --git a/test/std/containers/unord/unord.set/insert_init.pass.cpp b/test/std/containers/unord/unord.set/insert_init.pass.cpp index 2d8eafba48915..27b7290eb341a 100644 --- a/test/std/containers/unord/unord.set/insert_init.pass.cpp +++ b/test/std/containers/unord/unord.set/insert_init.pass.cpp @@ -44,7 +44,7 @@ int main() assert(c.count(3) == 1); assert(c.count(4) == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.set/insert_range.pass.cpp b/test/std/containers/unord/unord.set/insert_range.pass.cpp index 72a83abf74e97..41b2c0e1431b6 100644 --- a/test/std/containers/unord/unord.set/insert_range.pass.cpp +++ b/test/std/containers/unord/unord.set/insert_range.pass.cpp @@ -44,7 +44,7 @@ int main() assert(c.count(3) == 1); assert(c.count(4) == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.set/insert_rvalue.pass.cpp b/test/std/containers/unord/unord.set/insert_rvalue.pass.cpp index e043579bf9718..5d12f225cc6ab 100644 --- a/test/std/containers/unord/unord.set/insert_rvalue.pass.cpp +++ b/test/std/containers/unord/unord.set/insert_rvalue.pass.cpp @@ -75,7 +75,7 @@ int main() assert(r.second); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<double, std::hash<double>, std::equal_to<double>, min_allocator<double>> C; diff --git a/test/std/containers/unord/unord.set/iterators.pass.cpp b/test/std/containers/unord/unord.set/iterators.pass.cpp index d3a45801f1623..494411854977e 100644 --- a/test/std/containers/unord/unord.set/iterators.pass.cpp +++ b/test/std/containers/unord/unord.set/iterators.pass.cpp @@ -65,7 +65,7 @@ int main() assert(std::distance(c.cbegin(), c.cend()) == c.size()); C::const_iterator i; } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.set/load_factor.pass.cpp b/test/std/containers/unord/unord.set/load_factor.pass.cpp index 3e56442d384c3..a342d472a3d58 100644 --- a/test/std/containers/unord/unord.set/load_factor.pass.cpp +++ b/test/std/containers/unord/unord.set/load_factor.pass.cpp @@ -47,7 +47,7 @@ int main() const C c; assert(c.load_factor() == 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.set/local_iterators.pass.cpp b/test/std/containers/unord/unord.set/local_iterators.pass.cpp index 2ffd93f30d19d..55c80e4cb185a 100644 --- a/test/std/containers/unord/unord.set/local_iterators.pass.cpp +++ b/test/std/containers/unord/unord.set/local_iterators.pass.cpp @@ -203,7 +203,7 @@ int main() assert(std::distance(i, j) == 1); assert(*i == 4); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.set/max_bucket_count.pass.cpp b/test/std/containers/unord/unord.set/max_bucket_count.pass.cpp index 8b5e265de3f24..dab13ea5ae5f0 100644 --- a/test/std/containers/unord/unord.set/max_bucket_count.pass.cpp +++ b/test/std/containers/unord/unord.set/max_bucket_count.pass.cpp @@ -27,7 +27,7 @@ int main() const C c; assert(c.max_bucket_count() > 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.set/max_load_factor.pass.cpp b/test/std/containers/unord/unord.set/max_load_factor.pass.cpp index d326f4a2d7e27..542788cca9678 100644 --- a/test/std/containers/unord/unord.set/max_load_factor.pass.cpp +++ b/test/std/containers/unord/unord.set/max_load_factor.pass.cpp @@ -41,7 +41,7 @@ int main() c.max_load_factor(2.5); assert(c.max_load_factor() == 2.5); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.set/max_size.pass.cpp b/test/std/containers/unord/unord.set/max_size.pass.cpp index 1c6e74125c7da..3135ad994737c 100644 --- a/test/std/containers/unord/unord.set/max_size.pass.cpp +++ b/test/std/containers/unord/unord.set/max_size.pass.cpp @@ -26,7 +26,7 @@ int main() std::unordered_set<int> u; assert(u.max_size() > 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> u; diff --git a/test/std/containers/unord/unord.set/rehash.pass.cpp b/test/std/containers/unord/unord.set/rehash.pass.cpp index e28c25dc81977..a4d4d3fbf02c9 100644 --- a/test/std/containers/unord/unord.set/rehash.pass.cpp +++ b/test/std/containers/unord/unord.set/rehash.pass.cpp @@ -67,7 +67,7 @@ int main() assert(c.bucket_count() == 31); test(c); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.set/reserve.pass.cpp b/test/std/containers/unord/unord.set/reserve.pass.cpp index 078b886b267e5..4bd5332f07966 100644 --- a/test/std/containers/unord/unord.set/reserve.pass.cpp +++ b/test/std/containers/unord/unord.set/reserve.pass.cpp @@ -73,7 +73,7 @@ int main() assert(c.bucket_count() >= 16); test(c); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/test/std/containers/unord/unord.set/swap_member.pass.cpp b/test/std/containers/unord/unord.set/swap_member.pass.cpp index 89ec986d08f32..5ddb2d00daef8 100644 --- a/test/std/containers/unord/unord.set/swap_member.pass.cpp +++ b/test/std/containers/unord/unord.set/swap_member.pass.cpp @@ -386,7 +386,7 @@ int main() 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; diff --git a/test/std/containers/unord/unord.set/types.pass.cpp b/test/std/containers/unord/unord.set/types.pass.cpp index 7e752a434ecec..fdda2b8072e36 100644 --- a/test/std/containers/unord/unord.set/types.pass.cpp +++ b/test/std/containers/unord/unord.set/types.pass.cpp @@ -48,7 +48,7 @@ int main() static_assert((std::is_same<C::size_type, std::size_t>::value), ""); static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), ""); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<short, std::hash<short>, std::equal_to<short>, min_allocator<short>> C; diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/allocator.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/allocator.pass.cpp index 30905aeb9fe26..d0b03b2cd0b8d 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/allocator.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/allocator.pass.cpp @@ -43,7 +43,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp index 6925e30454128..05cb0525eb797 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp @@ -134,7 +134,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<int> A; typedef std::unordered_set<int, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/assign_init.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/assign_init.pass.cpp index 69d19a4dac2e9..a99e74af59439 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/assign_init.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/assign_init.pass.cpp @@ -59,7 +59,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<int> A; typedef std::unordered_set<int, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/assign_move.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/assign_move.pass.cpp index e8712b7431c4e..d8732268b85f1 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/assign_move.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/assign_move.pass.cpp @@ -162,7 +162,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<int> A; typedef std::unordered_set<int, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/compare_copy_constructible.fail.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/compare_copy_constructible.fail.cpp new file mode 100644 index 0000000000000..6b675f00f16ba --- /dev/null +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/compare_copy_constructible.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. +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// Check that std::unordered_set fails to instantiate if the comparison predicate is +// not copy-constructible. This is LWG issue 2436 + +#include <unordered_set> + +template <class T> +struct Comp { + bool operator () (const T& lhs, const T& rhs) const { return lhs == rhs; } + + Comp () {} +private: + Comp (const Comp &); // declared but not defined + }; + + +int main() { + std::unordered_set<int, std::hash<int>, Comp<int> > m; +} diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/copy.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/copy.pass.cpp index e1a9b27619b7c..07278be79e57c 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/copy.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/copy.pass.cpp @@ -105,7 +105,7 @@ int main() assert(c.max_load_factor() == 1); } #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/copy_alloc.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/copy_alloc.pass.cpp index b31875befa387..59f4bfabd582e 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/copy_alloc.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/copy_alloc.pass.cpp @@ -65,7 +65,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/default.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/default.pass.cpp index 6efa9ed8d1de3..e53f381f2d6df 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/default.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/default.pass.cpp @@ -43,7 +43,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/default_noexcept.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/default_noexcept.pass.cpp index f419c31c47963..3dcc3247902ed 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/default_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/default_noexcept.pass.cpp @@ -17,9 +17,12 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <unordered_set> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" #include "../../../test_hash.h" @@ -30,6 +33,7 @@ struct some_comp typedef T value_type; some_comp(); some_comp(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -42,15 +46,14 @@ struct some_hash int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_set<MoveOnly> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::unordered_set<MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C; - static_assert(std::is_nothrow_default_constructible<C>::value, ""); + LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<C>::value, ""); } { typedef std::unordered_set<MoveOnly, std::hash<MoveOnly>, @@ -66,5 +69,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/dtor_noexcept.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/dtor_noexcept.pass.cpp index 1e196b2e119e1..b6837ccaec8da 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/dtor_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/dtor_noexcept.pass.cpp @@ -11,19 +11,20 @@ // ~unordered_set() // implied noexcept; +// UNSUPPORTED: c++98, c++03 + #include <unordered_set> #include <cassert> #include "MoveOnly.h" #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_comp { typedef T value_type; ~some_comp() noexcept(false); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -35,11 +36,8 @@ struct some_hash ~some_hash() noexcept(false); }; -#endif - int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_set<MoveOnly> C; static_assert(std::is_nothrow_destructible<C>::value, ""); @@ -63,5 +61,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/hash_copy_constructible.fail.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/hash_copy_constructible.fail.cpp new file mode 100644 index 0000000000000..066f160a25864 --- /dev/null +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/hash_copy_constructible.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. +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// Check that std::unordered_set fails to instantiate if the hash function is +// not copy-constructible. This is mentioned in LWG issue 2436 + +#include <unordered_set> + +template <class T> +struct Hash { + std::size_t operator () (const T& lhs) const { return 0; } + + Hash () {} +private: + Hash (const Hash &); // declared but not defined + }; + + +int main() { + std::unordered_set<int, Hash<int> > m; +} diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/init.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/init.pass.cpp index 2c31d575b6359..3fd0c3926c0b7 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/init.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/init.pass.cpp @@ -57,7 +57,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/init_size.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/init_size.pass.cpp index 340fc410109a4..b7eed1e5b2534 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/init_size.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/init_size.pass.cpp @@ -60,7 +60,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash.pass.cpp index fa6f0bd2ad5fc..735babd522b34 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash.pass.cpp @@ -62,7 +62,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_equal.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_equal.pass.cpp index dc3a6652ec251..643a57fa99ca8 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_equal.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_equal.pass.cpp @@ -63,7 +63,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_equal_allocator.pass.cpp index 1b006dbbc91cd..72b9ed2a1de0a 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_equal_allocator.pass.cpp @@ -64,7 +64,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/move.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/move.pass.cpp index f2a2a68d40365..e865986337c47 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/move.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/move.pass.cpp @@ -103,7 +103,7 @@ int main() assert(c0.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/move_alloc.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/move_alloc.pass.cpp index 92eb36d513b61..2342bbc130be1 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/move_alloc.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/move_alloc.pass.cpp @@ -110,7 +110,7 @@ int main() assert(c0.empty()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef int P; typedef min_allocator<int> A; diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.pass.cpp index 02af34d8f885f..45f18dbbcb5cf 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/move_assign_noexcept.pass.cpp @@ -17,6 +17,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <unordered_set> #include <cassert> @@ -28,6 +30,7 @@ struct some_comp { typedef T value_type; some_comp& operator=(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -41,7 +44,6 @@ struct some_hash int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_set<MoveOnly> C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); @@ -65,5 +67,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/move_noexcept.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/move_noexcept.pass.cpp index b2d89ba5c33bf..b4046148bc79c 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/move_noexcept.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/move_noexcept.pass.cpp @@ -15,6 +15,8 @@ // This tests a conforming extension +// UNSUPPORTED: c++98, c++03 + #include <unordered_set> #include <cassert> @@ -26,6 +28,7 @@ struct some_comp { typedef T value_type; some_comp(const some_comp&); + bool operator()(const T&, const T&) const { return false; } }; template <class T> @@ -38,7 +41,6 @@ struct some_hash int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_set<MoveOnly> C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); @@ -62,5 +64,4 @@ int main() some_comp<MoveOnly>> C; static_assert(!std::is_nothrow_move_constructible<C>::value, ""); } -#endif } diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/range.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/range.pass.cpp index 40f3f4f4d7f97..c978d8d5d8a4b 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/range.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/range.pass.cpp @@ -60,7 +60,7 @@ int main() assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/range_size.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/range_size.pass.cpp index ff50c712ab5d5..b87d5615e00e0 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/range_size.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/range_size.pass.cpp @@ -63,7 +63,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/range_size_hash.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/range_size_hash.pass.cpp index bcdcc5510c3c2..7234d8a80aec2 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/range_size_hash.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/range_size_hash.pass.cpp @@ -65,7 +65,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/range_size_hash_equal.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/range_size_hash_equal.pass.cpp index 632265ac861d6..bcf3058aa835c 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/range_size_hash_equal.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/range_size_hash_equal.pass.cpp @@ -66,7 +66,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/range_size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/range_size_hash_equal_allocator.pass.cpp index ebe54fd4cbc66..ad9b414d7f13c 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/range_size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/range_size_hash_equal_allocator.pass.cpp @@ -68,7 +68,7 @@ int main() assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<int, test_hash<std::hash<int> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/size.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/size.pass.cpp index 8f6228ad8ec4c..88e499773bf33 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/size.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/size.pass.cpp @@ -43,7 +43,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash.pass.cpp index 4c2c18edd1ce6..eb98dcc7b7e4e 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash.pass.cpp @@ -45,7 +45,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_equal.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_equal.pass.cpp index e9368782ad9a0..4ae012038ae5e 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_equal.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_equal.pass.cpp @@ -46,7 +46,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<NotConstructible, test_hash<std::hash<NotConstructible> >, diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_equal_allocator.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_equal_allocator.pass.cpp index 96233e187af5a..b2ddbe94e7410 100644 --- a/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_equal_allocator.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_equal_allocator.pass.cpp @@ -47,7 +47,7 @@ int main() assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::unordered_set<NotConstructible, test_hash<std::hash<NotConstructible> >, 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 5d746407a80cb..d35d79b312660 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <unordered_set> // void swap(unordered_set& c) @@ -26,6 +28,7 @@ #include <unordered_set> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "test_allocator.h" @@ -33,20 +36,20 @@ template <class T> struct some_comp { typedef T value_type; - + some_comp() {} some_comp(const some_comp&) {} + bool operator()(const T&, const T&) const { return false; } }; 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; + bool operator()(const T&, const T&) const { return false; } }; #if TEST_STD_VER >= 14 @@ -60,6 +63,7 @@ struct some_hash typedef T value_type; some_hash() {} some_hash(const some_hash&); + std::size_t operator()(const T&) const { return 0; } }; template <class T> @@ -68,6 +72,7 @@ struct some_hash2 typedef T value_type; some_hash2() {} some_hash2(const some_hash2&); + std::size_t operator()(const T&) const { return 0; } }; #if TEST_STD_VER >= 14 @@ -79,7 +84,7 @@ template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -91,7 +96,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -104,7 +109,7 @@ template <class T> struct some_alloc3 { typedef T value_type; - + some_alloc3() {} some_alloc3(const some_alloc3&); void deallocate(void*, unsigned) {} @@ -115,7 +120,6 @@ struct some_alloc3 int main() { -#if __has_feature(cxx_noexcept) { typedef std::unordered_set<MoveOnly> C; C c1, c2; @@ -193,6 +197,4 @@ int main() static_assert( noexcept(swap(c1, c2)), ""); } #endif - -#endif } diff --git a/test/std/containers/unord/unord.set/unord.set.swap/swap_non_member.pass.cpp b/test/std/containers/unord/unord.set/unord.set.swap/swap_non_member.pass.cpp index 7415e29777169..2755b52850274 100644 --- a/test/std/containers/unord/unord.set/unord.set.swap/swap_non_member.pass.cpp +++ b/test/std/containers/unord/unord.set/unord.set.swap/swap_non_member.pass.cpp @@ -386,7 +386,7 @@ int main() 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; diff --git a/test/std/depr/depr.c.headers/fenv_h.pass.cpp b/test/std/depr/depr.c.headers/fenv_h.pass.cpp index f2fcf4914cfd4..0da4c9d86b2d0 100644 --- a/test/std/depr/depr.c.headers/fenv_h.pass.cpp +++ b/test/std/depr/depr.c.headers/fenv_h.pass.cpp @@ -60,7 +60,7 @@ int main() { - fenv_t fenv = {0}; + fenv_t fenv = {}; fexcept_t fex = 0; static_assert((std::is_same<decltype(feclearexcept(0)), int>::value), ""); static_assert((std::is_same<decltype(fegetexceptflag(&fex, 0)), int>::value), ""); 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 637cf72287b8a..ff045a913fdb3 100644 --- a/test/std/depr/depr.c.headers/inttypes_h.pass.cpp +++ b/test/std/depr/depr.c.headers/inttypes_h.pass.cpp @@ -917,7 +917,7 @@ int main() uintmax_t i4 = 0; } { - imaxdiv_t i1 = {0}; + imaxdiv_t 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/math_h.pass.cpp b/test/std/depr/depr.c.headers/math_h.pass.cpp index ed12fcf73a8cf..7e1b2d110642e 100644 --- a/test/std/depr/depr.c.headers/math_h.pass.cpp +++ b/test/std/depr/depr.c.headers/math_h.pass.cpp @@ -9,9 +9,6 @@ // <math.h> -// NOTE: isinf and isnan are tested separately because they are expected to fail -// on linux. We don't want their expected failure to hide other failures in this file. - #include <math.h> #include <type_traits> #include <cassert> @@ -631,6 +628,29 @@ void test_isgreaterequal() assert(isgreaterequal(-1.0, 0.F) == false); } +void test_isinf() +{ +#ifdef isinf +#error isinf defined +#endif + static_assert((std::is_same<decltype(isinf((float)0)), bool>::value), ""); + + typedef decltype(isinf((double)0)) DoubleRetType; +#ifndef __linux__ + static_assert((std::is_same<DoubleRetType, bool>::value), ""); +#else + // GLIBC < 2.26 defines 'isinf(double)' with a return type of 'int' in + // all C++ dialects. The test should tolerate this. + // See: https://sourceware.org/bugzilla/show_bug.cgi?id=19439 + static_assert((std::is_same<DoubleRetType, bool>::value + || std::is_same<DoubleRetType, int>::value), ""); +#endif + + static_assert((std::is_same<decltype(isinf(0)), bool>::value), ""); + static_assert((std::is_same<decltype(isinf((long double)0)), bool>::value), ""); + assert(isinf(-1.0) == false); +} + void test_isless() { #ifdef isless @@ -688,6 +708,29 @@ void test_islessgreater() assert(islessgreater(-1.0, 0.F) == true); } +void test_isnan() +{ +#ifdef isnan +#error isnan defined +#endif + static_assert((std::is_same<decltype(isnan((float)0)), bool>::value), ""); + + typedef decltype(isnan((double)0)) DoubleRetType; +#ifndef __linux__ + static_assert((std::is_same<DoubleRetType, bool>::value), ""); +#else + // GLIBC < 2.26 defines 'isnan(double)' with a return type of 'int' in + // all C++ dialects. The test should tolerate this. + // See: https://sourceware.org/bugzilla/show_bug.cgi?id=19439 + static_assert((std::is_same<DoubleRetType, bool>::value + || std::is_same<DoubleRetType, int>::value), ""); +#endif + + static_assert((std::is_same<decltype(isnan(0)), bool>::value), ""); + static_assert((std::is_same<decltype(isnan((long double)0)), bool>::value), ""); + assert(isnan(-1.0) == false); +} + void test_isunordered() { #ifdef isunordered @@ -1443,9 +1486,11 @@ int main() test_isnormal(); test_isgreater(); test_isgreaterequal(); + test_isinf(); test_isless(); test_islessequal(); test_islessgreater(); + test_isnan(); test_isunordered(); test_acosh(); test_asinh(); diff --git a/test/std/depr/depr.c.headers/math_h_isinf.pass.cpp b/test/std/depr/depr.c.headers/math_h_isinf.pass.cpp deleted file mode 100644 index cc7eaac7de62b..0000000000000 --- a/test/std/depr/depr.c.headers/math_h_isinf.pass.cpp +++ /dev/null @@ -1,30 +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. -// -//===----------------------------------------------------------------------===// - -// <math.h> - -// isinf - -// XFAIL: linux - -#include <math.h> -#include <type_traits> -#include <cassert> - -int main() -{ -#ifdef isinf -#error isinf defined -#endif - static_assert((std::is_same<decltype(isinf((float)0)), bool>::value), ""); - static_assert((std::is_same<decltype(isinf((double)0)), bool>::value), ""); - static_assert((std::is_same<decltype(isinf(0)), bool>::value), ""); - static_assert((std::is_same<decltype(isinf((long double)0)), bool>::value), ""); - assert(isinf(-1.0) == false); -} diff --git a/test/std/depr/depr.c.headers/math_h_isnan.pass.cpp b/test/std/depr/depr.c.headers/math_h_isnan.pass.cpp deleted file mode 100644 index 118f96bdd4347..0000000000000 --- a/test/std/depr/depr.c.headers/math_h_isnan.pass.cpp +++ /dev/null @@ -1,30 +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. -// -//===----------------------------------------------------------------------===// - -// <math.h> - -// isnan - -// XFAIL: linux - -#include <math.h> -#include <type_traits> -#include <cassert> - -int main() -{ -#ifdef isnan -#error isnan defined -#endif - static_assert((std::is_same<decltype(isnan((float)0)), bool>::value), ""); - static_assert((std::is_same<decltype(isnan((double)0)), bool>::value), ""); - static_assert((std::is_same<decltype(isnan(0)), bool>::value), ""); - static_assert((std::is_same<decltype(isnan((long double)0)), bool>::value), ""); - assert(isnan(-1.0) == false); -} diff --git a/test/std/depr/depr.c.headers/setjmp_h.pass.cpp b/test/std/depr/depr.c.headers/setjmp_h.pass.cpp index 9bc35b747493c..9663d8892ac50 100644 --- a/test/std/depr/depr.c.headers/setjmp_h.pass.cpp +++ b/test/std/depr/depr.c.headers/setjmp_h.pass.cpp @@ -19,6 +19,7 @@ int main() { jmp_buf jb; + ((void)jb); // Prevent unused warning static_assert((std::is_same<decltype(longjmp(jb, 0)), void>::value), "std::is_same<decltype(longjmp(jb, 0)), void>::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 f7d12b1ad551c..e3c38801e4a87 100644 --- a/test/std/depr/depr.c.headers/stdarg_h.pass.cpp +++ b/test/std/depr/depr.c.headers/stdarg_h.pass.cpp @@ -11,11 +11,13 @@ #include <stdarg.h> +#include "test_macros.h" + #ifndef va_arg #error va_arg not defined #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 # ifndef va_copy # error va_copy is not defined when c++ >= 11 # endif diff --git a/test/std/depr/depr.c.headers/stdint_h.pass.cpp b/test/std/depr/depr.c.headers/stdint_h.pass.cpp index 92bb04e558bb5..3d49111fd82b9 100644 --- a/test/std/depr/depr.c.headers/stdint_h.pass.cpp +++ b/test/std/depr/depr.c.headers/stdint_h.pass.cpp @@ -171,8 +171,8 @@ int main() // INTN_MIN static_assert(INT8_MIN == -128, "INT8_MIN == -128"); static_assert(INT16_MIN == -32768, "INT16_MIN == -32768"); - static_assert(INT32_MIN == -2147483648U, "INT32_MIN == -2147483648"); - static_assert(INT64_MIN == -9223372036854775808ULL, "INT64_MIN == -9223372036854775808LL"); + static_assert(INT32_MIN == -2147483647 - 1, "INT32_MIN == -2147483648"); + static_assert(INT64_MIN == -9223372036854775807LL - 1, "INT64_MIN == -9223372036854775808LL"); // INTN_MAX static_assert(INT8_MAX == 127, "INT8_MAX == 127"); @@ -189,8 +189,8 @@ int main() // INT_FASTN_MIN static_assert(INT_FAST8_MIN <= -128, "INT_FAST8_MIN <= -128"); static_assert(INT_FAST16_MIN <= -32768, "INT_FAST16_MIN <= -32768"); - static_assert(INT_FAST32_MIN <= -2147483648U, "INT_FAST32_MIN <= -2147483648"); - static_assert(INT_FAST64_MIN <= -9223372036854775808ULL, "INT_FAST64_MIN <= -9223372036854775808LL"); + static_assert(INT_FAST32_MIN <= -2147483647 - 1, "INT_FAST32_MIN <= -2147483648"); + static_assert(INT_FAST64_MIN <= -9223372036854775807LL - 1, "INT_FAST64_MIN <= -9223372036854775808LL"); // INT_FASTN_MAX static_assert(INT_FAST8_MAX >= 127, "INT_FAST8_MAX >= 127"); 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 3c5dd0ebf0e0d..85f9d2986284f 100644 --- a/test/std/depr/depr.c.headers/stdio_h.pass.cpp +++ b/test/std/depr/depr.c.headers/stdio_h.pass.cpp @@ -99,17 +99,25 @@ #include <cstdarg> +#if defined(__GNUC__) #pragma GCC diagnostic ignored "-Wformat-zero-length" #pragma GCC diagnostic ignored "-Wdeprecated-declarations" // for tmpnam +#endif int main() { FILE* fp = 0; - fpos_t fpos = {0}; - size_t s = 0; ((void)s); + fpos_t fpos = {}; + size_t s = 0; char* cp = 0; char arr[] = {'a', 'b'}; va_list va; + ((void)fp); // Prevent unused warning + ((void)fpos); // Prevent unused warning + ((void)s); // Prevent unused warning + ((void)cp); // Prevent unused warning + ((void)arr); // Prevent unused warning + ((void)va); // Prevent unused warning static_assert((std::is_same<decltype(remove("")), int>::value), ""); static_assert((std::is_same<decltype(rename("","")), int>::value), ""); static_assert((std::is_same<decltype(tmpfile()), FILE*>::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 afc784f74b894..db0308b7ef82c 100644 --- a/test/std/depr/depr.c.headers/string_h.pass.cpp +++ b/test/std/depr/depr.c.headers/string_h.pass.cpp @@ -47,4 +47,15 @@ int main() 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), ""); + + // These tests fail on systems whose C library doesn't provide a correct overload + // set for strchr, strpbrk, strrchr, strstr, and memchr, unless the compiler is + // a suitably recent version of Clang. +#if !defined(__APPLE__) || defined(_LIBCPP_PREFERRED_OVERLOAD) + static_assert((std::is_same<decltype(strchr(cpc, 0)), const char*>::value), ""); + static_assert((std::is_same<decltype(strpbrk(cpc, cpc)), const char*>::value), ""); + static_assert((std::is_same<decltype(strrchr(cpc, 0)), const char*>::value), ""); + static_assert((std::is_same<decltype(strstr(cpc, cpc)), const char*>::value), ""); + static_assert((std::is_same<decltype(memchr(vpc, 0, s)), const void*>::value), ""); +#endif } 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 0d229af409bde..a2639383cda7a 100644 --- a/test/std/depr/depr.c.headers/time_h.pass.cpp +++ b/test/std/depr/depr.c.headers/time_h.pass.cpp @@ -25,7 +25,7 @@ int main() clock_t c = 0; ((void)c); size_t s = 0; time_t t = 0; - tm tmv = {0}; + tm tmv = {}; static_assert((std::is_same<decltype(clock()), clock_t>::value), ""); static_assert((std::is_same<decltype(difftime(t,t)), double>::value), ""); static_assert((std::is_same<decltype(mktime(&tmv)), time_t>::value), ""); 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 e561b3e5a724a..f2e42a3285885 100644 --- a/test/std/depr/depr.c.headers/wchar_h.pass.cpp +++ b/test/std/depr/depr.c.headers/wchar_h.pass.cpp @@ -9,8 +9,8 @@ // <wchar.h> - #include <wchar.h> +#include <stdarg.h> #include <type_traits> #ifndef NULL @@ -32,25 +32,25 @@ int main() { // mbstate_t comes from the underlying C library; it is defined (in C99) as: -// a complete object type other than an array type that can hold the conversion -// state information necessary to convert between sequences of multibyte +// a complete object type other than an array type that can hold the conversion +// state information necessary to convert between sequences of multibyte // characters and wide characters -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wmissing-braces" - mbstate_t mb = {0}; -#pragma clang diagnostic pop - + mbstate_t mb = {}; size_t s = 0; tm *tm = 0; wint_t w = 0; ::FILE* fp = 0; -#ifdef __APPLE__ - __darwin_va_list va; -#else - __builtin_va_list va; -#endif + ::va_list va; char* ns = 0; wchar_t* ws = 0; + ((void)mb); // Prevent unused warning + ((void)s); // Prevent unused warning + ((void)tm); // Prevent unused warning + ((void)w); // Prevent unused warning + ((void)fp); // Prevent unused warning + ((void)va); // Prevent unused warning + ((void)ns); // Prevent unused warning + ((void)ws); // Prevent unused warning static_assert((std::is_same<decltype(fwprintf(fp, L"")), int>::value), ""); static_assert((std::is_same<decltype(fwscanf(fp, L"")), int>::value), ""); static_assert((std::is_same<decltype(swprintf(ws, s, L"")), int>::value), ""); @@ -82,19 +82,14 @@ int main() static_assert((std::is_same<decltype(wcscoll(L"", L"")), int>::value), ""); static_assert((std::is_same<decltype(wcsncmp(L"", L"", s)), int>::value), ""); static_assert((std::is_same<decltype(wcsxfrm(ws, L"", s)), size_t>::value), ""); - // const wchar_t* wcschr((const wchar_t*)0, L' ') - See below static_assert((std::is_same<decltype(wcschr((wchar_t*)0, L' ')), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcscspn(L"", L"")), size_t>::value), ""); static_assert((std::is_same<decltype(wcslen(L"")), size_t>::value), ""); - // const wchar_t* wcspbrk((const wchar_t*)0, L"") - See below static_assert((std::is_same<decltype(wcspbrk((wchar_t*)0, L"")), wchar_t*>::value), ""); - // const wchar_t* wcsrchr((const wchar_t*)0, L' ') - See below static_assert((std::is_same<decltype(wcsrchr((wchar_t*)0, L' ')), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcsspn(L"", L"")), size_t>::value), ""); - // const wchar_t* wcsstr((const wchar_t*)0, L"") - See below static_assert((std::is_same<decltype(wcsstr((wchar_t*)0, L"")), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcstok(ws, L"", (wchar_t**)0)), wchar_t*>::value), ""); - // const wchar_t* wmemchr((const wchar_t*)0, L' ', s) - See below static_assert((std::is_same<decltype(wmemchr((wchar_t*)0, L' ', s)), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wmemcmp(L"", L"", s)), int>::value), ""); static_assert((std::is_same<decltype(wmemcpy(ws, L"", s)), wchar_t*>::value), ""); @@ -110,10 +105,10 @@ int main() static_assert((std::is_same<decltype(mbsrtowcs(ws, (const char**)0, s, &mb)), size_t>::value), ""); static_assert((std::is_same<decltype(wcsrtombs(ns, (const wchar_t**)0, s, &mb)), size_t>::value), ""); -// This test fails on systems whose C library doesn't provide a correct overload -// set for wcschr, wcspbrk, wcsrchr, wcsstr, and wmemchr. There's no way for -// libc++ to fix that on the C library's behalf. -#ifndef __APPLE__ + // These tests fail on systems whose C library doesn't provide a correct overload + // set for wcschr, wcspbrk, wcsrchr, wcsstr, and wmemchr, unless the compiler is + // a suitably recent version of Clang. +#if !defined(__APPLE__) || defined(_LIBCPP_PREFERRED_OVERLOAD) static_assert((std::is_same<decltype(wcschr((const wchar_t*)0, L' ')), const wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcspbrk((const wchar_t*)0, L"")), const wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcsrchr((const wchar_t*)0, L' ')), const wchar_t*>::value), ""); diff --git a/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/ccp.pass.cpp b/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/ccp.pass.cpp index 9911df7150780..078d8911d8a68 100644 --- a/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/ccp.pass.cpp +++ b/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/ccp.pass.cpp @@ -15,6 +15,7 @@ #include <strstream> #include <cassert> +#include <string> int main() { diff --git a/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/ccp_size.pass.cpp b/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/ccp_size.pass.cpp index a80095099401b..8b4ae722f2249 100644 --- a/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/ccp_size.pass.cpp +++ b/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/ccp_size.pass.cpp @@ -15,6 +15,7 @@ #include <strstream> #include <cassert> +#include <string> int main() { diff --git a/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/cp.pass.cpp b/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/cp.pass.cpp index edd6c1f6286cd..23068f5fd332a 100644 --- a/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/cp.pass.cpp +++ b/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/cp.pass.cpp @@ -15,6 +15,7 @@ #include <strstream> #include <cassert> +#include <string> int main() { diff --git a/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/cp_size.pass.cpp b/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/cp_size.pass.cpp index 5d01715ba1b70..ff797e0929473 100644 --- a/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/cp_size.pass.cpp +++ b/test/std/depr/depr.str.strstreams/depr.istrstream/depr.istrstream.cons/cp_size.pass.cpp @@ -15,6 +15,7 @@ #include <strstream> #include <cassert> +#include <string> int main() { diff --git a/test/std/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.cons/cp_size_mode.pass.cpp b/test/std/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.cons/cp_size_mode.pass.cpp index 1ad0bfa8e2695..b6519de8eddd3 100644 --- a/test/std/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.cons/cp_size_mode.pass.cpp +++ b/test/std/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.cons/cp_size_mode.pass.cpp @@ -15,6 +15,7 @@ #include <strstream> #include <cassert> +#include <string> int main() { diff --git a/test/std/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.cons/default.pass.cpp b/test/std/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.cons/default.pass.cpp index 5ea4988ffa6f5..29debf187c7e2 100644 --- a/test/std/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.cons/default.pass.cpp +++ b/test/std/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.cons/default.pass.cpp @@ -15,6 +15,7 @@ #include <strstream> #include <cassert> +#include <string> int main() { diff --git a/test/std/depr/depr.str.strstreams/depr.strstream/depr.strstream.cons/cp_size_mode.pass.cpp b/test/std/depr/depr.str.strstreams/depr.strstream/depr.strstream.cons/cp_size_mode.pass.cpp index 2a4c0ec5aa201..1dc03b8aa806c 100644 --- a/test/std/depr/depr.str.strstreams/depr.strstream/depr.strstream.cons/cp_size_mode.pass.cpp +++ b/test/std/depr/depr.str.strstreams/depr.strstream/depr.strstream.cons/cp_size_mode.pass.cpp @@ -15,6 +15,7 @@ #include <strstream> #include <cassert> +#include <string> int main() { diff --git a/test/std/depr/depr.str.strstreams/depr.strstream/depr.strstream.cons/default.pass.cpp b/test/std/depr/depr.str.strstreams/depr.strstream/depr.strstream.cons/default.pass.cpp index 2ec5e7f748e16..6298fcac30a92 100644 --- a/test/std/depr/depr.str.strstreams/depr.strstream/depr.strstream.cons/default.pass.cpp +++ b/test/std/depr/depr.str.strstreams/depr.strstream/depr.strstream.cons/default.pass.cpp @@ -15,6 +15,7 @@ #include <strstream> #include <cassert> +#include <string> int main() { diff --git a/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.cons/custom_alloc.pass.cpp b/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.cons/custom_alloc.pass.cpp index 12a1fb874c301..e466d50c64f6d 100644 --- a/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.cons/custom_alloc.pass.cpp +++ b/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.cons/custom_alloc.pass.cpp @@ -18,7 +18,7 @@ int called = 0; -void* my_alloc(std::size_t n) +void* my_alloc(std::size_t) { static char buf[10000]; ++called; diff --git a/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/overflow.pass.cpp b/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/overflow.pass.cpp new file mode 100644 index 0000000000000..dda19a9517fb1 --- /dev/null +++ b/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/overflow.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. +// +//===----------------------------------------------------------------------===// + +// <strstream> + +// class strstreambuf + +// int overflow(int c); + +#include <iostream> +#include <string> +#include <strstream> + +int main() { + std::ostrstream oss; + std::string s; + + for (int i = 0; i < 4096; ++i) + s.push_back((i % 16) + 'a'); + + oss << s << std::ends; + std::cout << oss.str(); + oss.freeze(false); + + return 0; +} diff --git a/test/std/depr/exception.unexpected/set.unexpected/get_unexpected.pass.cpp b/test/std/depr/exception.unexpected/set.unexpected/get_unexpected.pass.cpp index 8b0a0b979de0c..02f9a81aa6ddd 100644 --- a/test/std/depr/exception.unexpected/set.unexpected/get_unexpected.pass.cpp +++ b/test/std/depr/exception.unexpected/set.unexpected/get_unexpected.pass.cpp @@ -23,7 +23,7 @@ void f3() int main() { - + std::unexpected_handler old = std::get_unexpected(); // verify there is a previous unexpected handler assert(old); diff --git a/test/std/diagnostics/assertions/cassert.pass.cpp b/test/std/diagnostics/assertions/cassert.pass.cpp index bed7a394ee4a6..3f886e7b91fd1 100644 --- a/test/std/diagnostics/assertions/cassert.pass.cpp +++ b/test/std/diagnostics/assertions/cassert.pass.cpp @@ -15,10 +15,6 @@ #error assert not defined #endif -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - int main() { } diff --git a/test/std/diagnostics/errno/cerrno.pass.cpp b/test/std/diagnostics/errno/cerrno.pass.cpp index c6743fb79e7fd..72c9371d16c45 100644 --- a/test/std/diagnostics/errno/cerrno.pass.cpp +++ b/test/std/diagnostics/errno/cerrno.pass.cpp @@ -12,10 +12,6 @@ #include <cerrno> -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - #ifndef E2BIG #error E2BIG not defined #endif diff --git a/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.nonvirtuals/default_ctor.pass.cpp b/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.nonvirtuals/default_ctor.pass.cpp index 0573ef862efd7..f6a97ef92d849 100644 --- a/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.nonvirtuals/default_ctor.pass.cpp +++ b/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.nonvirtuals/default_ctor.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <system_error> // class error_category @@ -18,23 +19,17 @@ #include <string> #include <cassert> -#if _LIBCPP_STD_VER > 11 - class test1 : public std::error_category { public: constexpr test1() = default; // won't compile if error_category() is not constexpr virtual const char* name() const noexcept {return nullptr;} - virtual std::string message(int ev) const {return std::string();} + virtual std::string message(int) const {return std::string();} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 static_assert(std::is_nothrow_default_constructible<test1>::value, "error_category() must exist and be noexcept"); -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp b/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp index 972299936ddf0..65ecc49212122 100644 --- a/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp +++ b/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp @@ -16,10 +16,24 @@ #include <system_error> #include <cassert> #include <string> +#include <cerrno> + +#include "test_macros.h" + +void test_message_for_bad_value() { + errno = E2BIG; // something that message will never generate + const std::error_category& e_cat1 = std::generic_category(); + const std::string msg = e_cat1.message(-1); + LIBCPP_ASSERT(msg == "Unknown error -1"); + assert(errno == E2BIG); +} int main() { const std::error_category& e_cat1 = std::generic_category(); std::string m1 = e_cat1.name(); assert(m1 == "generic"); + { + test_message_for_bad_value(); + } } diff --git a/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp b/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp index b5cb18ad76531..d1a94883f925e 100644 --- a/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp +++ b/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp @@ -16,6 +16,17 @@ #include <system_error> #include <cassert> #include <string> +#include <cerrno> + +#include "test_macros.h" + +void test_message_for_bad_value() { + errno = E2BIG; // something that message will never generate + const std::error_category& e_cat1 = std::system_category(); + const std::string msg = e_cat1.message(-1); + LIBCPP_ASSERT(msg == "Unknown error -1"); + assert(errno == E2BIG); +} int main() { @@ -26,4 +37,7 @@ int main() e_cond = e_cat1.default_error_condition(5000); assert(e_cond.value() == 5000); assert(e_cond.category() == std::system_category()); + { + test_message_for_bad_value(); + } } diff --git a/test/std/diagnostics/syserr/syserr.hash/error_code.pass.cpp b/test/std/diagnostics/syserr/syserr.hash/error_code.pass.cpp index b812e364bbc59..c8b3d98103c4d 100644 --- a/test/std/diagnostics/syserr/syserr.hash/error_code.pass.cpp +++ b/test/std/diagnostics/syserr/syserr.hash/error_code.pass.cpp @@ -16,12 +16,12 @@ // size_t operator()(T val) const; // }; -// Not very portable - #include <system_error> #include <cassert> #include <type_traits> +#include "test_macros.h" + void test(int i) { @@ -31,7 +31,9 @@ test(int i) static_assert((std::is_same<H::result_type, std::size_t>::value), "" ); H h; T ec(i, std::system_category()); - assert(h(ec) == i); + const std::size_t result = h(ec); + LIBCPP_ASSERT(result == i); + ((void)result); // Prevent unused warning } int main() diff --git a/test/std/experimental/algorithms/alg.random.sample/sample.pass.cpp b/test/std/experimental/algorithms/alg.random.sample/sample.pass.cpp index 0f0784d6ee90e..1a9f9b099b201 100644 --- a/test/std/experimental/algorithms/alg.random.sample/sample.pass.cpp +++ b/test/std/experimental/algorithms/alg.random.sample/sample.pass.cpp @@ -64,12 +64,12 @@ void test() { end = std::experimental::sample(PopulationIterator(ia), PopulationIterator(ia + is), SampleIterator(oa), os, g); - assert(&*end - oa == std::min(os, is)); + assert(end.base() - 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(end.base() - oa == std::min(os, is)); assert(std::equal(oa, oa + os, oa2)); } @@ -85,7 +85,7 @@ void test_empty_population() { SampleIterator end = std::experimental::sample(PopulationIterator(ia), PopulationIterator(ia), SampleIterator(oa), os, g); - assert(&*end == oa); + assert(end.base() == oa); } template <template<class> class PopulationIteratorType, class PopulationItem, @@ -100,7 +100,7 @@ void test_empty_sample() { SampleIterator end = std::experimental::sample(PopulationIterator(ia), PopulationIterator(ia + is), SampleIterator(oa), 0, g); - assert(&*end == oa); + assert(end.base() == oa); } template <template<class> class PopulationIteratorType, class PopulationItem, @@ -119,8 +119,8 @@ void test_small_population() { 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)); + assert(end.base() - oa == std::min(os, is)); + assert(std::equal(oa, end.base(), oa1)); } int main() { diff --git a/test/std/experimental/algorithms/alg.search/search.pass.cpp b/test/std/experimental/algorithms/alg.search/search.pass.cpp index 60a44e4c26a2c..81d220ba1aed7 100644 --- a/test/std/experimental/algorithms/alg.search/search.pass.cpp +++ b/test/std/experimental/algorithms/alg.search/search.pass.cpp @@ -15,7 +15,7 @@ // ForwardIterator search(ForwardIterator first, ForwardIterator last, // const Searcher& searcher); // -// returns searcher.operator(first, last) +// returns searcher.operator(first, last).first // #include <experimental/algorithm> @@ -27,10 +27,11 @@ int searcher_called = 0; struct MySearcher { template <typename Iterator> - Iterator operator() ( Iterator b, Iterator /*e*/) const + std::pair<Iterator, Iterator> + operator() (Iterator b, Iterator e) const { ++searcher_called; - return b; + return std::make_pair(b, e); } }; diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/bad_symlink b/test/std/experimental/filesystem/Inputs/static_test_env/bad_symlink new file mode 120000 index 0000000000000..76646beed5ed3 --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/bad_symlink @@ -0,0 +1 @@ +dne
\ No newline at end of file diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/afile3 b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/afile3 new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/afile3 diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/dir3/file5 b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/dir3/file5 new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/dir3/file5 diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/file4 b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/file4 new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/file4 diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 new file mode 120000 index 0000000000000..3979139526219 --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 @@ -0,0 +1 @@ +dir3
\ No newline at end of file diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file1 b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file1 new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file1 diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file2 b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file2 new file mode 100644 index 0000000000000..44834e586734f --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/dir1/file2 @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
\ No newline at end of file diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/empty_file b/test/std/experimental/filesystem/Inputs/static_test_env/empty_file new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/empty_file diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/non_empty_file b/test/std/experimental/filesystem/Inputs/static_test_env/non_empty_file new file mode 100644 index 0000000000000..44834e586734f --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/non_empty_file @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
\ No newline at end of file diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_dir b/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_dir new file mode 120000 index 0000000000000..df490f837a85c --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_dir @@ -0,0 +1 @@ +dir1
\ No newline at end of file diff --git a/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_empty_file b/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_empty_file new file mode 120000 index 0000000000000..b79b689fc85ac --- /dev/null +++ b/test/std/experimental/filesystem/Inputs/static_test_env/symlink_to_empty_file @@ -0,0 +1 @@ +empty_file
\ No newline at end of file diff --git a/test/std/experimental/filesystem/class.directory_entry/directory_entry.cons.pass.cpp b/test/std/experimental/filesystem/class.directory_entry/directory_entry.cons.pass.cpp new file mode 100644 index 0000000000000..9a92f0698ba7c --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_entry/directory_entry.cons.pass.cpp @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class directory_entry + +// directory_entry() noexcept = default; +// directory_entry(const directory_entry&) = default; +// directory_entry(directory_entry&&) noexcept = default; +// explicit directory_entry(const path); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +namespace fs = std::experimental::filesystem; + +void test_default_ctor() +{ + using namespace fs; + // Default + { + static_assert(std::is_nothrow_default_constructible<directory_entry>::value, + "directory_entry must have a nothrow default constructor"); + directory_entry e; + assert(e.path() == path()); + } +} + + +void test_copy_ctor() +{ + using namespace fs; + // Copy + { + static_assert(std::is_copy_constructible<directory_entry>::value, + "directory_entry must be copy constructible"); + static_assert(!std::is_nothrow_copy_constructible<directory_entry>::value, + "directory_entry's copy constructor cannot be noexcept"); + const path p("foo/bar/baz"); + const directory_entry e(p); + assert(e.path() == p); + directory_entry e2(e); + assert(e.path() == p); + assert(e2.path() == p); + } + +} + +void test_move_ctor() +{ + using namespace fs; + // Move + { + static_assert(std::is_nothrow_move_constructible<directory_entry>::value, + "directory_entry must be nothrow move constructible"); + const path p("foo/bar/baz"); + directory_entry e(p); + assert(e.path() == p); + directory_entry e2(std::move(e)); + assert(e2.path() == p); + assert(e.path() != p); // Testing moved from state. + } +} + +void test_path_ctor() { + using namespace fs; + { + static_assert(std::is_constructible<directory_entry, const path&>::value, + "directory_entry must be constructible from path"); + static_assert(!std::is_nothrow_constructible<directory_entry, const path&>::value, + "directory_entry constructor should not be noexcept"); + static_assert(!std::is_convertible<path const&, directory_entry>::value, + "directory_entry constructor should be explicit"); + } + { + const path p("foo/bar/baz"); + const directory_entry e(p); + assert(p == e.path()); + } +} + +int main() { + test_default_ctor(); + test_copy_ctor(); + test_move_ctor(); + test_path_ctor(); +} diff --git a/test/std/experimental/filesystem/class.directory_entry/directory_entry.mods.pass.cpp b/test/std/experimental/filesystem/class.directory_entry/directory_entry.mods.pass.cpp new file mode 100644 index 0000000000000..97ecbefac42a9 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_entry/directory_entry.mods.pass.cpp @@ -0,0 +1,113 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class directory_entry + +// directory_entry& operator=(directory_entry const&) = default; +// directory_entry& operator=(directory_entry&&) noexcept = default; +// void assign(path const&); +// void replace_filename(path const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +namespace fs = std::experimental::filesystem; + +void test_copy_assign_operator() +{ + using namespace fs; + // Copy + { + static_assert(std::is_copy_assignable<directory_entry>::value, + "directory_entry must be copy assignable"); + static_assert(!std::is_nothrow_copy_assignable<directory_entry>::value, + "directory_entry's copy assignment cannot be noexcept"); + const path p("foo/bar/baz"); + const path p2("abc"); + const directory_entry e(p); + directory_entry e2; + assert(e.path() == p && e2.path() == path()); + e2 = e; + assert(e.path() == p && e2.path() == p); + directory_entry e3(p2); + e2 = e3; + assert(e2.path() == p2 && e3.path() == p2); + } +} + + +void test_move_assign_operator() +{ + using namespace fs; + // Copy + { + static_assert(std::is_nothrow_move_assignable<directory_entry>::value, + "directory_entry is noexcept move assignable"); + const path p("foo/bar/baz"); + const path p2("abc"); + directory_entry e(p); + directory_entry e2(p2); + assert(e.path() == p && e2.path() == p2); + e2 = std::move(e); + assert(e2.path() == p); + assert(e.path() != p); // testing moved from state + } +} + +void test_path_assign_method() +{ + using namespace fs; + const path p("foo/bar/baz"); + const path p2("abc"); + directory_entry e(p); + { + static_assert(std::is_same<decltype(e.assign(p)), void>::value, + "return type should be void"); + static_assert(noexcept(e.assign(p)) == false, "operation must not be noexcept"); + } + { + assert(e.path() == p); + e.assign(p2); + assert(e.path() == p2 && e.path() != p); + e.assign(p); + assert(e.path() == p && e.path() != p2); + } +} + +void test_replace_filename_method() +{ + using namespace fs; + const path p("/path/to/foo.exe"); + const path replace("bar.out"); + const path expect("/path/to/bar.out"); + directory_entry e(p); + { + static_assert(noexcept(e.replace_filename(replace)) == false, + "operation cannot be noexcept"); + static_assert(std::is_same<decltype(e.replace_filename(replace)), void>::value, + "operation must return void"); + } + { + assert(e.path() == p); + e.replace_filename(replace); + assert(e.path() == expect); + } +} + +int main() { + test_copy_assign_operator(); + test_move_assign_operator(); + test_path_assign_method(); + test_replace_filename_method(); +} diff --git a/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/comparisons.pass.cpp b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/comparisons.pass.cpp new file mode 100644 index 0000000000000..96e5093002293 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/comparisons.pass.cpp @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class directory_entry + +// bool operator==(directory_entry const&) const noexcept; +// bool operator!=(directory_entry const&) const noexcept; +// bool operator< (directory_entry const&) const noexcept; +// bool operator<=(directory_entry const&) const noexcept; +// bool operator> (directory_entry const&) const noexcept; +// bool operator>=(directory_entry const&) const noexcept; + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +namespace fs = std::experimental::filesystem; + +#define CHECK_OP(Op) \ + static_assert(std::is_same<decltype(ce. operator Op (ce)), bool>::value, ""); \ + static_assert(noexcept(ce.operator Op (ce)), "Operation must be noexcept" ) + +void test_comparison_signatures() { + using namespace fs; + path const p("foo/bar/baz"); + // Check that the operators are member functions with the correct signatures. + { + directory_entry const ce(p); + CHECK_OP(==); + CHECK_OP(!=); + CHECK_OP(< ); + CHECK_OP(<=); + CHECK_OP(> ); + CHECK_OP(>=); + } +} +#undef CHECK_OP + +// The actual semantics of the comparisons are testing via paths operators. +void test_comparisons_simple() { + using namespace fs; + typedef std::pair<path, path> TestType; + TestType TestCases[] = + { + {"", ""}, + {"", "a"}, + {"a", "a"}, + {"a", "b"}, + {"foo/bar/baz", "foo/bar/baz/"} + }; + auto TestFn = [](path const& LHS, const directory_entry& LHSE, + path const& RHS, const directory_entry& RHSE) { + assert((LHS == RHS) == (LHSE == RHSE)); + assert((LHS != RHS) == (LHSE != RHSE)); + assert((LHS < RHS) == (LHSE < RHSE)); + assert((LHS <= RHS) == (LHSE <= RHSE)); + assert((LHS > RHS) == (LHSE > RHSE)); + assert((LHS >= RHS) == (LHSE >= RHSE)); + }; + for (auto const& TC : TestCases) { + const directory_entry L(TC.first); + const directory_entry R(TC.second); + TestFn(TC.first, L, TC.second, R); + TestFn(TC.second, R, TC.first, L); + } +} + +int main() { + test_comparison_signatures(); + test_comparisons_simple(); +} diff --git a/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/path.pass.cpp b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/path.pass.cpp new file mode 100644 index 0000000000000..d228a3d926413 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/path.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class directory_entry + +// const path& path() const noexcept; +// operator const path&() const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +namespace fs = std::experimental::filesystem; + +void test_path_method() { + using namespace fs; + const path p("foo/bar/baz.exe"); + const path p2("abc"); + { + directory_entry nce; + const directory_entry e(""); + static_assert(std::is_same<decltype(e.path()), const path&>::value, ""); + static_assert(std::is_same<decltype(nce.path()), const path&>::value, ""); + static_assert(noexcept(e.path()) && noexcept(nce.path()), ""); + } + { + directory_entry e(p); + path const& pref = e.path(); + assert(pref == p); + assert(&pref == &e.path()); + e.assign(p2); + assert(pref == p2); + assert(&pref == &e.path()); + } +} + +void test_path_conversion() { + using namespace fs; + const path p("foo/bar/baz.exe"); + const path p2("abc"); + { + directory_entry nce; + const directory_entry e(""); + // Check conversions exist + static_assert(std::is_convertible<directory_entry&, path const&>::value, ""); + static_assert(std::is_convertible<directory_entry const&, path const&>::value, ""); + static_assert(std::is_convertible<directory_entry &&, path const&>::value, ""); + static_assert(std::is_convertible<directory_entry const&&, path const&>::value, ""); + // Not convertible to non-const + static_assert(!std::is_convertible<directory_entry&, path&>::value, ""); + static_assert(!std::is_convertible<directory_entry const&, path&>::value, ""); + static_assert(!std::is_convertible<directory_entry &&, path&>::value, ""); + static_assert(!std::is_convertible<directory_entry const&&, path&>::value, ""); + // conversions are noexcept + static_assert(noexcept(e.operator fs::path const&()) && + noexcept(e.operator fs::path const&()), ""); + } + // const + { + directory_entry const e(p); + path const& pref = e; + assert(&pref == &e.path()); + } + // non-const + { + directory_entry e(p); + path const& pref = e; + assert(&pref == &e.path()); + + e.assign(p2); + assert(pref == p2); + assert(&pref == &e.path()); + } +} + +int main() { + test_path_method(); + test_path_conversion(); +} diff --git a/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/status.pass.cpp b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/status.pass.cpp new file mode 100644 index 0000000000000..54c5172ebce46 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/status.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class directory_entry + +// file_status status() const; +// file_status status(error_code const&) const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "filesystem_test_helper.hpp" + +int main() +{ + using namespace fs; + { + const directory_entry e("foo"); + std::error_code ec; + static_assert(std::is_same<decltype(e.status()), file_status>::value, ""); + static_assert(std::is_same<decltype(e.status(ec)), file_status>::value, ""); + static_assert(noexcept(e.status()) == false, ""); + static_assert(noexcept(e.status(ec)) == true, ""); + } + auto TestFn = [](path const& p) { + const directory_entry e(p); + std::error_code pec, eec; + file_status ps = fs::status(p, pec); + file_status es = e.status(eec); + assert(ps.type() == es.type()); + assert(ps.permissions() == es.permissions()); + assert(pec == eec); + }; + { + TestFn(StaticEnv::File); + TestFn(StaticEnv::Dir); + TestFn(StaticEnv::SymlinkToFile); + TestFn(StaticEnv::DNE); + } +} diff --git a/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp new file mode 100644 index 0000000000000..3a99eb671b44e --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_entry/directory_entry.obs/symlink_status.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: c++98, c++03 + +// <experimental/filesystem> + +// class directory_entry + +// file_status symlink_status() const; +// file_status symlink_status(error_code&) const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "filesystem_test_helper.hpp" + +int main() { + using namespace fs; + { + const directory_entry e("foo"); + std::error_code ec; + static_assert(std::is_same<decltype(e.symlink_status()), file_status>::value, ""); + static_assert(std::is_same<decltype(e.symlink_status(ec)), file_status>::value, ""); + static_assert(noexcept(e.symlink_status()) == false, ""); + static_assert(noexcept(e.symlink_status(ec)) == true, ""); + } + auto TestFn = [](path const& p) { + const directory_entry e(p); + std::error_code pec, eec; + file_status ps = fs::symlink_status(p, pec); + file_status es = e.symlink_status(eec); + assert(ps.type() == es.type()); + assert(ps.permissions() == es.permissions()); + assert(pec == eec); + }; + { + TestFn(StaticEnv::File); + TestFn(StaticEnv::Dir); + TestFn(StaticEnv::SymlinkToFile); + TestFn(StaticEnv::DNE); + } +} diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy.pass.cpp new file mode 100644 index 0000000000000..5c4583391e74f --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator(directory_iterator const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_copy_construct_tests) + +TEST_CASE(test_constructor_signature) +{ + using D = directory_iterator; + static_assert(std::is_copy_constructible<D>::value, ""); +} + +TEST_CASE(test_copy_end_iterator) +{ + const directory_iterator endIt; + directory_iterator it(endIt); + TEST_CHECK(it == endIt); +} + +TEST_CASE(test_copy_valid_iterator) +{ + const path testDir = StaticEnv::Dir; + const directory_iterator endIt{}; + + const directory_iterator it(testDir); + TEST_REQUIRE(it != endIt); + const path entry = *it; + + const directory_iterator it2(it); + TEST_REQUIRE(it2 == it); + TEST_CHECK(*it2 == entry); + TEST_CHECK(*it == entry); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp new file mode 100644 index 0000000000000..0d5ebf3ebe964 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/copy_assign.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator& operator=(directory_iterator const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_copy_assign_tests) + +TEST_CASE(test_assignment_signature) +{ + using D = directory_iterator; + static_assert(std::is_copy_assignable<D>::value, ""); +} + +TEST_CASE(test_copy_to_end_iterator) +{ + const path testDir = StaticEnv::Dir; + + const directory_iterator from(testDir); + TEST_REQUIRE(from != directory_iterator{}); + const path entry = *from; + + directory_iterator to{}; + to = from; + TEST_REQUIRE(to == from); + TEST_CHECK(*to == entry); + TEST_CHECK(*from == entry); +} + + +TEST_CASE(test_copy_from_end_iterator) +{ + const path testDir = StaticEnv::Dir; + + const directory_iterator from{}; + + directory_iterator to(testDir); + TEST_REQUIRE(to != directory_iterator{}); + + to = from; + TEST_REQUIRE(to == from); + TEST_CHECK(to == directory_iterator{}); +} + +TEST_CASE(test_copy_valid_iterator) +{ + const path testDir = StaticEnv::Dir; + const directory_iterator endIt{}; + + directory_iterator it_obj(testDir); + const directory_iterator& it = it_obj; + TEST_REQUIRE(it != endIt); + ++it_obj; + TEST_REQUIRE(it != endIt); + const path entry = *it; + + directory_iterator it2(testDir); + TEST_REQUIRE(it2 != it); + const path entry2 = *it2; + TEST_CHECK(entry2 != entry); + + it2 = it; + TEST_REQUIRE(it2 == it); + TEST_CHECK(*it2 == entry); +} + +TEST_CASE(test_returns_reference_to_self) +{ + const directory_iterator it; + directory_iterator it2; + directory_iterator& ref = (it2 = it); + TEST_CHECK(&ref == &it2); +} + + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/ctor.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/ctor.pass.cpp new file mode 100644 index 0000000000000..a6becb1bafaa7 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/ctor.pass.cpp @@ -0,0 +1,246 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class directory_iterator + +// explicit directory_iterator(const path& p); +// directory_iterator(const path& p, directory_options options); +// directory_iterator(const path& p, error_code& ec) noexcept; +// directory_iterator(const path& p, directory_options options, error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_constructor_tests) + +TEST_CASE(test_constructor_signatures) +{ + using D = directory_iterator; + + // explicit directory_iterator(path const&); + static_assert(!std::is_convertible<path, D>::value, ""); + static_assert(std::is_constructible<D, path>::value, ""); + static_assert(!std::is_nothrow_constructible<D, path>::value, ""); + + // directory_iterator(path const&, error_code&) noexcept + static_assert(std::is_nothrow_constructible<D, path, std::error_code&>::value, ""); + + // directory_iterator(path const&, directory_options); + static_assert(std::is_constructible<D, path, directory_options>::value, ""); + static_assert(!std::is_nothrow_constructible<D, path, directory_options>::value, ""); + + // directory_iterator(path const&, directory_options, error_code&) noexcept + static_assert(std::is_nothrow_constructible<D, path, directory_options, std::error_code&>::value, ""); +} + +TEST_CASE(test_construction_from_bad_path) +{ + std::error_code ec; + directory_options opts = directory_options::none; + const directory_iterator endIt; + + const path testPaths[] = { StaticEnv::DNE, StaticEnv::BadSymlink }; + for (path const& testPath : testPaths) + { + { + directory_iterator it(testPath, ec); + TEST_CHECK(ec); + TEST_CHECK(it == endIt); + } + { + directory_iterator it(testPath, opts, ec); + TEST_CHECK(ec); + TEST_CHECK(it == endIt); + } + { + TEST_CHECK_THROW(filesystem_error, directory_iterator(testPath)); + TEST_CHECK_THROW(filesystem_error, directory_iterator(testPath, opts)); + } + } +} + +TEST_CASE(access_denied_test_case) +{ + using namespace std::experimental::filesystem; + scoped_test_env env; + path const testDir = env.make_env_path("dir1"); + path const testFile = testDir / "testFile"; + env.create_dir(testDir); + env.create_file(testFile, 42); + + // Test that we can iterator over the directory before changing the perms + directory_iterator it(testDir); + TEST_REQUIRE(it != directory_iterator{}); + + // Change the permissions so we can no longer iterate + permissions(testDir, perms::none); + + // Check that the construction fails when skip_permissions_denied is + // not given. + { + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == directory_iterator{}); + } + // Check that construction does not report an error when + // 'skip_permissions_denied' is given. + { + std::error_code ec; + directory_iterator it(testDir, directory_options::skip_permission_denied, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it == directory_iterator{}); + } +} + + +TEST_CASE(access_denied_to_file_test_case) +{ + using namespace std::experimental::filesystem; + scoped_test_env env; + path const testFile = env.make_env_path("file1"); + env.create_file(testFile, 42); + + // Change the permissions so we can no longer iterate + permissions(testFile, perms::none); + + // Check that the construction fails when skip_permissions_denied is + // not given. + { + std::error_code ec; + directory_iterator it(testFile, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == directory_iterator{}); + } + // Check that construction still fails when 'skip_permissions_denied' is given + // because we tried to open a file and not a directory. + { + std::error_code ec; + directory_iterator it(testFile, directory_options::skip_permission_denied, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == directory_iterator{}); + } +} + +TEST_CASE(test_open_on_empty_directory_equals_end) +{ + scoped_test_env env; + const path testDir = env.make_env_path("dir1"); + env.create_dir(testDir); + + const directory_iterator endIt; + { + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_CHECK(!ec); + TEST_CHECK(it == endIt); + } + { + directory_iterator it(testDir); + TEST_CHECK(it == endIt); + } +} + +TEST_CASE(test_open_on_directory_succeeds) +{ + const path testDir = StaticEnv::Dir; + std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList), + std::end( StaticEnv::DirIterationList)); + const directory_iterator endIt{}; + + { + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it != endIt); + TEST_CHECK(dir_contents.count(*it)); + } + { + directory_iterator it(testDir); + TEST_CHECK(it != endIt); + TEST_CHECK(dir_contents.count(*it)); + } +} + +TEST_CASE(test_open_on_file_fails) +{ + const path testFile = StaticEnv::File; + const directory_iterator endIt{}; + { + std::error_code ec; + directory_iterator it(testFile, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == endIt); + } + { + TEST_CHECK_THROW(filesystem_error, directory_iterator(testFile)); + } +} + +TEST_CASE(test_open_on_empty_string) +{ + const path testPath = ""; + const directory_iterator endIt{}; + + std::error_code ec; + directory_iterator it(testPath, ec); + TEST_CHECK(ec); + TEST_CHECK(it == endIt); +} + +TEST_CASE(test_open_on_dot_dir) +{ + const path testPath = "."; + + std::error_code ec; + directory_iterator it(testPath, ec); + TEST_CHECK(!ec); +} + +TEST_CASE(test_open_on_symlink) +{ + const path symlinkToDir = StaticEnv::SymlinkToDir; + std::set<path> dir_contents; + for (path const& p : StaticEnv::DirIterationList) { + dir_contents.insert(p.filename()); + } + const directory_iterator endIt{}; + + { + std::error_code ec; + directory_iterator it(symlinkToDir, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it != endIt); + path const& entry = *it; + TEST_CHECK(dir_contents.count(entry.filename())); + } + { + std::error_code ec; + directory_iterator it(symlinkToDir, + directory_options::follow_directory_symlink, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it != endIt); + path const& entry = *it; + TEST_CHECK(dir_contents.count(entry.filename())); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/default_ctor.pass.cpp new file mode 100644 index 0000000000000..94ace185a6aa8 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/default_ctor.pass.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 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator::directory_iterator() noexcept + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +int main() { + { + static_assert(std::is_nothrow_default_constructible<fs::directory_iterator>::value, ""); + } + { + fs::directory_iterator d1; + const fs::directory_iterator d2; + assert(d1 == d2); + } +} diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/increment.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/increment.pass.cpp new file mode 100644 index 0000000000000..589b4eca7efa2 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/increment.pass.cpp @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator& operator++(); +// directory_iterator& increment(error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" +#include <iostream> + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_increment_tests) + +TEST_CASE(test_increment_signatures) +{ + using D = directory_iterator; + directory_iterator d; ((void)d); + std::error_code ec; ((void)ec); + + ASSERT_SAME_TYPE(decltype(++d), directory_iterator&); + ASSERT_NOT_NOEXCEPT(++d); + + ASSERT_SAME_TYPE(decltype(d.increment(ec)), directory_iterator&); + ASSERT_NOEXCEPT(d.increment(ec)); +} + +TEST_CASE(test_prefix_increment) +{ + const path testDir = StaticEnv::Dir; + const std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList), + std::end( StaticEnv::DirIterationList)); + const directory_iterator endIt{}; + + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + directory_iterator& it_ref = ++it; + TEST_CHECK(&it_ref == &it); + } + + TEST_CHECK(it == endIt); +} + +TEST_CASE(test_postfix_increment) +{ + const path testDir = StaticEnv::Dir; + const std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList), + std::end( StaticEnv::DirIterationList)); + const directory_iterator endIt{}; + + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + const path entry2 = *it++; + TEST_CHECK(entry2 == entry); + } + + TEST_CHECK(it == endIt); +} + + +TEST_CASE(test_increment_method) +{ + const path testDir = StaticEnv::Dir; + const std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList), + std::end( StaticEnv::DirIterationList)); + const directory_iterator endIt{}; + + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + directory_iterator& it_ref = it.increment(ec); + TEST_REQUIRE(!ec); + TEST_CHECK(&it_ref == &it); + } + + TEST_CHECK(it == endIt); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move.pass.cpp new file mode 100644 index 0000000000000..f6c94e18eb0e8 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator(directory_iterator&&) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_move_construct_tests) + +TEST_CASE(test_constructor_signature) +{ + using D = directory_iterator; + static_assert(std::is_nothrow_move_constructible<D>::value, ""); +} + +TEST_CASE(test_move_end_iterator) +{ + const directory_iterator endIt; + directory_iterator endIt2{}; + + directory_iterator it(std::move(endIt2)); + TEST_CHECK(it == endIt); + TEST_CHECK(endIt2 == endIt); +} + +TEST_CASE(test_move_valid_iterator) +{ + const path testDir = StaticEnv::Dir; + const directory_iterator endIt{}; + + directory_iterator it(testDir); + TEST_REQUIRE(it != endIt); + const path entry = *it; + + const directory_iterator it2(std::move(it)); + TEST_CHECK(*it2 == entry); + + TEST_CHECK(it == it2 || it == endIt); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move_assign.pass.cpp new file mode 100644 index 0000000000000..445f05a3c3e1e --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/move_assign.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 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator& operator=(directory_iterator const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +// The filesystem specification explicitly allows for self-move on +// the directory iterators. Turn off this warning so we can test it. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wself-move" +#endif + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_move_assign_tests) + +TEST_CASE(test_assignment_signature) +{ + using D = directory_iterator; + static_assert(std::is_nothrow_move_assignable<D>::value, ""); +} + +TEST_CASE(test_move_to_end_iterator) +{ + const path testDir = StaticEnv::Dir; + + directory_iterator from(testDir); + TEST_REQUIRE(from != directory_iterator{}); + const path entry = *from; + + directory_iterator to{}; + to = std::move(from); + TEST_REQUIRE(to != directory_iterator{}); + TEST_CHECK(*to == entry); +} + + +TEST_CASE(test_move_from_end_iterator) +{ + const path testDir = StaticEnv::Dir; + + directory_iterator from{}; + + directory_iterator to(testDir); + TEST_REQUIRE(to != from); + + to = std::move(from); + TEST_REQUIRE(to == directory_iterator{}); + TEST_REQUIRE(from == directory_iterator{}); +} + +TEST_CASE(test_move_valid_iterator) +{ + const path testDir = StaticEnv::Dir; + const directory_iterator endIt{}; + + directory_iterator it(testDir); + TEST_REQUIRE(it != endIt); + ++it; + TEST_REQUIRE(it != endIt); + const path entry = *it; + + directory_iterator it2(testDir); + TEST_REQUIRE(it2 != it); + const path entry2 = *it2; + TEST_CHECK(entry2 != entry); + + it2 = std::move(it); + TEST_REQUIRE(it2 != directory_iterator{}); + TEST_CHECK(*it2 == entry); +} + +TEST_CASE(test_returns_reference_to_self) +{ + directory_iterator it; + directory_iterator it2; + directory_iterator& ref = (it2 = it); + TEST_CHECK(&ref == &it2); +} + + +TEST_CASE(test_self_move) +{ + // Create two non-equal iterators that have exactly the same state. + directory_iterator it(StaticEnv::Dir); + directory_iterator it2(StaticEnv::Dir); + ++it; ++it2; + TEST_CHECK(it != it2); + TEST_CHECK(*it2 == *it); + + it = std::move(it); + TEST_CHECK(*it2 == *it); +} + + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp new file mode 100644 index 0000000000000..f93a184521895 --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.nonmembers/begin_end.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class directory_iterator + +// directory_iterator begin(directory_iterator iter) noexcept; +// directory_iterator end(directory_iterator iter) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" +#include <iostream> + +using namespace std::experimental::filesystem; + +TEST_SUITE(directory_iterator_begin_end_tests) + +TEST_CASE(test_function_signatures) +{ + using D = directory_iterator; + directory_iterator d; ((void)d); + + ASSERT_SAME_TYPE(decltype(begin(d)), directory_iterator); + ASSERT_NOEXCEPT(begin(std::move(d))); + + ASSERT_SAME_TYPE(decltype(end(d)), directory_iterator); + ASSERT_NOEXCEPT(end(std::move(d))); +} + +TEST_CASE(test_ranged_for_loop) +{ + const path testDir = StaticEnv::Dir; + std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList), + std::end( StaticEnv::DirIterationList)); + + std::error_code ec; + directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + for (auto& elem : it) { + TEST_CHECK(dir_contents.erase(elem) == 1); + } + TEST_CHECK(dir_contents.empty()); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.directory_iterator/types.pass.cpp b/test/std/experimental/filesystem/class.directory_iterator/types.pass.cpp new file mode 100644 index 0000000000000..dad278f43d79d --- /dev/null +++ b/test/std/experimental/filesystem/class.directory_iterator/types.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 + +// <experimental/filesystem> + +// class directory_iterator + +// typedef ... value_type; +// typedef ... difference_type; +// typedef ... pointer; +// typedef ... reference; +// typedef ... iterator_category + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + using D = directory_iterator; + ASSERT_SAME_TYPE(D::value_type, directory_entry); + ASSERT_SAME_TYPE(D::difference_type, std::ptrdiff_t); + ASSERT_SAME_TYPE(D::pointer, const directory_entry*); + ASSERT_SAME_TYPE(D::reference, const directory_entry&); + ASSERT_SAME_TYPE(D::iterator_category, std::input_iterator_tag); +} diff --git a/test/std/experimental/filesystem/class.file_status/file_status.cons.pass.cpp b/test/std/experimental/filesystem/class.file_status/file_status.cons.pass.cpp new file mode 100644 index 0000000000000..585b0bb1dd5ee --- /dev/null +++ b/test/std/experimental/filesystem/class.file_status/file_status.cons.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class file_status + +// explicit file_status() noexcept; +// explicit file_status(file_type, perms prms = perms::unknown) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_convertible.hpp" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + // Default ctor + { + static_assert(std::is_nothrow_default_constructible<file_status>::value, + "The default constructor must be noexcept"); + static_assert(!test_convertible<file_status>(), + "The default constructor must be explicit"); + const file_status f; + assert(f.type() == file_type::none); + assert(f.permissions() == perms::unknown); + } + + // Unary ctor + { + static_assert(std::is_nothrow_constructible<file_status, file_type>::value, + "This constructor must be noexcept"); + static_assert(!test_convertible<file_status, file_type>(), + "This constructor must be explicit"); + + const file_status f(file_type::not_found); + assert(f.type() == file_type::not_found); + assert(f.permissions() == perms::unknown); + } + // Binary ctor + { + static_assert(std::is_nothrow_constructible<file_status, file_type, perms>::value, + "This constructor must be noexcept"); + static_assert(!test_convertible<file_status, file_type, perms>(), + "This constructor must b explicit"); + const file_status f(file_type::regular, perms::owner_read); + assert(f.type() == file_type::regular); + assert(f.permissions() == perms::owner_read); + } +} diff --git a/test/std/experimental/filesystem/class.file_status/file_status.mods.pass.cpp b/test/std/experimental/filesystem/class.file_status/file_status.mods.pass.cpp new file mode 100644 index 0000000000000..8681b2dc50d6f --- /dev/null +++ b/test/std/experimental/filesystem/class.file_status/file_status.mods.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: c++98, c++03 + +// <experimental/filesystem> + +// class file_status + +// void type(file_type) noexcept; +// void permissions(perms) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + + file_status st; + + // type test + { + static_assert(noexcept(st.type(file_type::regular)), + "operation must be noexcept"); + static_assert(std::is_same<decltype(st.type(file_type::regular)), void>::value, + "operation must return void"); + assert(st.type() != file_type::regular); + st.type(file_type::regular); + assert(st.type() == file_type::regular); + } + // permissions test + { + static_assert(noexcept(st.permissions(perms::owner_read)), + "operation must be noexcept"); + static_assert(std::is_same<decltype(st.permissions(perms::owner_read)), void>::value, + "operation must return void"); + assert(st.permissions() != perms::owner_read); + st.permissions(perms::owner_read); + assert(st.permissions() == perms::owner_read); + } +} diff --git a/test/std/experimental/filesystem/class.file_status/file_status.obs.pass.cpp b/test/std/experimental/filesystem/class.file_status/file_status.obs.pass.cpp new file mode 100644 index 0000000000000..4113dee453dc6 --- /dev/null +++ b/test/std/experimental/filesystem/class.file_status/file_status.obs.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class file_status + +// file_type type() const noexcept; +// perms permissions(p) const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + + const file_status st(file_type::regular, perms::owner_read); + + // type test + { + static_assert(noexcept(st.type()), + "operation must be noexcept"); + static_assert(std::is_same<decltype(st.type()), file_type>::value, + "operation must return file_type"); + assert(st.type() == file_type::regular); + } + // permissions test + { + static_assert(noexcept(st.permissions()), + "operation must be noexcept"); + static_assert(std::is_same<decltype(st.permissions()), perms>::value, + "operation must return perms"); + assert(st.permissions() == perms::owner_read); + } +} diff --git a/test/std/experimental/filesystem/class.filesystem_error/filesystem_error.members.pass.cpp b/test/std/experimental/filesystem/class.filesystem_error/filesystem_error.members.pass.cpp new file mode 100644 index 0000000000000..68b67ed72803b --- /dev/null +++ b/test/std/experimental/filesystem/class.filesystem_error/filesystem_error.members.pass.cpp @@ -0,0 +1,103 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class filesystem_error + +// filesystem_error(const string& what_arg, error_code ec); +// filesystem_error(const string& what_arg, const path& p1, error_code ec); +// filesystem_error(const string& what_arg, const path& p1, const path& p2, error_code ec); +// const std::error_code& code() const; +// const char* what() const noexcept; +// const path& path1() const noexcept; +// const path& path2() const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +void test_constructors() { + using namespace fs; + + // The string returned by "filesystem_error::what() must contain runtime_error::what() + const std::string what_arg = "Hello World"; + const std::string what_contains = std::runtime_error(what_arg).what(); + assert(what_contains.find(what_arg) != std::string::npos); + auto CheckWhat = [what_contains](filesystem_error const& e) { + std::string s = e.what(); + assert(s.find(what_contains) != std::string::npos); + }; + + std::error_code ec = std::make_error_code(std::errc::file_exists); + const path p1("foo"); + const path p2("bar"); + + // filesystem_error(const string& what_arg, error_code ec); + { + ASSERT_NOT_NOEXCEPT(filesystem_error(what_arg, ec)); + filesystem_error e(what_arg, ec); + CheckWhat(e); + assert(e.code() == ec); + assert(e.path1().empty() && e.path2().empty()); + } + // filesystem_error(const string& what_arg, const path&, error_code ec); + { + ASSERT_NOT_NOEXCEPT(filesystem_error(what_arg, p1, ec)); + filesystem_error e(what_arg, p1, ec); + CheckWhat(e); + assert(e.code() == ec); + assert(e.path1() == p1); + assert(e.path2().empty()); + } + // filesystem_error(const string& what_arg, const path&, const path&, error_code ec); + { + ASSERT_NOT_NOEXCEPT(filesystem_error(what_arg, p1, p2, ec)); + filesystem_error e(what_arg, p1, p2, ec); + CheckWhat(e); + assert(e.code() == ec); + assert(e.path1() == p1); + assert(e.path2() == p2); + } +} + +void test_signatures() +{ + using namespace fs; + const path p; + std::error_code ec; + const filesystem_error e("lala", ec); + // const path& path1() const noexcept; + { + ASSERT_SAME_TYPE(path const&, decltype(e.path1())); + ASSERT_NOEXCEPT(e.path1()); + } + // const path& path2() const noexcept + { + ASSERT_SAME_TYPE(path const&, decltype(e.path2())); + ASSERT_NOEXCEPT(e.path2()); + } + // const char* what() const noexcept + { + ASSERT_SAME_TYPE(const char*, decltype(e.what())); + ASSERT_NOEXCEPT(e.what()); + } +} + +int main() { + static_assert(std::is_base_of<std::system_error, fs::filesystem_error>::value, ""); + test_constructors(); + test_signatures(); +} diff --git a/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp b/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp new file mode 100644 index 0000000000000..12330ebb5ca8c --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class path + +// template <class Source> +// path(const Source& source); +// template <class InputIterator> +// path(InputIterator first, InputIterator last); + + +#include <experimental/filesystem> +#include <iterator> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + + +template <class It> +std::reverse_iterator<It> mkRev(It it) { + return std::reverse_iterator<It>(it); +} + +void checkIteratorConcepts() { + using namespace fs; + using It = path::iterator; + using Traits = std::iterator_traits<It>; + ASSERT_SAME_TYPE(Traits::iterator_category, std::bidirectional_iterator_tag); + ASSERT_SAME_TYPE(Traits::value_type, path); + ASSERT_SAME_TYPE(Traits::pointer, path const*); + ASSERT_SAME_TYPE(Traits::reference, path const&); + { + It it; + ASSERT_SAME_TYPE(It&, decltype(++it)); + ASSERT_SAME_TYPE(It, decltype(it++)); + ASSERT_SAME_TYPE(It&, decltype(--it)); + ASSERT_SAME_TYPE(It, decltype(it--)); + ASSERT_SAME_TYPE(Traits::reference, decltype(*it)); + ASSERT_SAME_TYPE(Traits::pointer, decltype(it.operator->())); + ASSERT_SAME_TYPE(std::string const&, decltype(it->native())); + ASSERT_SAME_TYPE(bool, decltype(it == it)); + ASSERT_SAME_TYPE(bool, decltype(it != it)); + } + { + path const p; + ASSERT_SAME_TYPE(It, decltype(p.begin())); + ASSERT_SAME_TYPE(It, decltype(p.end())); + assert(p.begin() == p.end()); + } +} + +void checkBeginEndBasic() { + using namespace fs; + using It = path::iterator; + { + path const p; + ASSERT_SAME_TYPE(It, decltype(p.begin())); + ASSERT_SAME_TYPE(It, decltype(p.end())); + assert(p.begin() == p.end()); + } + { + path const p("foo"); + It default_constructed; + default_constructed = p.begin(); + assert(default_constructed == p.begin()); + assert(default_constructed != p.end()); + default_constructed = p.end(); + assert(default_constructed == p.end()); + assert(default_constructed != p.begin()); + } + { + path p("//root_name//first_dir////second_dir"); + const path expect[] = {"//root_name", "/", "first_dir", "second_dir"}; + assert(checkCollectionsEqual(p.begin(), p.end(), std::begin(expect), std::end(expect))); + assert(checkCollectionsEqualBackwards(p.begin(), p.end(), std::begin(expect), std::end(expect))); + + } + { + path p("////foo/bar/baz///"); + const path expect[] = {"/", "foo", "bar", "baz", "."}; + assert(checkCollectionsEqual(p.begin(), p.end(), std::begin(expect), std::end(expect))); + assert(checkCollectionsEqualBackwards(p.begin(), p.end(), std::begin(expect), std::end(expect))); + + } + +} + +int main() { + using namespace fs; + checkIteratorConcepts(); + checkBeginEndBasic(); // See path.decompose.pass.cpp for more tests. +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp new file mode 100644 index 0000000000000..1118497e06a86 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp @@ -0,0 +1,241 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class path + +// path& operator/=(path const&) +// template <class Source> +// path& operator/=(Source const&); +// template <class Source> +// path& append(Source const&); +// template <class InputIterator> +// path& append(InputIterator first, InputIterator last); + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct AppendOperatorTestcase { + MultiStringType lhs; + MultiStringType rhs; + MultiStringType expect; +}; + +#define S(Str) MKSTR(Str) +const AppendOperatorTestcase Cases[] = + { + {S(""), S(""), S("")} + , {S("p1"), S("p2"), S("p1/p2")} + , {S("p1/"), S("p2"), S("p1/p2")} + , {S("p1"), S("/p2"), S("p1/p2")} + , {S("p1/"), S("/p2"), S("p1//p2")} + , {S("p1"), S("\\p2"), S("p1/\\p2")} + , {S("p1\\"), S("p2"), S("p1\\/p2")} + , {S("p1\\"), S("\\p2"), S("p1\\/\\p2")} + , {S("p1"), S(""), S("p1")} + , {S(""), S("p2"), S("p2")} + }; + + +const AppendOperatorTestcase LongLHSCases[] = + { + {S("p1"), S("p2"), S("p1/p2")} + , {S("p1/"), S("p2"), S("p1/p2")} + , {S("p1"), S("/p2"), S("p1/p2")} + }; +#undef S + + +// The append operator may need to allocate a temporary buffer before a code_cvt +// conversion. Test if this allocation occurs by: +// 1. Create a path, `LHS`, and reserve enough space to append `RHS`. +// This prevents `LHS` from allocating during the actual appending. +// 2. Create a `Source` object `RHS`, which represents a "large" string. +// (The string must not trigger the SSO) +// 3. Append `RHS` to `LHS` and check for the expected allocation behavior. +template <class CharT> +void doAppendSourceAllocTest(AppendOperatorTestcase const& TC) +{ + using namespace fs; + using Ptr = CharT const*; + using Str = std::basic_string<CharT>; + using InputIter = input_iterator<Ptr>; + + const Ptr L = TC.lhs; + Str RShort = (Ptr)TC.rhs; + Str EShort = (Ptr)TC.expect; + assert(RShort.size() >= 2); + CharT c = RShort.back(); + RShort.append(100, c); + EShort.append(100, c); + const Ptr R = RShort.data(); + const Str& E = EShort; + std::size_t ReserveSize = E.size() + 3; + // basic_string + { + path LHS(L); PathReserve(LHS, ReserveSize); + Str RHS(R); + { + DisableAllocationGuard g; + LHS /= RHS; + } + assert(LHS == E); + } + // CharT* + { + path LHS(L); PathReserve(LHS, ReserveSize); + Ptr RHS(R); + { + DisableAllocationGuard g; + LHS /= RHS; + } + assert(LHS == E); + } + { + path LHS(L); PathReserve(LHS, ReserveSize); + Ptr RHS(R); + { + DisableAllocationGuard g; + LHS.append(RHS, StrEnd(RHS)); + } + assert(LHS == E); + } + // input iterator - For non-native char types, appends needs to copy the + // iterator range into a contigious block of memory before it can perform the + // code_cvt conversions. + // For "char" no allocations will be performed because no conversion is + // required. + bool DisableAllocations = std::is_same<CharT, char>::value; + { + path LHS(L); PathReserve(LHS, ReserveSize); + InputIter RHS(R); + { + RequireAllocationGuard g; // requires 1 or more allocations occur by default + if (DisableAllocations) g.requireExactly(0); + LHS /= RHS; + } + assert(LHS == E); + } + { + path LHS(L); PathReserve(LHS, ReserveSize); + InputIter RHS(R); + InputIter REnd(StrEnd(R)); + { + RequireAllocationGuard g; + if (DisableAllocations) g.requireExactly(0); + LHS.append(RHS, REnd); + } + assert(LHS == E); + } +} + +template <class CharT> +void doAppendSourceTest(AppendOperatorTestcase const& TC) +{ + using namespace fs; + using Ptr = CharT const*; + using Str = std::basic_string<CharT>; + using InputIter = input_iterator<Ptr>; + const Ptr L = TC.lhs; + const Ptr R = TC.rhs; + const Ptr E = TC.expect; + // basic_string + { + path LHS(L); + Str RHS(R); + path& Ref = (LHS /= RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + Str RHS(R); + path& Ref = LHS.append(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + // Char* + { + path LHS(L); + Str RHS(R); + path& Ref = (LHS /= RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + Ptr RHS(R); + path& Ref = LHS.append(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + Ptr RHS(R); + path& Ref = LHS.append(RHS, StrEnd(RHS)); + assert(LHS == E); + assert(&Ref == &LHS); + } + // iterators + { + path LHS(L); + InputIter RHS(R); + path& Ref = (LHS /= RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); InputIter RHS(R); + path& Ref = LHS.append(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + InputIter RHS(R); + InputIter REnd(StrEnd(R)); + path& Ref = LHS.append(RHS, REnd); + assert(LHS == E); + assert(&Ref == &LHS); + } +} + +int main() +{ + using namespace fs; + for (auto const & TC : Cases) { + { + path LHS((const char*)TC.lhs); + path RHS((const char*)TC.rhs); + path& Ref = (LHS /= RHS); + assert(LHS == (const char*)TC.expect); + assert(&Ref == &LHS); + } + doAppendSourceTest<char> (TC); + doAppendSourceTest<wchar_t> (TC); + doAppendSourceTest<char16_t>(TC); + doAppendSourceTest<char32_t>(TC); + } + for (auto const & TC : LongLHSCases) { + doAppendSourceAllocTest<char>(TC); + doAppendSourceAllocTest<wchar_t>(TC); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.cpp new file mode 100644 index 0000000000000..5c26f8464c121 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.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 + +// <experimental/filesystem> + +// class path + +// path& operator=(path const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + static_assert(std::is_copy_assignable<path>::value, ""); + static_assert(!std::is_nothrow_copy_assignable<path>::value, "should not be noexcept"); + const std::string s("foo"); + const path p(s); + path p2; + path& pref = (p2 = p); + assert(p.native() == s); + assert(p2.native() == s); + assert(&pref == &p2); +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.assign/move.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.assign/move.pass.cpp new file mode 100644 index 0000000000000..7263424ad252f --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.assign/move.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path& operator=(path&&) noexcept + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "count_new.hpp" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + static_assert(std::is_nothrow_move_assignable<path>::value, ""); + assert(globalMemCounter.checkOutstandingNewEq(0)); + const std::string s("we really really really really really really really " + "really really long string so that we allocate"); + assert(globalMemCounter.checkOutstandingNewEq(1)); + path p(s); + { + DisableAllocationGuard g; + path p2; + path& pref = (p2 = std::move(p)); + assert(p2.native() == s); + assert(p.native() != s); // Testing moved from state + assert(&pref == &p2); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp new file mode 100644 index 0000000000000..4c2d5112d10ba --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp @@ -0,0 +1,153 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class path + +// template <class Source> +// path& operator=(Source const&); +// template <class Source> +// path& assign(Source const&); +// template <class InputIterator> +// path& assign(InputIterator first, InputIterator last); + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" +#include <iostream> + +namespace fs = std::experimental::filesystem; + +template <class CharT> +void RunTestCase(MultiStringType const& MS) { + using namespace fs; + const char* Expect = MS; + const CharT* TestPath = MS; + const CharT* TestPathEnd = StrEnd(TestPath); + const std::size_t Size = TestPathEnd - TestPath; + const std::size_t SSize = StrEnd(Expect) - Expect; + assert(Size == SSize); + ////////////////////////////////////////////////////////////////////////////// + // basic_string<Char, Traits, Alloc> + { + const std::basic_string<CharT> S(TestPath); + path p; PathReserve(p, S.length() + 1); + { + // string provides a contigious iterator. No allocation needed. + DisableAllocationGuard g; + path& pref = (p = S); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + assert(p.string<CharT>() == S); + } + { + const std::basic_string<CharT> S(TestPath); + path p; PathReserve(p, S.length() + 1); + { + DisableAllocationGuard g; + path& pref = p.assign(S); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + assert(p.string<CharT>() == S); + } + ////////////////////////////////////////////////////////////////////////////// + // Char* pointers + { + path p; PathReserve(p, Size + 1); + { + // char* pointers are contigious and can be used with code_cvt directly. + // no allocations needed. + DisableAllocationGuard g; + path& pref = (p = TestPath); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + { + path p; PathReserve(p, Size + 1); + { + DisableAllocationGuard g; + path& pref = p.assign(TestPath); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + { + path p; PathReserve(p, Size + 1); + { + DisableAllocationGuard g; + path& pref = p.assign(TestPath, TestPathEnd); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + ////////////////////////////////////////////////////////////////////////////// + // Iterators + { + using It = input_iterator<const CharT*>; + path p; PathReserve(p, Size + 1); + It it(TestPath); + { + // Iterators cannot be used with code_cvt directly. This assignment + // may allocate if it's larger than a "short-string". + path& pref = (p = it); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + { + using It = input_iterator<const CharT*>; + path p; PathReserve(p, Size + 1); + It it(TestPath); + { + path& pref = p.assign(it); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + { + using It = input_iterator<const CharT*>; + path p; PathReserve(p, Size + 1); + It it(TestPath); + It e(TestPathEnd); + { + path& pref = p.assign(it, e); + assert(&pref == &p); + } + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } +} + +int main() { + for (auto const& MS : PathList) { + RunTestCase<char>(MS); + RunTestCase<wchar_t>(MS); + RunTestCase<char16_t>(MS); + RunTestCase<char32_t>(MS); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp new file mode 100644 index 0000000000000..557c1b24d88f1 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp @@ -0,0 +1,126 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class path + +// int compare(path const&) const noexcept; +// int compare(string_type const&) const; +// int compare(value_type const*) const; +// +// bool operator==(path const&, path const&) noexcept; +// bool operator!=(path const&, path const&) noexcept; +// bool operator< (path const&, path const&) noexcept; +// bool operator<=(path const&, path const&) noexcept; +// bool operator> (path const&, path const&) noexcept; +// bool operator>=(path const&, path const&) noexcept; +// +// size_t hash_value(path const&) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <vector> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct PathCompareTest { + const char* LHS; + const char* RHS; + int expect; +}; + +#define LONGA "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +#define LONGB "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" +#define LONGC "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" +#define LONGD "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" +const PathCompareTest CompareTestCases[] = +{ + {"", "", 0}, + {"a", "", 1}, + {"", "a", -1}, + {"a/b/c", "a/b/c", 0}, + {"b/a/c", "a/b/c", 1}, + {"a/b/c", "b/a/c", -1}, + {"a/b", "a/b/c", -1}, + {"a/b/c", "a/b", 1}, + {"a/b/", "a/b/.", 0}, + {"a/b//////", "a/b/////.", 0}, + {"a/.././b", "a///..//.////b", 0}, + {"//foo//bar///baz////", "//foo/bar/baz/", 0}, // duplicate separators + {"///foo/bar", "/foo/bar", 0}, // "///" is not a root directory + {"/foo/bar/", "/foo/bar", 1}, // trailing separator + {"//" LONGA "////" LONGB "/" LONGC "///" LONGD, "//" LONGA "/" LONGB "/" LONGC "/" LONGD, 0}, + { LONGA "/" LONGB "/" LONGC, LONGA "/" LONGB "/" LONGB, 1} + +}; +#undef LONGA +#undef LONGB +#undef LONGC +#undef LONGD + +int main() +{ + using namespace fs; + for (auto const & TC : CompareTestCases) { + const path p1(TC.LHS); + const path p2(TC.RHS); + const std::string R(TC.RHS); + const int E = TC.expect; + { // compare(...) functions + DisableAllocationGuard g; // none of these operations should allocate + + // check runtime results + int ret1 = p1.compare(p2); + int ret2 = p1.compare(R); + int ret3 = p1.compare(TC.RHS); + assert(ret1 == ret2 && ret1 == ret3); + int normalized_ret = ret1 < 0 ? -1 : (ret1 > 0 ? 1 : 0); + assert(normalized_ret == E); + + // check signatures + ASSERT_NOEXCEPT(p1.compare(p2)); + } + { // comparison operators + DisableAllocationGuard g; // none of these operations should allocate + + // Check runtime result + assert((p1 == p2) == (E == 0)); + assert((p1 != p2) == (E != 0)); + assert((p1 < p2) == (E < 0)); + assert((p1 <= p2) == (E <= 0)); + assert((p1 > p2) == (E > 0)); + assert((p1 >= p2) == (E >= 0)); + + // Check signatures + ASSERT_NOEXCEPT(p1 == p2); + ASSERT_NOEXCEPT(p1 != p2); + ASSERT_NOEXCEPT(p1 < p2); + ASSERT_NOEXCEPT(p1 <= p2); + ASSERT_NOEXCEPT(p1 > p2); + ASSERT_NOEXCEPT(p1 >= p2); + } + { // check hash values + auto h1 = hash_value(p1); + auto h2 = hash_value(p2); + assert((h1 == h2) == (p1 == p2)); + // check signature + ASSERT_SAME_TYPE(size_t, decltype(hash_value(p1))); + ASSERT_NOEXCEPT(hash_value(p1)); + } + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp new file mode 100644 index 0000000000000..6e00afe0b49c3 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp @@ -0,0 +1,277 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class path + +// path& operator+=(const path& x); +// path& operator+=(const string_type& x); // Implemented as Source template +// path& operator+=(const value_type* x); // Implemented as Source template +// path& operator+=(value_type x); +// template <class Source> +// path& operator+=(const Source& x); +// template <class EcharT> +// path& operator+=(EcharT x); +// template <class Source> +// path& concat(const Source& x); +// template <class InputIterator> +// path& concat(InputIterator first, InputIterator last); + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct ConcatOperatorTestcase { + MultiStringType lhs; + MultiStringType rhs; + MultiStringType expect; +}; + +#define LONGSTR "LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR" +#define S(Str) MKSTR(Str) +const ConcatOperatorTestcase Cases[] = + { + {S(""), S(""), S("")} + , {S("p1"), S("p2"), S("p1p2")} + , {S("p1/"), S("/p2"), S("p1//p2")} + , {S(""), S("\\foo/bar/baz"), S("\\foo/bar/baz")} + , {S("c:\\foo"), S(""), S("c:\\foo")} + , {S(LONGSTR), S("foo"), S(LONGSTR "foo")} + , {S("abcdefghijklmnopqrstuvwxyz/\\"), S("/\\123456789"), S("abcdefghijklmnopqrstuvwxyz/\\/\\123456789")} + }; +const ConcatOperatorTestcase LongLHSCases[] = + { + {S(""), S(LONGSTR), S(LONGSTR)} + , {S("p1/"), S(LONGSTR), S("p1/" LONGSTR)} + }; +const ConcatOperatorTestcase CharTestCases[] = + { + {S(""), S("P"), S("P")} + , {S("/fooba"), S("r"), S("/foobar")} + }; +#undef S +#undef LONGSTR + +// The concat operator may need to allocate a temporary buffer before a code_cvt +// conversion. Test if this allocation occurs by: +// 1. Create a path, `LHS`, and reserve enough space to append `RHS`. +// This prevents `LHS` from allocating during the actual appending. +// 2. Create a `Source` object `RHS`, which represents a "large" string. +// (The string must not trigger the SSO) +// 3. Concat `RHS` to `LHS` and check for the expected allocation behavior. +template <class CharT> +void doConcatSourceAllocTest(ConcatOperatorTestcase const& TC) +{ + using namespace fs; + using Ptr = CharT const*; + using Str = std::basic_string<CharT>; + using InputIter = input_iterator<Ptr>; + + const Ptr L = TC.lhs; + const Ptr R = TC.rhs; + const Ptr E = TC.expect; + std::size_t ReserveSize = StrLen(E) + 1; + // basic_string + { + path LHS(L); PathReserve(LHS, ReserveSize); + Str RHS(R); + { + DisableAllocationGuard g; + LHS += RHS; + } + assert(LHS == E); + } + // CharT* + { + path LHS(L); PathReserve(LHS, ReserveSize); + Ptr RHS(R); + { + DisableAllocationGuard g; + LHS += RHS; + } + assert(LHS == E); + } + { + path LHS(L); PathReserve(LHS, ReserveSize); + Ptr RHS(R); + { + DisableAllocationGuard g; + LHS.concat(RHS, StrEnd(RHS)); + } + assert(LHS == E); + } + // input iterator - For non-native char types, appends needs to copy the + // iterator range into a contigious block of memory before it can perform the + // code_cvt conversions. + // For "char" no allocations will be performed because no conversion is + // required. + bool DisableAllocations = std::is_same<CharT, char>::value; + { + path LHS(L); PathReserve(LHS, ReserveSize); + InputIter RHS(R); + { + RequireAllocationGuard g; // requires 1 or more allocations occur by default + if (DisableAllocations) g.requireExactly(0); + LHS += RHS; + } + assert(LHS == E); + } + { + path LHS(L); PathReserve(LHS, ReserveSize); + InputIter RHS(R); + InputIter REnd(StrEnd(R)); + { + RequireAllocationGuard g; + if (DisableAllocations) g.requireExactly(0); + LHS.concat(RHS, REnd); + } + assert(LHS == E); + } +} + +template <class CharT> +void doConcatSourceTest(ConcatOperatorTestcase const& TC) +{ + using namespace fs; + using Ptr = CharT const*; + using Str = std::basic_string<CharT>; + using InputIter = input_iterator<Ptr>; + const Ptr L = TC.lhs; + const Ptr R = TC.rhs; + const Ptr E = TC.expect; + // basic_string + { + path LHS(L); + Str RHS(R); + path& Ref = (LHS += RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + Str RHS(R); + path& Ref = LHS.concat(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + // Char* + { + path LHS(L); + Str RHS(R); + path& Ref = (LHS += RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + Ptr RHS(R); + path& Ref = LHS.concat(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + Ptr RHS(R); + path& Ref = LHS.concat(RHS, StrEnd(RHS)); + assert(LHS == E); + assert(&Ref == &LHS); + } + // iterators + { + path LHS(L); + InputIter RHS(R); + path& Ref = (LHS += RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); InputIter RHS(R); + path& Ref = LHS.concat(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + InputIter RHS(R); + InputIter REnd(StrEnd(R)); + path& Ref = LHS.concat(RHS, REnd); + assert(LHS == E); + assert(&Ref == &LHS); + } +} + +template <class CharT> +void doConcatECharTest(ConcatOperatorTestcase const& TC) +{ + using namespace fs; + using Ptr = CharT const*; + const Ptr RStr = TC.rhs; + assert(StrLen(RStr) == 1); + const Ptr L = TC.lhs; + const CharT R = RStr[0]; + const Ptr E = TC.expect; + { + path LHS(L); + path& Ref = (LHS += R); + assert(LHS == E); + assert(&Ref == &LHS); + } +} + +int main() +{ + using namespace fs; + for (auto const & TC : Cases) { + { + path LHS((const char*)TC.lhs); + path RHS((const char*)TC.rhs); + path& Ref = (LHS += RHS); + assert(LHS == (const char*)TC.expect); + assert(&Ref == &LHS); + } + doConcatSourceTest<char> (TC); + doConcatSourceTest<wchar_t> (TC); + doConcatSourceTest<char16_t>(TC); + doConcatSourceTest<char32_t>(TC); + } + for (auto const & TC : LongLHSCases) { + // Do path test + { + path LHS((const char*)TC.lhs); + path RHS((const char*)TC.rhs); + const char* E = TC.expect; + PathReserve(LHS, StrLen(E) + 5); + { + DisableAllocationGuard g; + path& Ref = (LHS += RHS); + assert(&Ref == &LHS); + } + assert(LHS == E); + } + doConcatSourceAllocTest<char>(TC); + doConcatSourceAllocTest<wchar_t>(TC); + } + for (auto const& TC : CharTestCases) { + doConcatECharTest<char>(TC); + doConcatECharTest<wchar_t>(TC); + doConcatECharTest<char16_t>(TC); + doConcatECharTest<char32_t>(TC); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp new file mode 100644 index 0000000000000..67b8a04049ecc --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class path + +// path(path const&) + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + static_assert(std::is_copy_constructible<path>::value, ""); + static_assert(!std::is_nothrow_copy_constructible<path>::value, "should not be noexcept"); + const std::string s("foo"); + const path p(s); + path p2(p); + assert(p.native() == s); + assert(p2.native() == s); +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.construct/default.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.construct/default.pass.cpp new file mode 100644 index 0000000000000..f26504616d50b --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.construct/default.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path() noexcept + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + static_assert(std::is_nothrow_default_constructible<path>::value, ""); + const path p; + assert(p.empty()); +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.construct/move.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.construct/move.pass.cpp new file mode 100644 index 0000000000000..b8ac4b307005a --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.construct/move.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 + +// <experimental/filesystem> + +// class path + +// path(path&&) noexcept + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "count_new.hpp" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + static_assert(std::is_nothrow_move_constructible<path>::value, ""); + assert(globalMemCounter.checkOutstandingNewEq(0)); + const std::string s("we really really really really really really really " + "really really long string so that we allocate"); + assert(globalMemCounter.checkOutstandingNewEq(1)); + path p(s); + { + DisableAllocationGuard g; + path p2(std::move(p)); + assert(p2.native() == s); + assert(p.native() != s); // Testing moved from state + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp new file mode 100644 index 0000000000000..d89e7c815efb9 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class path + +// template <class Source> +// path(const Source& source); +// template <class InputIterator> +// path(InputIterator first, InputIterator last); + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "min_allocator.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +template <class CharT> +void RunTestCase(MultiStringType const& MS) { + using namespace fs; + const char* Expect = MS; + const CharT* TestPath = MS; + const CharT* TestPathEnd = StrEnd(TestPath); + const std::size_t Size = TestPathEnd - TestPath; + const std::size_t SSize = StrEnd(Expect) - Expect; + assert(Size == SSize); + // StringTypes + { + const std::basic_string<CharT> S(TestPath); + path p(S); + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + assert(p.string<CharT>() == S); + } + // Char* pointers + { + path p(TestPath); + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + { + path p(TestPath, TestPathEnd); + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + // Iterators + { + using It = input_iterator<const CharT*>; + path p(It{TestPath}); + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } + { + using It = input_iterator<const CharT*>; + path p(It{TestPath}, It{TestPathEnd}); + assert(p.native() == Expect); + assert(p.string<CharT>() == TestPath); + } +} + +int main() { + for (auto const& MS : PathList) { + RunTestCase<char>(MS); + RunTestCase<wchar_t>(MS); + RunTestCase<char16_t>(MS); + RunTestCase<char32_t>(MS); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp new file mode 100644 index 0000000000000..4c83481aaf2d8 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp @@ -0,0 +1,198 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class path + +// 8.4.9 path decomposition [path.decompose] +//------------------------------------------ +// path root_name() const; +// path root_directory() const; +// path root_path() const; +// path relative_path() const; +// path parent_path() const; +// path filename() const; +// path stem() const; +// path extension() const; +//------------------------------- +// 8.4.10 path query [path.query] +//------------------------------- +// bool empty() const noexcept; +// bool has_root_path() const; +// bool has_root_name() const; +// bool has_root_directory() const; +// bool has_relative_path() const; +// bool has_parent_path() const; +// bool has_filename() const; +// bool has_stem() const; +// bool has_extension() const; +// bool is_absolute() const; +// bool is_relative() const; +//------------------------------- +// 8.5 path iterators [path.itr] +//------------------------------- +// iterator begin() const; +// iterator end() const; + + +#include <experimental/filesystem> +#include <type_traits> +#include <vector> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +template <class It> +std::reverse_iterator<It> mkRev(It it) { + return std::reverse_iterator<It>(it); +} + + +namespace fs = std::experimental::filesystem; +struct PathDecomposeTestcase +{ + std::string raw; + std::vector<std::string> elements; + std::string root_path; + std::string root_name; + std::string root_directory; + std::string relative_path; + std::string parent_path; + std::string filename; +}; + +const PathDecomposeTestcase PathTestCases[] = + { + {"", {}, "", "", "", "", "", ""} + , {".", {"."}, "", "", "", ".", "", "."} + , {"..", {".."}, "", "", "", "..", "", ".."} + , {"foo", {"foo"}, "", "", "", "foo", "", "foo"} + , {"/", {"/"}, "/", "", "/", "", "", "/"} + , {"/foo", {"/", "foo"}, "/", "", "/", "foo", "/", "foo"} + , {"foo/", {"foo", "."}, "", "", "", "foo/", "foo", "."} + , {"/foo/", {"/", "foo", "."}, "/", "", "/", "foo/", "/foo", "."} + , {"foo/bar", {"foo","bar"}, "", "", "", "foo/bar", "foo", "bar"} + , {"/foo//bar", {"/","foo","bar"}, "/", "", "/", "foo/bar", "/foo", "bar"} + , {"//net", {"//net"}, "//net", "//net", "", "", "", "//net"} + , {"//net/foo", {"//net", "/", "foo"}, "//net/", "//net", "/", "foo", "//net/", "foo"} + , {"///foo///", {"/", "foo", "."}, "/", "", "/", "foo///", "///foo", "."} + , {"///foo///bar", {"/", "foo", "bar"}, "/", "", "/", "foo///bar", "///foo", "bar"} + , {"/.", {"/", "."}, "/", "", "/", ".", "/", "."} + , {"./", {".", "."}, "", "", "", "./", ".", "."} + , {"/..", {"/", ".."}, "/", "", "/", "..", "/", ".."} + , {"../", {"..", "."}, "", "", "", "../", "..", "."} + , {"foo/.", {"foo", "."}, "", "", "", "foo/.", "foo", "."} + , {"foo/..", {"foo", ".."}, "", "", "", "foo/..", "foo", ".."} + , {"foo/./", {"foo", ".", "."}, "", "", "", "foo/./", "foo/.", "."} + , {"foo/./bar", {"foo", ".", "bar"}, "", "", "", "foo/./bar", "foo/.", "bar"} + , {"foo/../", {"foo", "..", "."}, "", "", "", "foo/../", "foo/..", "."} + , {"foo/../bar", {"foo", "..", "bar"}, "", "", "", "foo/../bar", "foo/..", "bar"} + , {"c:", {"c:"}, "", "", "", "c:", "", "c:"} + , {"c:/", {"c:", "."}, "", "", "", "c:/", "c:", "."} + , {"c:foo", {"c:foo"}, "", "", "", "c:foo", "", "c:foo"} + , {"c:/foo", {"c:", "foo"}, "", "", "", "c:/foo", "c:", "foo"} + , {"c:foo/", {"c:foo", "."}, "", "", "", "c:foo/", "c:foo", "."} + , {"c:/foo/", {"c:", "foo", "."}, "", "", "", "c:/foo/", "c:/foo", "."} + , {"c:/foo/bar", {"c:", "foo", "bar"}, "", "", "", "c:/foo/bar", "c:/foo", "bar"} + , {"prn:", {"prn:"}, "", "", "", "prn:", "", "prn:"} + , {"c:\\", {"c:\\"}, "", "", "", "c:\\", "", "c:\\"} + , {"c:\\foo", {"c:\\foo"}, "", "", "", "c:\\foo", "", "c:\\foo"} + , {"c:foo\\", {"c:foo\\"}, "", "", "", "c:foo\\", "", "c:foo\\"} + , {"c:\\foo\\", {"c:\\foo\\"}, "", "", "", "c:\\foo\\", "", "c:\\foo\\"} + , {"c:\\foo/", {"c:\\foo", "."}, "", "", "", "c:\\foo/", "c:\\foo", "."} + , {"c:/foo\\bar", {"c:", "foo\\bar"}, "", "", "", "c:/foo\\bar", "c:", "foo\\bar"} + , {"//", {"//"}, "//", "//", "", "", "", "//"} + }; + +void decompPathTest() +{ + using namespace fs; + for (auto const & TC : PathTestCases) { + path p(TC.raw); + assert(p == TC.raw); + + assert(p.root_path() == TC.root_path); + assert(p.has_root_path() != TC.root_path.empty()); + + assert(p.root_name() == TC.root_name); + assert(p.has_root_name() != TC.root_name.empty()); + + assert(p.root_directory() == TC.root_directory); + assert(p.has_root_directory() != TC.root_directory.empty()); + + assert(p.relative_path() == TC.relative_path); + assert(p.has_relative_path() != TC.relative_path.empty()); + + assert(p.parent_path() == TC.parent_path); + assert(p.has_parent_path() != TC.parent_path.empty()); + + assert(p.filename() == TC.filename); + assert(p.has_filename() != TC.filename.empty()); + + assert(p.is_absolute() == p.has_root_directory()); + assert(p.is_relative() != p.is_absolute()); + + assert(checkCollectionsEqual(p.begin(), p.end(), + TC.elements.begin(), TC.elements.end())); + // check backwards + assert(checkCollectionsEqual(mkRev(p.end()), mkRev(p.begin()), + TC.elements.rbegin(), TC.elements.rend())); + } +} + + +struct FilenameDecompTestcase +{ + std::string raw; + std::string filename; + std::string stem; + std::string extension; +}; + +const FilenameDecompTestcase FilenameTestCases[] = +{ + {"", "", "", ""} + , {".", ".", ".", ""} + , {"..", "..", "..", ""} + , {"/", "/", "/", ""} + , {"foo", "foo", "foo", ""} + , {"/foo/bar.txt", "bar.txt", "bar", ".txt"} + , {"foo..txt", "foo..txt", "foo.", ".txt"} +}; + + +void decompFilenameTest() +{ + using namespace fs; + for (auto const & TC : FilenameTestCases) { + path p(TC.raw); + assert(p == TC.raw); + + assert(p.filename() == TC.filename); + assert(p.has_filename() != TC.filename.empty()); + + assert(p.stem() == TC.stem); + assert(p.has_stem() != TC.stem.empty()); + + assert(p.extension() == TC.extension); + assert(p.has_extension() != TC.extension.empty()); + } +} + +int main() +{ + decompPathTest(); + decompFilenameTest(); +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp new file mode 100644 index 0000000000000..47e94c9a213f6 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class path + +// template <class ECharT, class Traits = char_traits<ECharT>, +// class Allocator = allocator<ECharT>> +// basic_string<ECharT, Traits, Allocator> +// generic_string(const Allocator& a = Allocator()) const; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "min_allocator.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + + +// generic_string<C, T, A> forwards to string<C, T, A>. Tests for +// string<C, T, A>() are in "path.native.op/string_alloc.pass.cpp". +// generic_string is minimally tested here. +int main() +{ + using namespace fs; + using CharT = wchar_t; + using Traits = std::char_traits<CharT>; + using Alloc = malloc_allocator<CharT>; + using Str = std::basic_string<CharT, Traits, Alloc>; + const wchar_t* expect = longString; + const path p((const char*)longString); + { + DisableAllocationGuard g; + Alloc a; + Alloc::disable_default_constructor = true; + Str s = p.generic_string<wchar_t, Traits, Alloc>(a); + assert(s == expect); + assert(Alloc::alloc_count > 0); + assert(Alloc::outstanding_alloc() == 1); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.pass.cpp new file mode 100644 index 0000000000000..81d06843640db --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.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 + +// <experimental/filesystem> + +// class path + +// std::string generic_string() const; +// std::wstring generic_wstring() const; +// std::u8string generic_u8string() const; +// std::u16string generic_u16string() const; +// std::u32string generic_u32string() const; + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "min_allocator.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + +int main() +{ + using namespace fs; + auto const& MS = longString; + const char* value = longString; + const path p(value); + { + std::string s = p.generic_string(); + assert(s == value); + } + { + std::string s = p.generic_u8string(); + assert(s == (const char*)MS); + } + { + std::wstring s = p.generic_wstring(); + assert(s == (const wchar_t*)MS); + } + { + std::u16string s = p.generic_u16string(); + assert(s == (const char16_t*)MS); + } + { + std::u32string s = p.generic_u32string(); + assert(s == (const char32_t*)MS); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp new file mode 100644 index 0000000000000..5be934968c468 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.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 + +// <experimental/filesystem> + +// class path + +// void clear() noexcept + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + const path p("/foo/bar/baz"); + { + path p; + ASSERT_NOEXCEPT(p.clear()); + ASSERT_SAME_TYPE(void, decltype(p.clear())); + p.clear(); + assert(p.empty()); + } + { + path p2(p); + assert(p == p2); + p2.clear(); + assert(p2.empty()); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp new file mode 100644 index 0000000000000..559538cf0ec42 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class path + +// path& make_preferred() + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct MakePreferredTestcase { + const char* value; +}; + +const MakePreferredTestcase TestCases[] = + { + {""} + , {"hello_world"} + , {"/"} + , {"/foo/bar/baz/"} + , {"\\"} + , {"\\foo\\bar\\baz\\"} + , {"\\foo\\/bar\\/baz\\"} + }; + +int main() +{ + // This operation is an identity operation on linux. + using namespace fs; + for (auto const & TC : TestCases) { + path p(TC.value); + assert(p == TC.value); + path& Ref = (p.make_preferred()); + assert(p.native() == TC.value); + assert(&Ref == &p); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp new file mode 100644 index 0000000000000..4ad9084dbf81e --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path& remove_filename() + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct RemoveFilenameTestcase { + const char* value; + const char* expect; +}; + +const RemoveFilenameTestcase TestCases[] = + { + {"", ""} + , {"/", ""} + , {"\\", ""} + , {".", ""} + , {"..", ""} + , {"/foo", "/"} + , {"/foo/", "/foo"} + , {"/foo/.", "/foo"} + , {"/foo/..", "/foo"} + , {"/foo/////", "/foo"} + , {"/foo\\\\", "/"} + , {"/foo//\\/", "/foo//\\"} + , {"file.txt", ""} + , {"bar/../baz/./file.txt", "bar/../baz/."} + }; + +int main() +{ + using namespace fs; + for (auto const & TC : TestCases) { + path const p_orig(TC.value); + path p(p_orig); + assert(p == TC.value); + path& Ref = (p.remove_filename()); + assert(p == TC.expect); + assert(&Ref == &p); + { + const path parentp = p_orig.parent_path(); + if (parentp == p_orig.root_name()) { + + assert(p.empty()); + } else { + assert(p == parentp); + } + } + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.pass.cpp new file mode 100644 index 0000000000000..98f6e9b88ab8c --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.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: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path& replace_extension(path const& p = path()) + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct ReplaceExtensionTestcase { + const char* value; + const char* expect; + const char* extension; +}; + +const ReplaceExtensionTestcase TestCases[] = + { + {"", "", ""} + , {"foo.cpp", "foo", ""} + , {"foo.cpp", "foo.", "."} + , {"foo..cpp", "foo..txt", "txt"} + , {"", ".txt", "txt"} + , {"", ".txt", ".txt"} + , {"/foo", "/foo.txt", ".txt"} + , {"/foo", "/foo.txt", "txt"} + , {"/foo.cpp", "/foo.txt", ".txt"} + , {"/foo.cpp", "/foo.txt", "txt"} + }; +const ReplaceExtensionTestcase NoArgCases[] = + { + {"", "", ""} + , {"foo", "foo", ""} + , {"foo.cpp", "foo", ""} + , {"foo..cpp", "foo.", ""} +}; + +int main() +{ + using namespace fs; + for (auto const & TC : TestCases) { + path p(TC.value); + assert(p == TC.value); + path& Ref = (p.replace_extension(TC.extension)); + assert(p == TC.expect); + assert(&Ref == &p); + } + for (auto const& TC : NoArgCases) { + path p(TC.value); + assert(p == TC.value); + path& Ref = (p.replace_extension()); + assert(p == TC.expect); + assert(&Ref == &p); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.cpp new file mode 100644 index 0000000000000..66c97218c8331 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// path& replace_filename() + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct ReplaceFilenameTestcase { + const char* value; + const char* expect; + const char* filename; +}; + +const ReplaceFilenameTestcase TestCases[] = + { + {"/foo", "/bar", "bar"} + , {"/foo", "/", ""} + , {"foo", "bar", "bar"} + , {"/", "bar", "bar"} + , {"\\", "bar", "bar"} + , {"///", "bar", "bar"} + , {"\\\\", "bar", "bar"} + , {"\\/\\", "\\/bar", "bar"} + , {".", "bar", "bar"} + , {"..", "bar", "bar"} + , {"/foo\\baz/bong/", "/foo\\baz/bong/bar", "bar"} + , {"/foo\\baz/bong", "/foo\\baz/bar", "bar"} + }; + +int main() +{ + using namespace fs; + for (auto const & TC : TestCases) { + path p(TC.value); + assert(p == TC.value); + path& Ref = (p.replace_filename(TC.filename)); + assert(p == TC.expect); + assert(&Ref == &p); + // Tests Effects "as-if": remove_filename() append(filename) + { + path p2(TC.value); + path replace(TC.filename); + p2.remove_filename(); + p2 /= replace; + assert(p2 == p); + } + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.pass.cpp new file mode 100644 index 0000000000000..04bbe3751a59f --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.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 + +// <experimental/filesystem> + +// class path + +// void swap(path& rhs) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +struct SwapTestcase { + const char* value1; + const char* value2; +}; + +#define LONG_STR1 "_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG" +#define LONG_STR2 "_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2" +const SwapTestcase TestCases[] = + { + {"", ""} + , {"shortstr", LONG_STR1} + , {LONG_STR1, "shortstr"} + , {LONG_STR1, LONG_STR2} + }; +#undef LONG_STR1 +#undef LONG_STR2 + +int main() +{ + using namespace fs; + { + path p; + ASSERT_NOEXCEPT(p.swap(p)); + ASSERT_SAME_TYPE(void, decltype(p.swap(p))); + } + for (auto const & TC : TestCases) { + path p1(TC.value1); + path p2(TC.value2); + { + DisableAllocationGuard g; + p1.swap(p2); + } + assert(p1 == TC.value2); + assert(p2 == TC.value1); + { + DisableAllocationGuard g; + p1.swap(p2); + } + assert(p1 == TC.value1); + assert(p2 == TC.value2); + } + // self-swap + { + const char* Val = "aoeuaoeuaoeuaoeuaoeuaoeuaoeuaoeuaoeu"; + path p1(Val); + assert(p1 == Val); + { + DisableAllocationGuard g; + p1.swap(p1); + } + assert(p1 == Val); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp new file mode 100644 index 0000000000000..7cf3564bb9b1b --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// const value_type* c_str() const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +int main() +{ + using namespace fs; + const char* const value = "hello world"; + const std::string str_value = value; + path p(value); + { // Check signature + ASSERT_SAME_TYPE(path::value_type const*, decltype(p.c_str())); + ASSERT_NOEXCEPT(p.c_str()); + } + { + path p(value); + assert(p.c_str() == str_value); + assert(p.native().c_str() == p.c_str()); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.pass.cpp new file mode 100644 index 0000000000000..2a83fef9f9e64 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.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 + +// <experimental/filesystem> + +// class path + +// std::string string() const; +// std::wstring wstring() const; +// std::u8string u8string() const; +// std::u16string u16string() const; +// std::u32string u32string() const; + + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "min_allocator.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + +int main() +{ + using namespace fs; + auto const& MS = longString; + const char* value = longString; + const path p(value); + { + std::string s = p.string(); + assert(s == value); + } + { + std::string s = p.u8string(); + assert(s == (const char*)MS); + } + { + std::wstring s = p.wstring(); + assert(s == (const wchar_t*)MS); + } + { + std::u16string s = p.u16string(); + assert(s == (const char16_t*)MS); + } + { + std::u32string s = p.u32string(); + assert(s == (const char32_t*)MS); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp new file mode 100644 index 0000000000000..7f8df27faf0ad --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.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 + +// <experimental/filesystem> + +// class path + +// const string_type& native() const noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +int main() +{ + using namespace fs; + const char* const value = "hello world"; + path p(value); + { // Check signature + ASSERT_SAME_TYPE(path::string_type const&, decltype(p.native())); + ASSERT_NOEXCEPT(p.native()); + } + { // native() is tested elsewhere + path p(value); + assert(p.native() == value); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp new file mode 100644 index 0000000000000..9ef83f989aa55 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp @@ -0,0 +1,47 @@ + +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class path + +// operator string_type() const; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +int main() +{ + using namespace fs; + using string_type = path::string_type; + const char* const value = "hello world"; + path p(value); + { // Check signature + static_assert(std::is_convertible<path, string_type>::value, ""); + static_assert(std::is_constructible<string_type, path>::value, ""); + ASSERT_SAME_TYPE(string_type, decltype(p.operator string_type())); + ASSERT_NOT_NOEXCEPT(p.operator string_type()); + } + { + path p(value); + assert(p.native() == value); + string_type s = p; + assert(s == value); + assert(p == value); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp new file mode 100644 index 0000000000000..e983297350001 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp @@ -0,0 +1,138 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class path + +// template <class ECharT, class Traits = char_traits<ECharT>, +// class Allocator = allocator<ECharT>> +// basic_string<ECharT, Traits, Allocator> +// string(const Allocator& a = Allocator()) const; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "min_allocator.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +// the SSO is always triggered for strings of size 2. +MultiStringType shortString = MKSTR("a"); +MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + +template <class CharT> +void doShortStringTest(MultiStringType const& MS) { + using namespace fs; + using Ptr = CharT const*; + using Str = std::basic_string<CharT>; + using Alloc = std::allocator<CharT>; + Ptr value = MS; + const path p((const char*)MS); + { + DisableAllocationGuard g; + Str s = p.string<CharT>(); + assert(s == value); + Str s2 = p.string<CharT>(Alloc{}); + assert(s2 == value); + } + using MAlloc = malloc_allocator<CharT>; + MAlloc::reset(); + { + using Traits = std::char_traits<CharT>; + using AStr = std::basic_string<CharT, Traits, MAlloc>; + DisableAllocationGuard g; + AStr s = p.string<CharT, Traits, MAlloc>(); + assert(s == value); + assert(MAlloc::alloc_count == 0); + assert(MAlloc::outstanding_alloc() == 0); + } + MAlloc::reset(); + { // Other allocator - provided copy + using Traits = std::char_traits<CharT>; + using AStr = std::basic_string<CharT, Traits, MAlloc>; + DisableAllocationGuard g; + MAlloc a; + // don't allow another allocator to be default constructed. + MAlloc::disable_default_constructor = true; + AStr s = p.string<CharT, Traits, MAlloc>(a); + assert(s == value); + assert(MAlloc::alloc_count == 0); + assert(MAlloc::outstanding_alloc() == 0); + } + MAlloc::reset(); +} + +template <class CharT> +void doLongStringTest(MultiStringType const& MS) { + using namespace fs; + using Ptr = CharT const*; + using Str = std::basic_string<CharT>; + Ptr value = MS; + const path p((const char*)MS); + { // Default allocator + using Alloc = std::allocator<CharT>; + Str s = p.string<CharT>(); + assert(s == value); + Str s2 = p.string<CharT>(Alloc{}); + assert(s2 == value); + } + using MAlloc = malloc_allocator<CharT>; + MAlloc::reset(); + { // Other allocator - default construct + using Traits = std::char_traits<CharT>; + using AStr = std::basic_string<CharT, Traits, MAlloc>; + DisableAllocationGuard g; + AStr s = p.string<CharT, Traits, MAlloc>(); + assert(s == value); + assert(MAlloc::alloc_count > 0); + assert(MAlloc::outstanding_alloc() == 1); + } + MAlloc::reset(); + { // Other allocator - provided copy + using Traits = std::char_traits<CharT>; + using AStr = std::basic_string<CharT, Traits, MAlloc>; + DisableAllocationGuard g; + MAlloc a; + // don't allow another allocator to be default constructed. + MAlloc::disable_default_constructor = true; + AStr s = p.string<CharT, Traits, MAlloc>(a); + assert(s == value); + assert(MAlloc::alloc_count > 0); + assert(MAlloc::outstanding_alloc() == 1); + } + MAlloc::reset(); + ///////////////////////////////////////////////////////////////////////////// +} + +int main() +{ + using namespace fs; + { + auto const& S = shortString; + doShortStringTest<char>(S); + doShortStringTest<wchar_t>(S); + doShortStringTest<char16_t>(S); + doShortStringTest<char32_t>(S); + } + { + auto const& S = longString; + doLongStringTest<char>(S); + doLongStringTest<wchar_t>(S); + doLongStringTest<char16_t>(S); + doLongStringTest<char32_t>(S); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp new file mode 100644 index 0000000000000..9cf37d4cd537a --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +//------------------------------- +// 8.4.10 path query [path.query] +//------------------------------- +// bool empty() const noexcept; +// bool has_root_path() const; +// bool has_root_name() const; +// bool has_root_directory() const; +// bool has_relative_path() const; +// bool has_parent_path() const; +// bool has_filename() const; +// bool has_stem() const; +// bool has_extension() const; +// bool is_absolute() const; +// bool is_relative() const; + +// tested in path.decompose +int main() {} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp new file mode 100644 index 0000000000000..58983778446a9 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// path operator/(path const&, path const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +// This is mainly tested via the member append functions. +int main() +{ + using namespace fs; + path p1("abc"); + path p2("def"); + path p3 = p1 / p2; + assert(p3 == "abc/def"); +} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp new file mode 100644 index 0000000000000..28867432c61de --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp @@ -0,0 +1,14 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// The comparison operators are tested as part of [path.compare] +// in class.path/path.members/path.compare.pass.cpp +int main() {} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp new file mode 100644 index 0000000000000..b03b8008b6220 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp @@ -0,0 +1,14 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// The "hash_value" function is tested as part of [path.compare] +// in class.path/path.members/path.compare.pass.cpp +int main() {} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.pass.cpp new file mode 100644 index 0000000000000..4853994b49500 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.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 + +// <experimental/filesystem> + +// template <class Source> +// path u8path(Source const&); +// template <class InputIter> +// path u8path(InputIter, InputIter); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +int main() +{ + using namespace fs; + const char* In1 = "abcd/efg"; + const std::string In2(In1); + const auto In3 = In2.begin(); + const auto In3End = In2.end(); + { + path p = fs::u8path(In1); + assert(p == In1); + } + { + path p = fs::u8path(In2); + assert(p == In1); + } + { + path p = fs::u8path(In3); + assert(p == In1); + } + { + path p = fs::u8path(In3, In3End); + assert(p == In1); + } +} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp new file mode 100644 index 0000000000000..e8d150f1e39df --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class path + +// template <class charT, class traits> +// basic_ostream<charT, traits>& +// operator<<(basic_ostream<charT, traits>& os, const path& p); +// +// template <class charT, class traits> +// basic_istream<charT, traits>& +// operator>>(basic_istream<charT, traits>& is, path& p) +// + +#include <experimental/filesystem> +#include <type_traits> +#include <sstream> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +MultiStringType InStr = MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789"); +MultiStringType OutStr = MKSTR("\"abcdefg/\\\"hijklmnop\\\"/qrstuvwxyz/123456789\""); + +template <class CharT> +void doIOTest() { + using namespace fs; + using Ptr = const CharT*; + using StrStream = std::basic_stringstream<CharT>; + const char* const InCStr = InStr; + const Ptr E = OutStr; + const path p((const char*)InStr); + StrStream ss; + { // test output + auto& ret = (ss << p); + assert(ss.str() == E); + assert(&ret == &ss); + } + { // test input + path p_in; + auto& ret = ss >> p_in; + assert(p_in.native() == (const char*)InStr); + assert(&ret == &ss); + } +} + + +int main() { + doIOTest<char>(); + doIOTest<wchar_t>(); + //doIOTest<char16_t>(); + //doIOTest<char32_t>(); +} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.cpp new file mode 100644 index 0000000000000..3a9b48b2669a7 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// template <class charT, class traits> +// basic_ostream<charT, traits>& +// operator<<(basic_ostream<charT, traits>& os, const path& p); +// +// template <class charT, class traits> +// basic_istream<charT, traits>& +// operator>>(basic_istream<charT, traits>& is, path& p) +// + +// TODO(EricWF) This test fails because "std::quoted" fails to compile +// for char16_t and char32_t types. Combine with path.io.pass.cpp when this +// passes. +// XFAIL: * + +#include <experimental/filesystem> +#include <type_traits> +#include <sstream> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +MultiStringType InStr = MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789"); +MultiStringType OutStr = MKSTR("\"abcdefg/\\\"hijklmnop\\\"/qrstuvwxyz/123456789\""); + +template <class CharT> +void doIOTest() { + using namespace fs; + using Ptr = const CharT*; + using StrStream = std::basic_stringstream<CharT>; + const char* const InCStr = InStr; + const Ptr E = OutStr; + const path p((const char*)InStr); + StrStream ss; + { // test output + auto& ret = (ss << p); + assert(ss.str() == E); + assert(&ret == &ss); + } + { // test input + path p_in; + auto& ret = ss >> p_in; + assert(p_in.native() == (const char*)InStr); + assert(&ret == &ss); + } +} + + +int main() { + doIOTest<char16_t>(); + doIOTest<char32_t>(); +} diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/swap.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/swap.pass.cpp new file mode 100644 index 0000000000000..8d180463a5776 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/path.nonmember/swap.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: c++98, c++03 + +// <experimental/filesystem> + +// void swap(path& lhs, path& rhs) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "count_new.hpp" +#include "filesystem_test_helper.hpp" + +namespace fs = std::experimental::filesystem; + +// NOTE: this is tested in path.members/path.modifiers via the member swap. +int main() +{ + using namespace fs; + const char* value1 = "foo/bar/baz"; + const char* value2 = "_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG"; + path p1(value1); + path p2(value2); + { + using namespace std; using namespace fs; + ASSERT_NOEXCEPT(swap(p1, p2)); + ASSERT_SAME_TYPE(void, decltype(swap(p1, p2))); + } + { + DisableAllocationGuard g; + using namespace std; + using namespace fs; + swap(p1, p2); + assert(p1.native() == value2); + assert(p2.native() == value1); + swap(p1, p2); + assert(p1.native() == value1); + assert(p2.native() == value2); + } +} diff --git a/test/std/experimental/filesystem/class.path/synop.pass.cpp b/test/std/experimental/filesystem/class.path/synop.pass.cpp new file mode 100644 index 0000000000000..b0a7b5cd65e21 --- /dev/null +++ b/test/std/experimental/filesystem/class.path/synop.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class path + +// typedef ... value_type; +// typedef basic_string<value_type> string_type; +// static constexpr value_type preferred_separator = ...; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +int main() { + using namespace fs; + ASSERT_SAME_TYPE(path::value_type, char); + ASSERT_SAME_TYPE(path::string_type, std::basic_string<path::value_type>); + { + ASSERT_SAME_TYPE(const path::value_type, decltype(path::preferred_separator)); + static_assert(path::preferred_separator == '/', ""); + // Make preferred_separator ODR used by taking it's address. + const char* dummy = &path::preferred_separator; + ((void)dummy); + } +} diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp new file mode 100644 index 0000000000000..4dbd599e543a3 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// recursive_recursive_directory_iterator(recursive_recursive_directory_iterator const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_copy_construct_tests) + +TEST_CASE(test_constructor_signature) +{ + using D = recursive_directory_iterator; + static_assert(std::is_copy_constructible<D>::value, ""); + //static_assert(!std::is_nothrow_copy_constructible<D>::value, ""); +} + +TEST_CASE(test_copy_end_iterator) +{ + const recursive_directory_iterator endIt; + recursive_directory_iterator it(endIt); + TEST_CHECK(it == endIt); +} + +TEST_CASE(test_copy_valid_iterator) +{ + const path testDir = StaticEnv::Dir; + const recursive_directory_iterator endIt{}; + + // build 'it' up with "interesting" non-default state so we can test + // that it gets copied. We want to get 'it' into a state such that: + // it.options() != directory_options::none + // it.depth() != 0 + // it.recursion_pending() != true + const directory_options opts = directory_options::skip_permission_denied; + recursive_directory_iterator it(testDir, opts); + TEST_REQUIRE(it != endIt); + while (it.depth() == 0) { + ++it; + TEST_REQUIRE(it != endIt); + } + it.disable_recursion_pending(); + TEST_CHECK(it.options() == opts); + TEST_CHECK(it.depth() == 1); + TEST_CHECK(it.recursion_pending() == false); + const path entry = *it; + + // OPERATION UNDER TEST // + const recursive_directory_iterator it2(it); + // ------------------- // + + TEST_REQUIRE(it2 == it); + TEST_CHECK(*it2 == entry); + TEST_CHECK(it2.depth() == 1); + TEST_CHECK(it2.recursion_pending() == false); + TEST_CHECK(it != endIt); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp new file mode 100644 index 0000000000000..3e9257eac8fa1 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/copy_assign.pass.cpp @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// recursive_directory_iterator& operator=(recursive_directory_iterator const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_copy_assign_tests) + +recursive_directory_iterator createInterestingIterator() + // Create an "interesting" iterator where all fields are + // in a non-default state. The returned 'it' is in a + // state such that: + // it.options() == directory_options::skip_permission_denied + // it.depth() == 1 + // it.recursion_pending() == true +{ + const path testDir = StaticEnv::Dir; + const recursive_directory_iterator endIt; + recursive_directory_iterator it(testDir, + directory_options::skip_permission_denied); + TEST_ASSERT(it != endIt); + while (it.depth() != 1) { + ++it; + TEST_ASSERT(it != endIt); + } + TEST_ASSERT(it.depth() == 1); + it.disable_recursion_pending(); + return it; +} + + +recursive_directory_iterator createDifferentInterestingIterator() + // Create an "interesting" iterator where all fields are + // in a non-default state. The returned 'it' is in a + // state such that: + // it.options() == directory_options::follow_directory_symlink + // it.depth() == 2 + // it.recursion_pending() == false +{ + const path testDir = StaticEnv::Dir; + const recursive_directory_iterator endIt; + recursive_directory_iterator it(testDir, + directory_options::follow_directory_symlink); + TEST_ASSERT(it != endIt); + while (it.depth() != 2) { + ++it; + TEST_ASSERT(it != endIt); + } + TEST_ASSERT(it.depth() == 2); + return it; +} + +TEST_CASE(test_assignment_signature) { + using D = recursive_directory_iterator; + static_assert(std::is_copy_assignable<D>::value, ""); +} + +TEST_CASE(test_copy_to_end_iterator) +{ + const recursive_directory_iterator endIt; + + const recursive_directory_iterator from = createInterestingIterator(); + const path entry = *from; + + recursive_directory_iterator to; + to = from; + TEST_REQUIRE(to == from); + TEST_CHECK(*to == entry); + TEST_CHECK(to.options() == from.options()); + TEST_CHECK(to.depth() == from.depth()); + TEST_CHECK(to.recursion_pending() == from.recursion_pending()); +} + + +TEST_CASE(test_copy_from_end_iterator) +{ + const recursive_directory_iterator from; + recursive_directory_iterator to = createInterestingIterator(); + + to = from; + TEST_REQUIRE(to == from); + TEST_CHECK(to == recursive_directory_iterator{}); +} + +TEST_CASE(test_copy_valid_iterator) +{ + const recursive_directory_iterator endIt; + + const recursive_directory_iterator it = createInterestingIterator(); + const path entry = *it; + + recursive_directory_iterator it2 = createDifferentInterestingIterator(); + TEST_REQUIRE(it2 != it); + TEST_CHECK(it2.options() != it.options()); + TEST_CHECK(it2.depth() != it.depth()); + TEST_CHECK(it2.recursion_pending() != it.recursion_pending()); + TEST_CHECK(*it2 != entry); + + it2 = it; + TEST_REQUIRE(it2 == it); + TEST_CHECK(it2.options() == it.options()); + TEST_CHECK(it2.depth() == it.depth()); + TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); + TEST_CHECK(*it2 == entry); +} + +TEST_CASE(test_returns_reference_to_self) +{ + const recursive_directory_iterator it; + recursive_directory_iterator it2; + recursive_directory_iterator& ref = (it2 = it); + TEST_CHECK(&ref == &it2); +} + +TEST_CASE(test_self_copy) +{ + // Create two non-equal iterators that have exactly the same state. + recursive_directory_iterator it = createInterestingIterator(); + recursive_directory_iterator it2 = createInterestingIterator(); + TEST_CHECK(it != it2); + TEST_CHECK(it2.options() == it.options()); + TEST_CHECK(it2.depth() == it.depth()); + TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); + TEST_CHECK(*it2 == *it); + + // perform a self-copy and check that the state still matches the + // other unmodified iterator. + recursive_directory_iterator const& cit = it; + it = cit; + TEST_CHECK(it2.options() == it.options()); + TEST_CHECK(it2.depth() == it.depth()); + TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); + TEST_CHECK(*it2 == *it); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp new file mode 100644 index 0000000000000..1cddccd0d7245 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp @@ -0,0 +1,240 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class directory_iterator + +// +// explicit recursive_directory_iterator(const path& p); +// recursive_directory_iterator(const path& p, directory_options options); +// recursive_directory_iterator(const path& p, error_code& ec) noexcept; +// recursive_directory_iterator(const path& p, directory_options options, error_code& ec) noexcept; + + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +using RDI = recursive_directory_iterator; + +TEST_SUITE(recursive_directory_iterator_constructor_tests) + +TEST_CASE(test_constructor_signatures) +{ + using D = recursive_directory_iterator; + + // explicit directory_iterator(path const&); + static_assert(!std::is_convertible<path, D>::value, ""); + static_assert(std::is_constructible<D, path>::value, ""); + static_assert(!std::is_nothrow_constructible<D, path>::value, ""); + + // directory_iterator(path const&, error_code&) noexcept + static_assert(std::is_nothrow_constructible<D, path, std::error_code&>::value, ""); + + // directory_iterator(path const&, directory_options); + static_assert(std::is_constructible<D, path, directory_options>::value, ""); + static_assert(!std::is_nothrow_constructible<D, path, directory_options>::value, ""); + + // directory_iterator(path const&, directory_options, error_code&) noexcept + static_assert(std::is_nothrow_constructible<D, path, directory_options, std::error_code&>::value, ""); +} + +TEST_CASE(test_construction_from_bad_path) +{ + std::error_code ec; + directory_options opts = directory_options::none; + const RDI endIt; + + const path testPaths[] = { StaticEnv::DNE, StaticEnv::BadSymlink }; + for (path const& testPath : testPaths) + { + { + RDI it(testPath, ec); + TEST_CHECK(ec); + TEST_CHECK(it == endIt); + } + { + RDI it(testPath, opts, ec); + TEST_CHECK(ec); + TEST_CHECK(it == endIt); + } + { + TEST_CHECK_THROW(filesystem_error, RDI(testPath)); + TEST_CHECK_THROW(filesystem_error, RDI(testPath, opts)); + } + } +} + +TEST_CASE(access_denied_test_case) +{ + using namespace std::experimental::filesystem; + scoped_test_env env; + path const testDir = env.make_env_path("dir1"); + path const testFile = testDir / "testFile"; + env.create_dir(testDir); + env.create_file(testFile, 42); + + // Test that we can iterator over the directory before changing the perms + RDI it(testDir); + TEST_REQUIRE(it != RDI{}); + + // Change the permissions so we can no longer iterate + permissions(testDir, perms::none); + + // Check that the construction fails when skip_permissions_denied is + // not given. + { + std::error_code ec; + RDI it(testDir, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == RDI{}); + } + // Check that construction does not report an error when + // 'skip_permissions_denied' is given. + { + std::error_code ec; + RDI it(testDir, directory_options::skip_permission_denied, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it == RDI{}); + } +} + + +TEST_CASE(access_denied_to_file_test_case) +{ + using namespace std::experimental::filesystem; + scoped_test_env env; + path const testFile = env.make_env_path("file1"); + env.create_file(testFile, 42); + + // Change the permissions so we can no longer iterate + permissions(testFile, perms::none); + + // Check that the construction fails when skip_permissions_denied is + // not given. + { + std::error_code ec; + RDI it(testFile, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == RDI{}); + } + // Check that construction still fails when 'skip_permissions_denied' is given + // because we tried to open a file and not a directory. + { + std::error_code ec; + RDI it(testFile, directory_options::skip_permission_denied, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == RDI{}); + } +} + +TEST_CASE(test_open_on_empty_directory_equals_end) +{ + scoped_test_env env; + const path testDir = env.make_env_path("dir1"); + env.create_dir(testDir); + + const RDI endIt; + { + std::error_code ec; + RDI it(testDir, ec); + TEST_CHECK(!ec); + TEST_CHECK(it == endIt); + } + { + RDI it(testDir); + TEST_CHECK(it == endIt); + } +} + +TEST_CASE(test_open_on_directory_succeeds) +{ + const path testDir = StaticEnv::Dir; + std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList), + std::end( StaticEnv::DirIterationList)); + const RDI endIt{}; + + { + std::error_code ec; + RDI it(testDir, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it != endIt); + TEST_CHECK(dir_contents.count(*it)); + } + { + RDI it(testDir); + TEST_CHECK(it != endIt); + TEST_CHECK(dir_contents.count(*it)); + } +} + +TEST_CASE(test_open_on_file_fails) +{ + const path testFile = StaticEnv::File; + const RDI endIt{}; + { + std::error_code ec; + RDI it(testFile, ec); + TEST_REQUIRE(ec); + TEST_CHECK(it == endIt); + } + { + TEST_CHECK_THROW(filesystem_error, RDI(testFile)); + } +} + +TEST_CASE(test_options_post_conditions) +{ + const path goodDir = StaticEnv::Dir; + const path badDir = StaticEnv::DNE; + + { + std::error_code ec; + + RDI it1(goodDir, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it1.options() == directory_options::none); + + RDI it2(badDir, ec); + TEST_REQUIRE(ec); + TEST_REQUIRE(it2 == RDI{}); + } + { + std::error_code ec; + const directory_options opts = directory_options::skip_permission_denied; + + RDI it1(goodDir, opts, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it1.options() == opts); + + RDI it2(badDir, opts, ec); + TEST_REQUIRE(ec); + TEST_REQUIRE(it2 == RDI{}); + } + { + RDI it(goodDir); + TEST_CHECK(it.options() == directory_options::none); + } + { + const directory_options opts = directory_options::follow_directory_symlink; + RDI it(goodDir, opts); + TEST_CHECK(it.options() == opts); + } +} +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp new file mode 100644 index 0000000000000..676e6f27c886b --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/depth.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// int depth() const + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_depth_tests) + +TEST_CASE(test_depth) +{ + const path testDir = StaticEnv::Dir; + const path DirDepth1 = StaticEnv::Dir2; + const path DirDepth2 = StaticEnv::Dir3; + const recursive_directory_iterator endIt{}; + + std::error_code ec; + recursive_directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(it.depth() == 0); + + bool seen_d1, seen_d2; + seen_d1 = seen_d2 = false; + + while (it != endIt) { + const path entry = *it; + const path parent = entry.parent_path(); + if (parent == testDir) { + TEST_CHECK(it.depth() == 0); + } else if (parent == DirDepth1) { + TEST_CHECK(it.depth() == 1); + seen_d1 = true; + } else if (parent == DirDepth2) { + TEST_CHECK(it.depth() == 2); + seen_d2 = true; + } else { + TEST_CHECK(!"Unexpected depth while iterating over static env"); + } + ++it; + } + TEST_REQUIRE(seen_d1 && seen_d2); + TEST_CHECK(it == endIt); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.pass.cpp new file mode 100644 index 0000000000000..387c6145b6a50 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/disable_recursion_pending.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// void disable_recursion_pending(); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_disable_recursion_pending_tests) + +// NOTE: The main semantics of disable_recursion_pending are tested +// in the 'recursion_pending()' tests. +TEST_CASE(basic_test) +{ + recursive_directory_iterator it(StaticEnv::Dir); + TEST_REQUIRE(it.recursion_pending() == true); + it.disable_recursion_pending(); + TEST_CHECK(it.recursion_pending() == false); + it.disable_recursion_pending(); + TEST_CHECK(it.recursion_pending() == false); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp new file mode 100644 index 0000000000000..e67fc2f20f6ef --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp @@ -0,0 +1,240 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// recursive_directory_iterator& operator++(); +// recursive_directory_iterator& increment(error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" +#include <iostream> + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_increment_tests) + +TEST_CASE(test_increment_signatures) +{ + using D = recursive_directory_iterator; + recursive_directory_iterator d; ((void)d); + std::error_code ec; ((void)ec); + + ASSERT_SAME_TYPE(decltype(++d), recursive_directory_iterator&); + ASSERT_NOT_NOEXCEPT(++d); + + ASSERT_SAME_TYPE(decltype(d.increment(ec)), recursive_directory_iterator&); + ASSERT_NOEXCEPT(d.increment(ec)); +} + +TEST_CASE(test_prefix_increment) +{ + const path testDir = StaticEnv::Dir; + const std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList), + std::end( StaticEnv::RecDirIterationList)); + const recursive_directory_iterator endIt{}; + + std::error_code ec; + recursive_directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + recursive_directory_iterator& it_ref = ++it; + TEST_CHECK(&it_ref == &it); + } + + TEST_CHECK(it == endIt); +} + +TEST_CASE(test_postfix_increment) +{ + const path testDir = StaticEnv::Dir; + const std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList), + std::end( StaticEnv::RecDirIterationList)); + const recursive_directory_iterator endIt{}; + + std::error_code ec; + recursive_directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + const path entry2 = *it++; + TEST_CHECK(entry2 == entry); + } + TEST_CHECK(it == endIt); +} + + +TEST_CASE(test_increment_method) +{ + const path testDir = StaticEnv::Dir; + const std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList), + std::end( StaticEnv::RecDirIterationList)); + const recursive_directory_iterator endIt{}; + + std::error_code ec; + recursive_directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + recursive_directory_iterator& it_ref = it.increment(ec); + TEST_REQUIRE(!ec); + TEST_CHECK(&it_ref == &it); + } + + TEST_CHECK(it == endIt); +} + +TEST_CASE(test_follow_symlinks) +{ + const path testDir = StaticEnv::Dir; + auto const& IterList = StaticEnv::RecDirFollowSymlinksIterationList; + + const std::set<path> dir_contents(std::begin(IterList), std::end(IterList)); + const recursive_directory_iterator endIt{}; + + std::error_code ec; + recursive_directory_iterator it(testDir, + directory_options::follow_directory_symlink, ec); + TEST_REQUIRE(!ec); + + std::set<path> unseen_entries = dir_contents; + while (!unseen_entries.empty()) { + TEST_REQUIRE(it != endIt); + const path entry = *it; + + TEST_REQUIRE(unseen_entries.erase(entry) == 1); + recursive_directory_iterator& it_ref = it.increment(ec); + TEST_REQUIRE(!ec); + TEST_CHECK(&it_ref == &it); + } + TEST_CHECK(it == endIt); +} + +TEST_CASE(access_denied_on_recursion_test_case) +{ + using namespace std::experimental::filesystem; + scoped_test_env env; + const path testFiles[] = { + env.create_dir("dir1"), + env.create_dir("dir1/dir2"), + env.create_file("dir1/dir2/file1"), + env.create_file("dir1/file2") + }; + const path startDir = testFiles[0]; + const path permDeniedDir = testFiles[1]; + const path otherFile = testFiles[3]; + auto SkipEPerm = directory_options::skip_permission_denied; + + // Change the permissions so we can no longer iterate + permissions(permDeniedDir, perms::none); + + const recursive_directory_iterator endIt; + + // Test that recursion resulting in a "EACCESS" error is not ignored + // by default. + { + std::error_code ec = GetTestEC(); + recursive_directory_iterator it(startDir, ec); + TEST_REQUIRE(ec != GetTestEC()); + TEST_REQUIRE(!ec); + while (it != endIt && it->path() != permDeniedDir) + ++it; + TEST_REQUIRE(it != endIt); + TEST_REQUIRE(*it == permDeniedDir); + + it.increment(ec); + TEST_CHECK(ec); + TEST_CHECK(it == endIt); + } + // Same as obove but test operator++(). + { + std::error_code ec = GetTestEC(); + recursive_directory_iterator it(startDir, ec); + TEST_REQUIRE(!ec); + while (it != endIt && it->path() != permDeniedDir) + ++it; + TEST_REQUIRE(it != endIt); + TEST_REQUIRE(*it == permDeniedDir); + + TEST_REQUIRE_THROW(filesystem_error, ++it); + } + // Test that recursion resulting in a "EACCESS" error is ignored when the + // correct options are given to the constructor. + { + std::error_code ec = GetTestEC(); + recursive_directory_iterator it(startDir, SkipEPerm, ec); + TEST_REQUIRE(!ec); + TEST_REQUIRE(it != endIt); + + bool seenOtherFile = false; + if (*it == otherFile) { + ++it; + seenOtherFile = true; + TEST_REQUIRE (it != endIt); + } + TEST_REQUIRE(*it == permDeniedDir); + + ec = GetTestEC(); + it.increment(ec); + TEST_REQUIRE(!ec); + + if (seenOtherFile) { + TEST_CHECK(it == endIt); + } else { + TEST_CHECK(it != endIt); + TEST_CHECK(*it == otherFile); + } + } + // Test that construction resulting in a "EACCESS" error is not ignored + // by default. + { + std::error_code ec; + recursive_directory_iterator it(permDeniedDir, ec); + TEST_REQUIRE(ec); + TEST_REQUIRE(it == endIt); + } + // Same as obove but testing the throwing constructors + { + TEST_REQUIRE_THROW(filesystem_error, + recursive_directory_iterator(permDeniedDir)); + } + // Test that construction resulting in a "EACCESS" error constructs the + // end iterator when the correct options are given. + { + std::error_code ec = GetTestEC(); + recursive_directory_iterator it(permDeniedDir, SkipEPerm, ec); + TEST_REQUIRE(!ec); + TEST_REQUIRE(it == endIt); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move.pass.cpp new file mode 100644 index 0000000000000..16dde66d216ea --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move.pass.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// recursive_directory_iterator(recursive_directory_iterator&&) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_move_construct_tests) + +TEST_CASE(test_constructor_signature) +{ + using D = recursive_directory_iterator; + static_assert(std::is_nothrow_move_constructible<D>::value, ""); +} + +TEST_CASE(test_move_end_iterator) +{ + const recursive_directory_iterator endIt; + recursive_directory_iterator endIt2{}; + + recursive_directory_iterator it(std::move(endIt2)); + TEST_CHECK(it == endIt); + TEST_CHECK(endIt2 == endIt); +} + +TEST_CASE(test_move_valid_iterator) +{ + const path testDir = StaticEnv::Dir; + const recursive_directory_iterator endIt{}; + + // build 'it' up with "interesting" non-default state so we can test + // that it gets copied. We want to get 'it' into a state such that: + // it.options() != directory_options::none + // it.depth() != 0 + // it.recursion_pending() != true + const directory_options opts = directory_options::skip_permission_denied; + recursive_directory_iterator it(testDir, opts); + TEST_REQUIRE(it != endIt); + while (it.depth() == 0) { + ++it; + TEST_REQUIRE(it != endIt); + } + it.disable_recursion_pending(); + TEST_CHECK(it.options() == opts); + TEST_CHECK(it.depth() == 1); + TEST_CHECK(it.recursion_pending() == false); + const path entry = *it; + + // OPERATION UNDER TEST // + const recursive_directory_iterator it2(std::move(it)); + // ------------------- // + + TEST_REQUIRE(it2 != endIt); + TEST_CHECK(*it2 == entry); + TEST_CHECK(it2.depth() == 1); + TEST_CHECK(it2.recursion_pending() == false); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp new file mode 100644 index 0000000000000..915d00267a828 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/move_assign.pass.cpp @@ -0,0 +1,169 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// recursive_directory_iterator& operator=(recursive_directory_iterator const&); + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +// The filesystem specification explicitly allows for self-move on +// the directory iterators. Turn off this warning so we can test it. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wself-move" +#endif + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_move_assign_tests) + +recursive_directory_iterator createInterestingIterator() + // Create an "interesting" iterator where all fields are + // in a non-default state. The returned 'it' is in a + // state such that: + // it.options() == directory_options::skip_permission_denied + // it.depth() == 1 + // it.recursion_pending() == true +{ + const path testDir = StaticEnv::Dir; + const recursive_directory_iterator endIt; + recursive_directory_iterator it(testDir, + directory_options::skip_permission_denied); + TEST_ASSERT(it != endIt); + while (it.depth() != 1) { + ++it; + TEST_ASSERT(it != endIt); + } + TEST_ASSERT(it.depth() == 1); + it.disable_recursion_pending(); + return it; +} + +recursive_directory_iterator createDifferentInterestingIterator() + // Create an "interesting" iterator where all fields are + // in a non-default state. The returned 'it' is in a + // state such that: + // it.options() == directory_options::follow_directory_symlink + // it.depth() == 2 + // it.recursion_pending() == false +{ + const path testDir = StaticEnv::Dir; + const recursive_directory_iterator endIt; + recursive_directory_iterator it(testDir, + directory_options::follow_directory_symlink); + TEST_ASSERT(it != endIt); + while (it.depth() != 2) { + ++it; + TEST_ASSERT(it != endIt); + } + TEST_ASSERT(it.depth() == 2); + return it; +} + + +TEST_CASE(test_assignment_signature) +{ + using D = recursive_directory_iterator; + static_assert(std::is_nothrow_move_assignable<D>::value, ""); +} + + +TEST_CASE(test_move_to_end_iterator) +{ + const recursive_directory_iterator endIt; + + recursive_directory_iterator from = createInterestingIterator(); + const recursive_directory_iterator from_copy(from); + const path entry = *from; + + recursive_directory_iterator to; + to = std::move(from); + TEST_REQUIRE(to != endIt); + TEST_CHECK(*to == entry); + TEST_CHECK(to.options() == from_copy.options()); + TEST_CHECK(to.depth() == from_copy.depth()); + TEST_CHECK(to.recursion_pending() == from_copy.recursion_pending()); + TEST_CHECK(from == endIt || from == to); +} + + +TEST_CASE(test_move_from_end_iterator) +{ + recursive_directory_iterator from; + recursive_directory_iterator to = createInterestingIterator(); + + to = std::move(from); + TEST_REQUIRE(to == from); + TEST_CHECK(to == recursive_directory_iterator{}); +} + +TEST_CASE(test_move_valid_iterator) +{ + const recursive_directory_iterator endIt; + + recursive_directory_iterator it = createInterestingIterator(); + const recursive_directory_iterator it_copy(it); + const path entry = *it; + + recursive_directory_iterator it2 = createDifferentInterestingIterator(); + const recursive_directory_iterator it2_copy(it2); + TEST_REQUIRE(it2 != it); + TEST_CHECK(it2.options() != it.options()); + TEST_CHECK(it2.depth() != it.depth()); + TEST_CHECK(it2.recursion_pending() != it.recursion_pending()); + TEST_CHECK(*it2 != entry); + + it2 = std::move(it); + TEST_REQUIRE(it2 != it2_copy && it2 != endIt); + TEST_CHECK(it2.options() == it_copy.options()); + TEST_CHECK(it2.depth() == it_copy.depth()); + TEST_CHECK(it2.recursion_pending() == it_copy.recursion_pending()); + TEST_CHECK(*it2 == entry); + TEST_CHECK(it == endIt || it == it2); +} + +TEST_CASE(test_returns_reference_to_self) +{ + recursive_directory_iterator it; + recursive_directory_iterator it2; + recursive_directory_iterator& ref = (it2 = std::move(it)); + TEST_CHECK(&ref == &it2); +} + +TEST_CASE(test_self_move) +{ + // Create two non-equal iterators that have exactly the same state. + recursive_directory_iterator it = createInterestingIterator(); + recursive_directory_iterator it2 = createInterestingIterator(); + TEST_CHECK(it != it2); + TEST_CHECK(it2.options() == it.options()); + TEST_CHECK(it2.depth() == it.depth()); + TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); + TEST_CHECK(*it2 == *it); + + it = std::move(it); + TEST_CHECK(it2.options() == it.options()); + TEST_CHECK(it2.depth() == it.depth()); + TEST_CHECK(it2.recursion_pending() == it.recursion_pending()); + TEST_CHECK(*it2 == *it); +} + + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp new file mode 100644 index 0000000000000..befa30484c0c3 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/pop.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// void pop(); +// void pop(error_code& ec); + +#include <experimental/filesystem> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_pop_tests) + +TEST_CASE(signature_tests) +{ + recursive_directory_iterator it{}; ((void)it); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(it.pop()); + ASSERT_NOT_NOEXCEPT(it.pop(ec)); // may require allocation or other things +} + +// NOTE: Since the order of iteration is unspecified we use a list of +// seen files at each depth to determine the new depth after a 'pop()' operation. +TEST_CASE(test_depth) +{ + const recursive_directory_iterator endIt{}; + + auto& DE0 = StaticEnv::DirIterationList; + std::set<path> notSeenDepth0(std::begin(DE0), std::end(DE0)); + + auto& DE1 = StaticEnv::DirIterationListDepth1; + std::set<path> notSeenDepth1(std::begin(DE1), std::end(DE1)); + + std::error_code ec; + recursive_directory_iterator it(StaticEnv::Dir, ec); + TEST_REQUIRE(it != endIt); + TEST_CHECK(it.depth() == 0); + + while (it.depth() != 2) { + if (it.depth() == 0) + notSeenDepth0.erase(it->path()); + else + notSeenDepth1.erase(it->path()); + ++it; + TEST_REQUIRE(it != endIt); + } + + while (true) { + auto set_ec = std::make_error_code(std::errc::address_in_use); + it.pop(set_ec); + TEST_REQUIRE(!set_ec); + + if (it == endIt) { + // We must have seen every entry at depth 0 and 1. + TEST_REQUIRE(notSeenDepth0.empty() && notSeenDepth1.empty()); + break; + } + else if (it.depth() == 1) { + // If we popped to depth 1 then there must be unseen entries + // at this level. + TEST_REQUIRE(!notSeenDepth1.empty()); + TEST_CHECK(notSeenDepth1.count(it->path())); + notSeenDepth1.clear(); + } + else if (it.depth() == 0) { + // If we popped to depth 0 there must be unseen entries at this + // level. There should also be no unseen entries at depth 1. + TEST_REQUIRE(!notSeenDepth0.empty()); + TEST_REQUIRE(notSeenDepth1.empty()); + TEST_CHECK(notSeenDepth0.count(it->path())); + notSeenDepth0.clear(); + } + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp new file mode 100644 index 0000000000000..5a3bdd9d482bb --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/recursion_pending.pass.cpp @@ -0,0 +1,162 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// bool recursion_pending() const; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_recursion_pending_tests) + +TEST_CASE(initial_value_test) +{ + recursive_directory_iterator it(StaticEnv::Dir); + TEST_REQUIRE(it.recursion_pending() == true); +} + +TEST_CASE(value_after_copy_construction_and_assignment_test) +{ + recursive_directory_iterator rec_pending_it(StaticEnv::Dir); + recursive_directory_iterator no_rec_pending_it(StaticEnv::Dir); + no_rec_pending_it.disable_recursion_pending(); + + { // copy construction + recursive_directory_iterator it(rec_pending_it); + TEST_CHECK(it.recursion_pending() == true); + it.disable_recursion_pending(); + TEST_REQUIRE(rec_pending_it.recursion_pending() == true); + + recursive_directory_iterator it2(no_rec_pending_it); + TEST_CHECK(it2.recursion_pending() == false); + } + { // copy assignment + recursive_directory_iterator it(StaticEnv::Dir); + it.disable_recursion_pending(); + it = rec_pending_it; + TEST_CHECK(it.recursion_pending() == true); + it.disable_recursion_pending(); + TEST_REQUIRE(rec_pending_it.recursion_pending() == true); + + recursive_directory_iterator it2(StaticEnv::Dir); + it2 = no_rec_pending_it; + TEST_CHECK(it2.recursion_pending() == false); + } + TEST_CHECK(rec_pending_it.recursion_pending() == true); + TEST_CHECK(no_rec_pending_it.recursion_pending() == false); +} + + +TEST_CASE(value_after_move_construction_and_assignment_test) +{ + recursive_directory_iterator rec_pending_it(StaticEnv::Dir); + recursive_directory_iterator no_rec_pending_it(StaticEnv::Dir); + no_rec_pending_it.disable_recursion_pending(); + + { // move construction + recursive_directory_iterator it_cp(rec_pending_it); + recursive_directory_iterator it(std::move(it_cp)); + TEST_CHECK(it.recursion_pending() == true); + + recursive_directory_iterator it_cp2(no_rec_pending_it); + recursive_directory_iterator it2(std::move(it_cp2)); + TEST_CHECK(it2.recursion_pending() == false); + } + { // copy assignment + recursive_directory_iterator it(StaticEnv::Dir); + it.disable_recursion_pending(); + recursive_directory_iterator it_cp(rec_pending_it); + it = std::move(it_cp); + TEST_CHECK(it.recursion_pending() == true); + + recursive_directory_iterator it2(StaticEnv::Dir); + recursive_directory_iterator it_cp2(no_rec_pending_it); + it2 = std::move(it_cp2); + TEST_CHECK(it2.recursion_pending() == false); + } + TEST_CHECK(rec_pending_it.recursion_pending() == true); + TEST_CHECK(no_rec_pending_it.recursion_pending() == false); +} + +TEST_CASE(increment_resets_value) +{ + const recursive_directory_iterator endIt; + { + recursive_directory_iterator it(StaticEnv::Dir); + it.disable_recursion_pending(); + TEST_CHECK(it.recursion_pending() == false); + ++it; + TEST_CHECK(it.recursion_pending() == true); + TEST_CHECK(it.depth() == 0); + } + { + recursive_directory_iterator it(StaticEnv::Dir); + it.disable_recursion_pending(); + TEST_CHECK(it.recursion_pending() == false); + it++; + TEST_CHECK(it.recursion_pending() == true); + TEST_CHECK(it.depth() == 0); + } + { + recursive_directory_iterator it(StaticEnv::Dir); + it.disable_recursion_pending(); + TEST_CHECK(it.recursion_pending() == false); + std::error_code ec; + it.increment(ec); + TEST_CHECK(it.recursion_pending() == true); + TEST_CHECK(it.depth() == 0); + } +} + +TEST_CASE(pop_does_not_reset_value) +{ + const recursive_directory_iterator endIt; + + auto& DE0 = StaticEnv::DirIterationList; + std::set<path> notSeenDepth0(std::begin(DE0), std::end(DE0)); + + recursive_directory_iterator it(StaticEnv::Dir); + TEST_REQUIRE(it != endIt); + + while (it.depth() == 0) { + notSeenDepth0.erase(it->path()); + ++it; + TEST_REQUIRE(it != endIt); + } + TEST_REQUIRE(it.depth() == 1); + it.disable_recursion_pending(); + it.pop(); + // Since the order of iteration is unspecified the pop() could result + // in the end iterator. When this is the case it is undefined behavior + // to call recursion_pending(). + if (it == endIt) { + TEST_CHECK(notSeenDepth0.empty()); +#if defined(_LIBCPP_VERSION) + TEST_CHECK(it.recursion_pending() == false); +#endif + } else { + TEST_CHECK(! notSeenDepth0.empty()); + TEST_CHECK(it.recursion_pending() == false); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp new file mode 100644 index 0000000000000..ca5117f0e32f3 --- /dev/null +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// class recursive_directory_iterator + +// recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; +// recursive_directory_iterator end(recursive_directory_iterator iter) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <set> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" +#include <iostream> + +using namespace std::experimental::filesystem; + +TEST_SUITE(recursive_directory_iterator_begin_end_tests) + +TEST_CASE(test_function_signatures) +{ + using D = recursive_directory_iterator; + recursive_directory_iterator d; ((void)d); + + ASSERT_SAME_TYPE(decltype(begin(d)), recursive_directory_iterator); + ASSERT_NOEXCEPT(begin(std::move(d))); + + ASSERT_SAME_TYPE(decltype(end(d)), recursive_directory_iterator); + ASSERT_NOEXCEPT(end(std::move(d))); +} + +TEST_CASE(test_ranged_for_loop) +{ + const path testDir = StaticEnv::Dir; + std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList), + std::end( StaticEnv::RecDirIterationList)); + + std::error_code ec; + recursive_directory_iterator it(testDir, ec); + TEST_REQUIRE(!ec); + + for (auto& elem : it) { + TEST_CHECK(dir_contents.erase(elem) == 1); + } + TEST_CHECK(dir_contents.empty()); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.enum/check_bitmask_types.hpp b/test/std/experimental/filesystem/fs.enum/check_bitmask_types.hpp new file mode 100644 index 0000000000000..77b136f3fcad9 --- /dev/null +++ b/test/std/experimental/filesystem/fs.enum/check_bitmask_types.hpp @@ -0,0 +1,75 @@ +#ifndef TEST_BITMASK_TYPE_HPP +#define TEST_BITMASK_TYPE_HPP + +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + + +template <class EnumType, EnumType Val1, EnumType Val2, + class UT = typename std::underlying_type<EnumType>::type, + UT UVal1 = static_cast<UT>(Val1), + UT UVal2 = static_cast<UT>(Val2), + UT UZero = static_cast<UT>(0), + EnumType Zero = static_cast<EnumType>(0) + > +struct check_bitmask_type { + + static constexpr UT dcast(EnumType e) { return static_cast<UT>(e); } + static constexpr UT unpromote(decltype((~UZero)) promoted) { return static_cast<UT>(promoted); } + // We need two values that are non-zero and share at least one bit. + static_assert(Val1 != Zero && Val2 != Zero, ""); + static_assert(Val1 != Val2, ""); + static_assert((UVal1 & UVal2) == 0, ""); + + + static bool check() + { + { + EnumType ValRef = Val1; + ASSERT_SAME_TYPE(EnumType, decltype(Val1 & Val2)); + ASSERT_SAME_TYPE(EnumType, decltype(Val1 | Val2)); + ASSERT_SAME_TYPE(EnumType, decltype(Val1 ^ Val2)); + ASSERT_SAME_TYPE(EnumType, decltype((~Val1))); + ASSERT_SAME_TYPE(EnumType&, decltype(ValRef &= Val2)); + ASSERT_SAME_TYPE(EnumType&, decltype(ValRef |= Val2)); + ASSERT_SAME_TYPE(EnumType&, decltype(ValRef ^= Val2)); + } + + static_assert((Val1 & Zero) == Zero, ""); + static_assert((Val1 & Val1) == Val1, ""); + static_assert(dcast(Val1 & Val2) == (UVal1 & UVal2), ""); + + static_assert((Val1 | Zero) == Val1, ""); + static_assert(dcast(Val1 | Val2) == (UVal1 | UVal2), ""); + + static_assert((Val1 ^ Zero) == Val1, ""); + static_assert(dcast(Val1 ^ Val2) == (UVal1 ^ UVal2), ""); + + static_assert(dcast(~Zero) == unpromote(~UZero), ""); + static_assert(dcast(~Val1) == unpromote(~UVal1), ""); + + { + EnumType e = Val1; + EnumType& eref = (e &= Val2); + assert(&eref == &e); + assert(dcast(eref) == (UVal1 & UVal2)); + } + { + EnumType e = Val1; + EnumType& eref = (e |= Val2); + assert(&eref == &e); + assert(dcast(eref) == (UVal1 | UVal2)); + } + { + EnumType e = Val1; + EnumType& eref = (e ^= Val2); + assert(&eref == &e); + assert(dcast(eref) == (UVal1 ^ UVal2)); + } + return true; + } +}; + +#endif // TEST_BITMASK_TYPE diff --git a/test/std/experimental/filesystem/fs.enum/enum.copy_options.pass.cpp b/test/std/experimental/filesystem/fs.enum/enum.copy_options.pass.cpp new file mode 100644 index 0000000000000..22f0cb845a72a --- /dev/null +++ b/test/std/experimental/filesystem/fs.enum/enum.copy_options.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 + +// <experimental/filesystem> + +// enum class copy_options; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "check_bitmask_types.hpp" +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +constexpr fs::copy_options ME(int val) { return static_cast<fs::copy_options>(val); } + +int main() { + typedef fs::copy_options E; + static_assert(std::is_enum<E>::value, ""); + + // Check that E is a scoped enum by checking for conversions. + typedef std::underlying_type<E>::type UT; + static_assert(!std::is_convertible<E, UT>::value, ""); + + static_assert(std::is_same<UT, unsigned short>::value, ""); // Implementation detail + + typedef check_bitmask_type<E, E::skip_existing, E::update_existing> BitmaskTester; + assert(BitmaskTester::check()); + + static_assert( + E::none == ME(0), + "Expected enumeration values do not match"); + // Option group for copy_file + static_assert( + E::skip_existing == ME(1) && + E::overwrite_existing == ME(2) && + E::update_existing == ME(4), + "Expected enumeration values do not match"); + // Option group for copy on directories + static_assert( + E::recursive == ME(8), + "Expected enumeration values do not match"); + // Option group for copy on symlinks + static_assert( + E::copy_symlinks == ME(16) && + E::skip_symlinks == ME(32), + "Expected enumeration values do not match"); + // Option group for changing form of copy + static_assert( + E::directories_only == ME(64) && + E::create_symlinks == ME(128) && + E::create_hard_links == ME(256), + "Expected enumeration values do not match"); +} diff --git a/test/std/experimental/filesystem/fs.enum/enum.directory_options.pass.cpp b/test/std/experimental/filesystem/fs.enum/enum.directory_options.pass.cpp new file mode 100644 index 0000000000000..7dbf7b2887e85 --- /dev/null +++ b/test/std/experimental/filesystem/fs.enum/enum.directory_options.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// enum class directory_options; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> +#include <sys/stat.h> + +#include "test_macros.h" +#include "check_bitmask_types.hpp" + +namespace fs = std::experimental::filesystem; + +constexpr fs::directory_options ME(int val) { return static_cast<fs::directory_options>(val); } + +int main() { + typedef fs::directory_options E; + static_assert(std::is_enum<E>::value, ""); + + // Check that E is a scoped enum by checking for conversions. + typedef std::underlying_type<E>::type UT; + static_assert(!std::is_convertible<E, UT>::value, ""); + static_assert(std::is_same<UT, unsigned char>::value, ""); + + typedef check_bitmask_type<E, E::follow_directory_symlink, E::skip_permission_denied> BitmaskTester; + assert(BitmaskTester::check()); + + static_assert( + E::none == ME(0) && + E::follow_directory_symlink == ME(1) && + E::skip_permission_denied == ME(2), + "Expected enumeration values do not match"); + +} diff --git a/test/std/experimental/filesystem/fs.enum/enum.file_type.pass.cpp b/test/std/experimental/filesystem/fs.enum/enum.file_type.pass.cpp new file mode 100644 index 0000000000000..ab94ad2877aac --- /dev/null +++ b/test/std/experimental/filesystem/fs.enum/enum.file_type.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// enum class file_type; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +namespace fs = std::experimental::filesystem; + +constexpr fs::file_type ME(int val) { return static_cast<fs::file_type>(val); } + +int main() { + typedef fs::file_type E; + static_assert(std::is_enum<E>::value, ""); + + // Check that E is a scoped enum by checking for conversions. + typedef std::underlying_type<E>::type UT; + static_assert(!std::is_convertible<E, UT>::value, ""); + + static_assert(std::is_same<UT, signed char>::value, ""); // Implementation detail + + static_assert( + E::none == ME(0) && + E::not_found == ME(-1) && + E::regular == ME(1) && + E::directory == ME(2) && + E::symlink == ME(3) && + E::block == ME(4) && + E::character == ME(5) && + E::fifo == ME(6) && + E::socket == ME(7) && + E::unknown == ME(8), + "Expected enumeration values do not match"); +} diff --git a/test/std/experimental/filesystem/fs.enum/enum.perms.pass.cpp b/test/std/experimental/filesystem/fs.enum/enum.perms.pass.cpp new file mode 100644 index 0000000000000..c0b14ba4b9b9a --- /dev/null +++ b/test/std/experimental/filesystem/fs.enum/enum.perms.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: c++98, c++03 + +// <experimental/filesystem> + +// enum class perms; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> +#include <sys/stat.h> + +#include "test_macros.h" +#include "check_bitmask_types.hpp" + +namespace fs = std::experimental::filesystem; + +constexpr fs::perms ME(int val) { return static_cast<fs::perms>(val); } + +int main() { + typedef fs::perms E; + static_assert(std::is_enum<E>::value, ""); + + // Check that E is a scoped enum by checking for conversions. + typedef std::underlying_type<E>::type UT; + static_assert(!std::is_convertible<E, UT>::value, ""); + + static_assert(std::is_same<UT, unsigned >::value, ""); // Implementation detail + + typedef check_bitmask_type<E, E::group_all, E::owner_all> BitmaskTester; + assert(BitmaskTester::check()); + + static_assert( + E::none == ME(0) && + + E::owner_read == ME(0400) && + E::owner_write == ME(0200) && + E::owner_exec == ME(0100) && + E::owner_all == ME(0700) && + + E::group_read == ME(040) && + E::group_write == ME(020) && + E::group_exec == ME(010) && + E::group_all == ME(070) && + + E::others_read == ME(04) && + E::others_write == ME(02) && + E::others_exec == ME(01) && + E::others_all == ME(07) && + E::all == ME(0777) && + E::set_uid == ME(04000) && + E::set_gid == ME(02000) && + E::sticky_bit == ME(01000) && + E::mask == ME(07777) && + E::unknown == ME(0xFFFF) && + E::add_perms == ME(0x10000) && + E::remove_perms == ME(0x20000) && + E::symlink_nofollow == ME(0x40000), + "Expected enumeration values do not match"); +} diff --git a/test/std/experimental/filesystem/fs.error.report/tested_elsewhere.pass.cpp b/test/std/experimental/filesystem/fs.error.report/tested_elsewhere.pass.cpp new file mode 100644 index 0000000000000..b58f5c55b643a --- /dev/null +++ b/test/std/experimental/filesystem/fs.error.report/tested_elsewhere.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/experimental/filesystem/fs.filesystem.synopsis/file_time_type.pass.cpp b/test/std/experimental/filesystem/fs.filesystem.synopsis/file_time_type.pass.cpp new file mode 100644 index 0000000000000..d8d92c5888ac6 --- /dev/null +++ b/test/std/experimental/filesystem/fs.filesystem.synopsis/file_time_type.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// typedef TrivialClock file_time_type; + +#include <experimental/filesystem> +#include <chrono> +#include <type_traits> + +// system_clock is used because it meets the requirements of TrivialClock, +// and it's resolution and range of system_clock should match the operating +// systems file time type. +typedef std::chrono::system_clock ExpectedClock; +typedef std::chrono::time_point<ExpectedClock> ExpectedTimePoint; + +int main() { + static_assert(std::is_same< + std::experimental::filesystem::file_time_type, + ExpectedTimePoint + >::value, ""); +} diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp new file mode 100644 index 0000000000000..4d59235c722b8 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// path absolute(const path& p, const path& base=current_path()); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(filesystem_absolute_path_test_suite) + +TEST_CASE(absolute_signature_test) +{ + const path p; ((void)p); + ASSERT_NOT_NOEXCEPT(absolute(p)); + ASSERT_NOT_NOEXCEPT(absolute(p, p)); +} + +// There are 4 cases is the proposal for absolute path. +// Each scope tests one of the cases. +TEST_CASE(absolute_path_test) +{ + // has_root_name() && has_root_directory() + { + const path p("//net/foo"); + const path base("//net/bar/baz"); + TEST_REQUIRE(p.has_root_name()); + TEST_REQUIRE(p.has_root_directory()); + TEST_CHECK(p.is_absolute()); + path ret = absolute(p, base); + TEST_CHECK(ret.is_absolute()); + TEST_CHECK(ret == p); + } + // !has_root_name() && has_root_directory() + { + const path p("/foo"); + const path base("//net/bar"); + TEST_REQUIRE(not p.has_root_name()); + TEST_REQUIRE(p.has_root_directory()); + TEST_CHECK(p.is_absolute()); + // ensure absolute(base) is not recursivly called + TEST_REQUIRE(base.has_root_name()); + TEST_REQUIRE(base.has_root_directory()); + + path ret = absolute(p, base); + TEST_CHECK(ret.is_absolute()); + TEST_CHECK(ret.has_root_name()); + TEST_CHECK(ret.root_name() == path("//net")); + TEST_CHECK(ret.has_root_directory()); + TEST_CHECK(ret.root_directory() == path("/")); + TEST_CHECK(ret == path("//net/foo")); + } + // has_root_name() && !has_root_directory() + { + const path p("//net"); + const path base("//net/foo/bar"); + TEST_REQUIRE(p.has_root_name()); + TEST_REQUIRE(not p.has_root_directory()); + TEST_CHECK(not p.is_absolute()); + // absolute is called recursivly on base. The following conditions + // must be true for it to return base unmodified + TEST_REQUIRE(base.has_root_name()); + TEST_REQUIRE(base.has_root_directory()); + path ret = absolute(p, base); + const path expect("//net/foo/bar"); + TEST_CHECK(ret.is_absolute()); + TEST_CHECK(ret == path("//net/foo/bar")); + } + // !has_root_name() && !has_root_directory() + { + const path p("bar/baz"); + const path base("//net/foo"); + TEST_REQUIRE(not p.has_root_name()); + TEST_REQUIRE(not p.has_root_directory()); + TEST_REQUIRE(base.has_root_name()); + TEST_REQUIRE(base.has_root_directory()); + + path ret = absolute(p, base); + TEST_CHECK(ret.is_absolute()); + TEST_CHECK(ret == path("//net/foo/bar/baz")); + } +} + +TEST_CASE(absolute_path_with_default_base) +{ + const path testCases[] = { + "//net/foo", // has_root_name() && has_root_directory() + "/foo", // !has_root_name() && has_root_directory() + "//net", // has_root_name() && !has_root_directory() + "bar/baz" // !has_root_name() && !has_root_directory() + }; + const path base = current_path(); + for (auto& p : testCases) { + const path ret = absolute(p); + const path expect = absolute(p, base); + TEST_CHECK(ret.is_absolute()); + TEST_CHECK(ret == expect); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp new file mode 100644 index 0000000000000..407f5b111a836 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// path canonical(const path& p, const path& base = current_path()); +// path canonical(const path& p, error_code& ec); +// path canonical(const path& p, const path& base, error_code& ec); + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(filesystem_canonical_path_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(canonical(p)); + ASSERT_NOT_NOEXCEPT(canonical(p, p)); + ASSERT_NOT_NOEXCEPT(canonical(p, ec)); + ASSERT_NOT_NOEXCEPT(canonical(p, p, ec)); +} + +// There are 4 cases is the proposal for absolute path. +// Each scope tests one of the cases. +TEST_CASE(test_canonical) +{ + // has_root_name() && has_root_directory() + const path Root = StaticEnv::Root; + const path RootName = Root.filename(); + const path DirName = StaticEnv::Dir.filename(); + const path SymlinkName = StaticEnv::SymlinkToFile.filename(); + struct TestCase { + path p; + path expect; + path base; + TestCase(path p1, path e, path b = StaticEnv::Root) + : p(p1), expect(e), base(b) {} + }; + const TestCase testCases[] = { + { ".", Root, Root}, + { DirName / ".." / "." / DirName, StaticEnv::Dir, Root}, + { StaticEnv::Dir2 / "..", StaticEnv::Dir }, + { StaticEnv::Dir3 / "../..", StaticEnv::Dir }, + { StaticEnv::Dir / ".", StaticEnv::Dir }, + { Root / "." / DirName / ".." / DirName, StaticEnv::Dir}, + { path("..") / "." / RootName / DirName / ".." / DirName, StaticEnv::Dir, Root}, + { StaticEnv::SymlinkToFile, StaticEnv::File }, + { SymlinkName, StaticEnv::File, StaticEnv::Root} + }; + for (auto& TC : testCases) { + std::error_code ec; + const path ret = canonical(TC.p, TC.base, ec); + TEST_REQUIRE(!ec); + const path ret2 = canonical(TC.p, TC.base); + TEST_CHECK(ret == TC.expect); + TEST_CHECK(ret == ret2); + TEST_CHECK(ret.is_absolute()); + } +} + +TEST_CASE(test_dne_path) +{ + std::error_code ec; + { + const path ret = canonical(StaticEnv::DNE, ec); + TEST_REQUIRE(ec); + TEST_CHECK(ret == path{}); + } + ec.clear(); + { + const path ret = canonical(StaticEnv::DNE, StaticEnv::Root, ec); + TEST_REQUIRE(ec); + TEST_CHECK(ret == path{}); + } + { + TEST_CHECK_THROW(filesystem_error, canonical(StaticEnv::DNE)); + TEST_CHECK_THROW(filesystem_error, canonical(StaticEnv::DNE, StaticEnv::Root)); + } +} + +TEST_CASE(test_exception_contains_paths) +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + const path p = "blabla/dne"; + const path base = StaticEnv::Root; + try { + canonical(p, base); + TEST_REQUIRE(false); + } catch (filesystem_error const& err) { + TEST_CHECK(err.path1() == p); + TEST_CHECK(err.path2() == base); + } + try { + canonical(p); + TEST_REQUIRE(false); + } catch (filesystem_error const& err) { + TEST_CHECK(err.path1() == p); + TEST_CHECK(err.path2() == current_path()); + } +#endif +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp new file mode 100644 index 0000000000000..7d318719f740e --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp @@ -0,0 +1,251 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// void copy(const path& from, const path& to); +// void copy(const path& from, const path& to, error_code& ec) noexcept; +// void copy(const path& from, const path& to, copy_options options); +// void copy(const path& from, const path& to, copy_options options, +// error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +using CO = fs::copy_options; + +TEST_SUITE(filesystem_copy_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + const copy_options opts{}; ((void)opts); + ASSERT_NOT_NOEXCEPT(fs::copy(p, p)); + ASSERT_NOEXCEPT(fs::copy(p, p, ec)); + ASSERT_NOT_NOEXCEPT(copy(p, p, opts)); + ASSERT_NOEXCEPT(copy(p, p, opts, ec)); +} + +// There are 4 cases is the proposal for absolute path. +// Each scope tests one of the cases. +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::copy(f, t); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == t + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path dir = env.create_dir("dir"); + const path fifo = env.create_fifo("fifo"); + TEST_REQUIRE(is_other(fifo)); + + // !exists(f) + { + std::error_code ec; + const path f = StaticEnv::DNE; + const path t = env.test_root; + fs::copy(f, t, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(f, t, ec)); + } + { // equivalent(f, t) == true + std::error_code ec; + fs::copy(file, file, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(file, file, ec)); + } + { // is_directory(from) && is_file(to) + std::error_code ec; + fs::copy(dir, file, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(dir, file, ec)); + } + { // is_other(from) + std::error_code ec; + fs::copy(fifo, dir, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(fifo, dir, ec)); + } + { // is_other(to) + std::error_code ec; + fs::copy(file, fifo, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(file, fifo, ec)); + } +} + +TEST_CASE(from_is_symlink) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + const path symlink = env.create_symlink(file, "sym"); + const path dne = env.make_env_path("dne"); + + { // skip symlinks + std::error_code ec = GetTestEC(); + fs::copy(symlink, dne, copy_options::skip_symlinks, ec); + TEST_CHECK(!ec); + TEST_CHECK(!exists(dne)); + } + { + const path dest = env.make_env_path("dest"); + std::error_code ec = GetTestEC(); + fs::copy(symlink, dest, copy_options::copy_symlinks, ec); + TEST_CHECK(!ec); + TEST_CHECK(exists(dest)); + TEST_CHECK(is_symlink(dest)); + } + { // copy symlink but target exists + std::error_code ec = GetTestEC(); + fs::copy(symlink, file, copy_options::copy_symlinks, ec); + TEST_CHECK(ec); + } + { // create symlinks but target exists + std::error_code ec = GetTestEC(); + fs::copy(symlink, file, copy_options::create_symlinks, ec); + TEST_CHECK(ec); + } +} + +TEST_CASE(from_is_regular_file) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + const path dir = env.create_dir("dir"); + { // skip copy because of directory + const path dest = env.make_env_path("dest1"); + std::error_code ec = GetTestEC(); + fs::copy(file, dest, CO::directories_only, ec); + TEST_CHECK(!ec); + TEST_CHECK(!exists(dest)); + } + { // create symlink to file + const path dest = env.make_env_path("sym"); + std::error_code ec = GetTestEC(); + fs::copy(file, dest, CO::create_symlinks, ec); + TEST_CHECK(!ec); + TEST_CHECK(is_symlink(dest)); + TEST_CHECK(equivalent(file, canonical(dest))); + } + { // create hard link to file + const path dest = env.make_env_path("hardlink"); + TEST_CHECK(hard_link_count(file) == 1); + std::error_code ec = GetTestEC(); + fs::copy(file, dest, CO::create_hard_links, ec); + TEST_CHECK(!ec); + TEST_CHECK(exists(dest)); + TEST_CHECK(hard_link_count(file) == 2); + } + { // is_directory(t) + const path dest_dir = env.create_dir("dest_dir"); + const path expect_dest = dest_dir / file.filename(); + std::error_code ec = GetTestEC(); + fs::copy(file, dest_dir, ec); + TEST_CHECK(!ec); + TEST_CHECK(is_regular_file(expect_dest)); + } + { // otherwise copy_file(from, to, ...) + const path dest = env.make_env_path("file_copy"); + std::error_code ec = GetTestEC(); + fs::copy(file, dest, ec); + TEST_CHECK(!ec); + TEST_CHECK(is_regular_file(dest)); + } +} + +TEST_CASE(from_is_directory) +{ + struct FileInfo { + path filename; + int size; + }; + const FileInfo files[] = { + {"file1", 0}, + {"file2", 42}, + {"file3", 300} + }; + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path nested_dir_name = "dir2"; + const path nested_dir = env.create_dir("dir/dir2"); + + for (auto& FI : files) { + env.create_file(dir / FI.filename, FI.size); + env.create_file(nested_dir / FI.filename, FI.size); + } + { // test for non-existent directory + const path dest = env.make_env_path("dest_dir1"); + std::error_code ec = GetTestEC(); + fs::copy(dir, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_directory(dest)); + for (auto& FI : files) { + path created = dest / FI.filename; + TEST_CHECK(is_regular_file(created)); + TEST_CHECK(file_size(created) == FI.size); + } + TEST_CHECK(!is_directory(dest / nested_dir_name)); + } + { // test for existing directory + const path dest = env.create_dir("dest_dir2"); + std::error_code ec = GetTestEC(); + fs::copy(dir, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_directory(dest)); + for (auto& FI : files) { + path created = dest / FI.filename; + TEST_CHECK(is_regular_file(created)); + TEST_CHECK(file_size(created) == FI.size); + } + TEST_CHECK(!is_directory(dest / nested_dir_name)); + } + { // test recursive copy + const path dest = env.make_env_path("dest_dir3"); + std::error_code ec = GetTestEC(); + fs::copy(dir, dest, CO::recursive, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_directory(dest)); + const path nested_dest = dest / nested_dir_name; + TEST_REQUIRE(is_directory(nested_dest)); + for (auto& FI : files) { + path created = dest / FI.filename; + path nested_created = nested_dest / FI.filename; + TEST_CHECK(is_regular_file(created)); + TEST_CHECK(file_size(created) == FI.size); + TEST_CHECK(is_regular_file(nested_created)); + TEST_CHECK(file_size(nested_created) == FI.size); + } + } + +} +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp new file mode 100644 index 0000000000000..ac9877bbd9ce7 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool copy_file(const path& from, const path& to); +// bool copy_file(const path& from, const path& to, error_code& ec) noexcept; +// bool copy_file(const path& from, const path& to, copy_options options); +// bool copy_file(const path& from, const path& to, copy_options options, +// error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <chrono> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +using CO = fs::copy_options; + +TEST_SUITE(filesystem_copy_file_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + const copy_options opts{}; ((void)opts); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p)), bool); + ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts)), bool); + ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, ec)), bool); + ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts, ec)), bool); + ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p)); + ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts)); + ASSERT_NOEXCEPT(fs::copy_file(p, p, ec)); + ASSERT_NOEXCEPT(fs::copy_file(p, p, opts, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::copy_file(f, t); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == t + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path file2 = env.create_file("file2", 55); + const path dne = env.make_env_path("dne"); + { // exists(to) && equivalent(to, from) + std::error_code ec; + TEST_CHECK(fs::copy_file(file, file, ec) == false); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(file, file, ec)); + } + { // exists(to) && !(skip_existing | overwrite_existing | update_existing) + std::error_code ec; + TEST_CHECK(fs::copy_file(file, file2, ec) == false); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(file, file2, ec)); + } +} + +TEST_CASE(copy_file) +{ + scoped_test_env env; + const path file = env.create_file("file1", 42); + + { // !exists(to) + const path dest = env.make_env_path("dest1"); + std::error_code ec; + TEST_REQUIRE(fs::copy_file(file, dest, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(file_size(dest) == 42); + } + { // exists(to) && overwrite_existing + const path dest = env.create_file("dest2", 55); + std::error_code ec; + TEST_REQUIRE(fs::copy_file(file, dest, + copy_options::overwrite_existing, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(file_size(dest) == 42); + } + { // exists(to) && update_existing + using Sec = std::chrono::seconds; + const path older = env.create_file("older_file", 1); + + SleepFor(Sec(2)); + const path from = env.create_file("update_from", 55); + + SleepFor(Sec(2)); + const path newer = env.create_file("newer_file", 2); + + std::error_code ec; + TEST_REQUIRE(fs::copy_file(from, older, copy_options::update_existing, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(file_size(older) == 55); + + TEST_REQUIRE(fs::copy_file(from, newer, copy_options::update_existing, ec) == false); + TEST_CHECK(!ec); + TEST_CHECK(file_size(newer) == 2); + } + { // skip_existing + const path file2 = env.create_file("file2", 55); + std::error_code ec; + TEST_REQUIRE(fs::copy_file(file, file2, copy_options::skip_existing, ec) == false); + TEST_CHECK(!ec); + TEST_CHECK(file_size(file2) == 55); + } +} + +TEST_CASE(test_attributes_get_copied) +{ + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path dest = env.make_env_path("file2"); + auto st = status(file); + perms default_perms = st.permissions(); + perms new_perms = perms::owner_read; + permissions(file, new_perms); + std::error_code ec; + TEST_REQUIRE(fs::copy_file(file, dest, ec) == true); + TEST_CHECK(!ec); + auto new_st = status(dest); + TEST_CHECK(new_st.permissions() == new_perms); +} + +TEST_CASE(copy_dir_test) +{ + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path dest = env.create_dir("dir1"); + std::error_code ec; + TEST_CHECK(fs::copy_file(file, dest, ec) == false); + TEST_CHECK(ec); + ec.clear(); + TEST_CHECK(fs::copy_file(dest, file, ec) == false); + TEST_CHECK(ec); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp new file mode 100644 index 0000000000000..6fae111952063 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp @@ -0,0 +1,108 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// void copy_symlink(const path& existing_symlink, const path& new_symlink); +// void copy_symlink(const path& existing_symlink, const path& new_symlink, +// error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_copy_symlink_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(fs::copy_symlink(p, p)); + ASSERT_NOEXCEPT(fs::copy_symlink(p, p, ec)); +} + + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::copy_symlink(f, t); + return true; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path file2 = env.create_file("file2", 55); + const path sym = env.create_symlink(file, "sym"); + const path dir = env.create_dir("dir"); + const path dne = env.make_env_path("dne"); + { // from is a file, not a symlink + std::error_code ec; + fs::copy_symlink(file, dne, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(file, dne, ec)); + } + { // from is a file, not a symlink + std::error_code ec; + fs::copy_symlink(dir, dne, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(dir, dne, ec)); + } + { // destination exists + std::error_code ec; + fs::copy_symlink(sym, file2, ec); + TEST_REQUIRE(ec); + } +} + +TEST_CASE(copy_symlink_basic) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path dir_sym = env.create_symlink(dir, "dir_sym"); + const path file = env.create_file("file", 42); + const path file_sym = env.create_symlink(file, "file_sym"); + { // test for directory symlinks + const path dest = env.make_env_path("dest1"); + std::error_code ec; + fs::copy_symlink(dir_sym, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_symlink(dest)); + TEST_CHECK(equivalent(dest, dir)); + } + { // test for file symlinks + const path dest = env.make_env_path("dest2"); + std::error_code ec; + fs::copy_symlink(file_sym, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_symlink(dest)); + TEST_CHECK(equivalent(dest, file)); + } +} + + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp new file mode 100644 index 0000000000000..ba060254956fe --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.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: c++98, c++03 + +// <experimental/filesystem> + +// bool create_directories(const path& p); +// bool create_directories(const path& p, error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_create_directories_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::create_directories(p)), bool); + ASSERT_SAME_TYPE(decltype(fs::create_directories(p, ec)), bool); + ASSERT_NOT_NOEXCEPT(fs::create_directories(p)); + ASSERT_NOEXCEPT(fs::create_directories(p, ec)); +} + +TEST_CASE(create_existing_directory) +{ + scoped_test_env env; + const path dir = env.create_dir("dir1"); + std::error_code ec; + TEST_CHECK(fs::create_directories(dir, ec) == false); + TEST_CHECK(!ec); + TEST_CHECK(is_directory(dir)); +} + +TEST_CASE(create_directory_one_level) +{ + scoped_test_env env; + const path dir = env.make_env_path("dir1"); + std::error_code ec; + TEST_CHECK(fs::create_directories(dir, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(is_directory(dir)); +} + +TEST_CASE(create_directories_multi_level) +{ + scoped_test_env env; + const path dir = env.make_env_path("dir1/dir2/dir3"); + std::error_code ec; + TEST_CHECK(fs::create_directories(dir, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(is_directory(dir)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp new file mode 100644 index 0000000000000..5fce217bc49e2 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// bool create_directory(const path& p); +// bool create_directory(const path& p, error_code& ec) noexcept; +// bool create_directory(const path& p, const path& attr); +// bool create_directory(const path& p, const path& attr, error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +#include <sys/types.h> +#include <sys/stat.h> + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +fs::perms read_umask() { + mode_t old_mask = umask(0); + umask(old_mask); // reset the mask to the old value. + return static_cast<fs::perms>(old_mask); +} + +TEST_SUITE(filesystem_create_directory_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::create_directory(p)), bool); + ASSERT_SAME_TYPE(decltype(fs::create_directory(p, ec)), bool); + ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p)), bool); + ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p, ec)), bool); + ASSERT_NOT_NOEXCEPT(fs::create_directory(p)); + ASSERT_NOEXCEPT(fs::create_directory(p, ec)); + ASSERT_NOT_NOEXCEPT(fs::create_directory(p, p)); + ASSERT_NOEXCEPT(fs::create_directory(p, p, ec)); +} + + +TEST_CASE(create_existing_directory) +{ + scoped_test_env env; + const path dir = env.create_dir("dir1"); + std::error_code ec; + TEST_CHECK(fs::create_directory(dir, ec) == false); + TEST_CHECK(!ec); + TEST_CHECK(is_directory(dir)); + // Test throwing version + TEST_CHECK(fs::create_directory(dir) == false); +} + +TEST_CASE(create_directory_one_level) +{ + scoped_test_env env; + const path dir = env.make_env_path("dir1"); + std::error_code ec; + TEST_CHECK(fs::create_directory(dir, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(is_directory(dir)); + + auto st = status(dir); + const perms expect_perms = perms::all & ~(read_umask()); + TEST_CHECK((st.permissions() & perms::all) == expect_perms); +} + +TEST_CASE(create_directory_multi_level) +{ + scoped_test_env env; + const path dir = env.make_env_path("dir1/dir2"); + const path dir1 = env.make_env_path("dir1"); + std::error_code ec; + TEST_CHECK(fs::create_directory(dir, ec) == false); + TEST_CHECK(ec); + TEST_CHECK(!is_directory(dir)); + TEST_CHECK(!is_directory(dir1)); +} + +TEST_CASE(dest_is_file) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + std::error_code ec; + TEST_CHECK(fs::create_directory(file, ec) == false); + TEST_CHECK(ec); + TEST_CHECK(is_regular_file(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp new file mode 100644 index 0000000000000..c32bdd2d1928e --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// bool create_directory(const path& p, const path& attr); +// bool create_directory(const path& p, const path& attr, error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_create_directory_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p)), bool); + ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p, ec)), bool); + ASSERT_NOT_NOEXCEPT(fs::create_directory(p, p)); + ASSERT_NOEXCEPT(fs::create_directory(p, p, ec)); +} + +TEST_CASE(create_existing_directory) +{ + scoped_test_env env; + const path dir = env.create_dir("dir1"); + const path dir2 = env.create_dir("dir2"); + + const perms orig_p = status(dir).permissions(); + permissions(dir2, perms::none); + + std::error_code ec; + TEST_CHECK(fs::create_directory(dir, dir2, ec) == false); + TEST_CHECK(!ec); + + // Check that the permissions were unchanged + TEST_CHECK(orig_p == status(dir).permissions()); + + // Test throwing version + TEST_CHECK(fs::create_directory(dir, dir2) == false); +} + +TEST_CASE(create_directory_one_level) +{ + scoped_test_env env; + // Remove setgid which mkdir would inherit + permissions(env.test_root, perms::remove_perms | perms::set_gid); + + const path dir = env.make_env_path("dir1"); + const path attr_dir = env.create_dir("dir2"); + permissions(attr_dir, perms::none); + + std::error_code ec; + TEST_CHECK(fs::create_directory(dir, attr_dir, ec) == true); + TEST_CHECK(!ec); + TEST_CHECK(is_directory(dir)); + + // Check that the new directory has the same permissions as attr_dir + auto st = status(dir); + TEST_CHECK(st.permissions() == perms::none); +} + +TEST_CASE(create_directory_multi_level) +{ + scoped_test_env env; + const path dir = env.make_env_path("dir1/dir2"); + const path dir1 = env.make_env_path("dir1"); + const path attr_dir = env.create_dir("attr_dir"); + std::error_code ec; + TEST_CHECK(fs::create_directory(dir, attr_dir, ec) == false); + TEST_CHECK(ec); + TEST_CHECK(!is_directory(dir)); + TEST_CHECK(!is_directory(dir1)); +} + +TEST_CASE(dest_is_file) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + const path attr_dir = env.create_dir("attr_dir"); + std::error_code ec; + TEST_CHECK(fs::create_directory(file, attr_dir, ec) == false); + TEST_CHECK(ec); + TEST_CHECK(is_regular_file(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp new file mode 100644 index 0000000000000..e0473754cc886 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.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 + +// <experimental/filesystem> + +// void create_directory_symlink(const path& existing_symlink, const path& new_symlink); +// void create_directory_symlink(const path& existing_symlink, const path& new_symlink, +// error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_create_directory_symlink_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(fs::create_directory_symlink(p, p)); + ASSERT_NOEXCEPT(fs::create_directory_symlink(p, p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::create_directory_symlink(f, t); + return true; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path file2 = env.create_file("file2", 55); + const path sym = env.create_symlink(file, "sym"); + { // destination exists + std::error_code ec; + fs::create_directory_symlink(sym, file2, ec); + TEST_REQUIRE(ec); + } +} + +TEST_CASE(create_directory_symlink_basic) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path dir_sym = env.create_symlink(dir, "dir_sym"); + + const path dest = env.make_env_path("dest1"); + std::error_code ec; + fs::create_directory_symlink(dir_sym, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_symlink(dest)); + TEST_CHECK(equivalent(dest, dir)); +} + + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp new file mode 100644 index 0000000000000..4a865fdee7e8c --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// void create_hard_link(const path& existing_symlink, const path& new_symlink); +// void create_hard_link(const path& existing_symlink, const path& new_symlink, +// error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_create_hard_link_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(fs::create_hard_link(p, p)); + ASSERT_NOEXCEPT(fs::create_hard_link(p, p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::create_hard_link(f, t); + return true; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path file2 = env.create_file("file2", 55); + const path sym = env.create_symlink(file, "sym"); + { // destination exists + std::error_code ec; + fs::create_hard_link(sym, file2, ec); + TEST_REQUIRE(ec); + } +} + +TEST_CASE(create_file_hard_link) +{ + scoped_test_env env; + const path file = env.create_file("file"); + const path dest = env.make_env_path("dest1"); + std::error_code ec; + TEST_CHECK(hard_link_count(file) == 1); + fs::create_hard_link(file, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(exists(dest)); + TEST_CHECK(equivalent(dest, file)); + TEST_CHECK(hard_link_count(file) == 2); +} + +TEST_CASE(create_directory_hard_link_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path dest = env.make_env_path("dest2"); + std::error_code ec; + + fs::create_hard_link(dir, dest, ec); + TEST_REQUIRE(ec); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp new file mode 100644 index 0000000000000..35ba57f3ab46f --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// void create_symlink(const path& existing_symlink, const path& new_symlink); +// void create_symlink(const path& existing_symlink, const path& new_symlink, +// error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_create_symlink_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(fs::create_symlink(p, p)); + ASSERT_NOEXCEPT(fs::create_symlink(p, p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::create_symlink(f, t); + return true; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path file2 = env.create_file("file2", 55); + const path sym = env.create_symlink(file, "sym"); + { // destination exists + std::error_code ec; + fs::create_symlink(sym, file2, ec); + TEST_REQUIRE(ec); + } +} + +TEST_CASE(create_symlink_basic) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + const path file_sym = env.create_symlink(file, "file_sym"); + const path dir = env.create_dir("dir"); + const path dir_sym = env.create_symlink(dir, "dir_sym"); + { + const path dest = env.make_env_path("dest1"); + std::error_code ec; + fs::create_symlink(file_sym, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_symlink(dest)); + TEST_CHECK(equivalent(dest, file)); + } + { + const path dest = env.make_env_path("dest2"); + std::error_code ec; + fs::create_symlink(dir_sym, dest, ec); + TEST_REQUIRE(!ec); + TEST_CHECK(is_symlink(dest)); + TEST_CHECK(equivalent(dest, dir)); + } +} + + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp new file mode 100644 index 0000000000000..9d004ab854c1d --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// path current_path(); +// path current_path(error_code& ec); +// void current_path(path const&); +// void current_path(path const&, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(filesystem_current_path_path_test_suite) + +TEST_CASE(current_path_signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(current_path()); + ASSERT_NOT_NOEXCEPT(current_path(ec)); + ASSERT_NOT_NOEXCEPT(current_path(p)); + ASSERT_NOEXCEPT(current_path(p, ec)); +} + +TEST_CASE(current_path_test) +{ + std::error_code ec; + const path p = current_path(ec); + TEST_REQUIRE(!ec); + TEST_CHECK(p.is_absolute()); + TEST_CHECK(is_directory(p)); + + const path p2 = current_path(); + TEST_CHECK(p2 == p); +} + +TEST_CASE(current_path_after_change_test) +{ + const path new_path = StaticEnv::Dir; + current_path(new_path); + TEST_CHECK(current_path() == new_path); +} + +TEST_CASE(current_path_is_file_test) +{ + const path p = StaticEnv::File; + std::error_code ec; + const path old_p = current_path(); + current_path(p, ec); + TEST_CHECK(ec); + TEST_CHECK(old_p == current_path()); +} + +TEST_CASE(set_to_non_absolute_path) +{ + const path base = StaticEnv::Dir; + current_path(base); + const path p = StaticEnv::Dir2.filename(); + std::error_code ec; + current_path(p, ec); + TEST_CHECK(!ec); + const path new_cwd = current_path(); + TEST_CHECK(new_cwd == StaticEnv::Dir2); + TEST_CHECK(new_cwd.is_absolute()); +} + +TEST_CASE(set_to_empty) +{ + const path p = ""; + std::error_code ec; + const path old_p = current_path(); + current_path(p, ec); + TEST_CHECK(ec); + TEST_CHECK(old_p == current_path()); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp new file mode 100644 index 0000000000000..621ff8305fc3f --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.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 + +// <experimental/filesystem> + +// bool equivalent(path const& lhs, path const& rhs); +// bool equivalent(path const& lhs, path const& rhs, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(equivalent_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(equivalent(p, p, ec)); + ASSERT_NOT_NOEXCEPT(equivalent(p, p)); +} + +TEST_CASE(equivalent_test) +{ + struct TestCase { + path lhs; + path rhs; + bool expect; + }; + const TestCase testCases[] = { + {StaticEnv::Dir, StaticEnv::Dir, true}, + {StaticEnv::File, StaticEnv::Dir, false}, + {StaticEnv::Dir, StaticEnv::SymlinkToDir, true}, + {StaticEnv::Dir, StaticEnv::SymlinkToFile, false}, + {StaticEnv::File, StaticEnv::File, true}, + {StaticEnv::File, StaticEnv::SymlinkToFile, true}, + }; + for (auto& TC : testCases) { + std::error_code ec; + TEST_CHECK(equivalent(TC.lhs, TC.rhs, ec) == TC.expect); + TEST_CHECK(!ec); + } +} + +TEST_CASE(equivalent_reports_double_dne) +{ + const path E = StaticEnv::File; + const path DNE = StaticEnv::DNE; + { // Test that no exception is thrown if one of the paths exists + TEST_CHECK(equivalent(E, DNE) == false); + TEST_CHECK(equivalent(DNE, E) == false); + } + { // Test that an exception is thrown if both paths do not exist. + TEST_CHECK_THROW(filesystem_error, equivalent(DNE, DNE)); + } + { + std::error_code ec; + TEST_CHECK(equivalent(DNE, DNE, ec) == false); + TEST_CHECK(ec); + } +} + +TEST_CASE(equivalent_is_other_succeeds) +{ + scoped_test_env env; + path const file = env.create_file("file", 42); + const path hl1 = env.create_hardlink(file, "hl1"); + const path hl2 = env.create_hardlink(file, "hl2"); + TEST_CHECK(equivalent(file, hl1)); + TEST_CHECK(equivalent(file, hl2)); + TEST_CHECK(equivalent(hl1, hl2)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp new file mode 100644 index 0000000000000..252ced6fd65fa --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.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 + +// <experimental/filesystem> + +// bool exists(file_status s) noexcept +// bool exists(path const& p); +// bool exists(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(exists_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(exists(s)); + ASSERT_NOEXCEPT(exists(p, ec)); + ASSERT_NOT_NOEXCEPT(exists(p)); +} + +TEST_CASE(exists_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, true}, + {file_type::directory, true}, + {file_type::symlink, true}, + {file_type::block, true}, + {file_type::character, true}, + {file_type::fifo, true}, + {file_type::socket, true}, + {file_type::unknown, true} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(exists(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(exists(p) == false); + + std::error_code ec = GetTestEC(); + TEST_CHECK(exists(p, ec) == false); + TEST_CHECK(!ec); +} + +TEST_CASE(test_exists_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(exists(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, exists(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp new file mode 100644 index 0000000000000..460e42dd1c3f3 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// uintmax_t file_size(const path& p); +// uintmax_t file_size(const path& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(file_size_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(file_size(p)), uintmax_t); + ASSERT_SAME_TYPE(decltype(file_size(p, ec)), uintmax_t); + ASSERT_NOT_NOEXCEPT(file_size(p)); + ASSERT_NOEXCEPT(file_size(p, ec)); +} + +TEST_CASE(file_size_empty_test) +{ + const path p = StaticEnv::EmptyFile; + TEST_CHECK(file_size(p) == 0); + std::error_code ec; + TEST_CHECK(file_size(p, ec) == 0); +} + +TEST_CASE(file_size_non_empty) +{ + scoped_test_env env; + const path p = env.create_file("file", 42); + TEST_CHECK(file_size(p) == 42); + std::error_code ec; + TEST_CHECK(file_size(p, ec) == 42); +} + +TEST_CASE(symlink_test_case) +{ + const path p = StaticEnv::File; + const path p2 = StaticEnv::SymlinkToFile; + TEST_CHECK(file_size(p) == file_size(p2)); +} + +TEST_CASE(file_size_error_cases) +{ + const path testCases[] = { + StaticEnv::Dir, + StaticEnv::SymlinkToDir, + StaticEnv::BadSymlink, + StaticEnv::DNE + }; + const uintmax_t expect = static_cast<uintmax_t>(-1); + for (auto& TC : testCases) { + std::error_code ec; + TEST_CHECK(file_size(TC, ec) == expect); + TEST_CHECK(ec); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp new file mode 100644 index 0000000000000..abc50e9c6a41d --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// uintmax_t hard_link_count(const path& p); +// uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(hard_link_count_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(hard_link_count(p)), uintmax_t); + ASSERT_SAME_TYPE(decltype(hard_link_count(p, ec)), uintmax_t); + ASSERT_NOT_NOEXCEPT(hard_link_count(p)); + ASSERT_NOEXCEPT(hard_link_count(p, ec)); +} + +TEST_CASE(hard_link_count_for_file) +{ + TEST_CHECK(hard_link_count(StaticEnv::File) == 1); + std::error_code ec; + TEST_CHECK(hard_link_count(StaticEnv::File, ec) == 1); +} + +TEST_CASE(hard_link_count_for_directory) +{ + uintmax_t DirExpect = 3; + uintmax_t Dir3Expect = 2; +#if defined(__APPLE__) + DirExpect += 2; + Dir3Expect += 1; +#endif + TEST_CHECK(hard_link_count(StaticEnv::Dir) == DirExpect); + TEST_CHECK(hard_link_count(StaticEnv::Dir3) == Dir3Expect); + + std::error_code ec; + TEST_CHECK(hard_link_count(StaticEnv::Dir, ec) == DirExpect); + TEST_CHECK(hard_link_count(StaticEnv::Dir3, ec) == Dir3Expect); +} +TEST_CASE(hard_link_count_increments_test) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + TEST_CHECK(hard_link_count(file) == 1); + + env.create_hardlink(file, "file_hl"); + TEST_CHECK(hard_link_count(file) == 2); +} + + +TEST_CASE(hard_link_count_error_cases) +{ + const path testCases[] = { + StaticEnv::BadSymlink, + StaticEnv::DNE + }; + const uintmax_t expect = static_cast<uintmax_t>(-1); + for (auto& TC : testCases) { + std::error_code ec; + TEST_CHECK(hard_link_count(TC, ec) == expect); + TEST_CHECK(ec); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp new file mode 100644 index 0000000000000..dee28aa5be618 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// bool is_block_file(file_status s) noexcept +// bool is_block_file(path const& p); +// bool is_block_file(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_block_file_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_block_file(s)); + ASSERT_NOEXCEPT(is_block_file(p, ec)); + ASSERT_NOT_NOEXCEPT(is_block_file(p)); +} + +TEST_CASE(is_block_file_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, false}, + {file_type::symlink, false}, + {file_type::block, true}, + {file_type::character, false}, + {file_type::fifo, false}, + {file_type::socket, false}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_block_file(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_block_file(p) == false); +} + +TEST_CASE(test_is_block_file_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_block_file(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_block_file(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp new file mode 100644 index 0000000000000..2de42bf209758 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// bool is_character_file(file_status s) noexcept +// bool is_character_file(path const& p); +// bool is_character_file(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_character_file_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_character_file(s)); + ASSERT_NOEXCEPT(is_character_file(p, ec)); + ASSERT_NOT_NOEXCEPT(is_character_file(p)); +} + +TEST_CASE(is_character_file_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, false}, + {file_type::symlink, false}, + {file_type::block, false}, + {file_type::character, true}, + {file_type::fifo, false}, + {file_type::socket, false}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_character_file(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_character_file(p) == false); +} + +TEST_CASE(test_is_character_file_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_character_file(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_character_file(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp new file mode 100644 index 0000000000000..d6ecb1a1e684d --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp @@ -0,0 +1,91 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// bool is_directory(file_status s) noexcept +// bool is_directory(path const& p); +// bool is_directory(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_directory_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_directory(s)); + ASSERT_NOEXCEPT(is_directory(p, ec)); + ASSERT_NOT_NOEXCEPT(is_directory(p)); +} + +TEST_CASE(is_directory_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, true}, + {file_type::symlink, false}, + {file_type::block, false}, + {file_type::character, false}, + {file_type::fifo, false}, + {file_type::socket, false}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_directory(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_directory(p) == false); +} + +TEST_CASE(static_env_test) +{ + TEST_CHECK(is_directory(StaticEnv::Dir)); + TEST_CHECK(is_directory(StaticEnv::SymlinkToDir)); + TEST_CHECK(!is_directory(StaticEnv::File)); +} + +TEST_CASE(test_is_directory_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path dir2 = env.create_dir("dir/dir2"); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_directory(dir2, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_directory(dir2)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp new file mode 100644 index 0000000000000..ba07d09d10d92 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/filesystem> + +// bool is_empty(path const& p); +// bool is_empty(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_empty_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_empty(p, ec)); + ASSERT_NOT_NOEXCEPT(is_empty(p)); +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + std::error_code ec; + TEST_CHECK(is_empty(p, ec) == false); + TEST_CHECK(ec); + TEST_CHECK_THROW(filesystem_error, is_empty(p)); +} + +TEST_CASE(test_is_empty_directory) +{ + TEST_CHECK(!is_empty(StaticEnv::Dir)); + TEST_CHECK(!is_empty(StaticEnv::SymlinkToDir)); +} + +TEST_CASE(test_is_empty_directory_dynamic) +{ + scoped_test_env env; + TEST_CHECK(is_empty(env.test_root)); + env.create_file("foo", 42); + TEST_CHECK(!is_empty(env.test_root)); +} + +TEST_CASE(test_is_empty_file) +{ + TEST_CHECK(is_empty(StaticEnv::EmptyFile)); + TEST_CHECK(!is_empty(StaticEnv::NonEmptyFile)); +} + +TEST_CASE(test_is_empty_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path dir2 = env.create_dir("dir/dir2"); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_empty(dir2, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_empty(dir2)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp new file mode 100644 index 0000000000000..44892f65d86e9 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// bool is_fifo(file_status s) noexcept +// bool is_fifo(path const& p); +// bool is_fifo(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_fifo_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_fifo(s)); + ASSERT_NOEXCEPT(is_fifo(p, ec)); + ASSERT_NOT_NOEXCEPT(is_fifo(p)); +} + +TEST_CASE(is_fifo_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, false}, + {file_type::symlink, false}, + {file_type::block, false}, + {file_type::character, false}, + {file_type::fifo, true}, + {file_type::socket, false}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_fifo(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_fifo(p) == false); +} + +TEST_CASE(test_is_fifo_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_fifo(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_fifo(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp new file mode 100644 index 0000000000000..e86b66b4ea64f --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// bool is_other(file_status s) noexcept +// bool is_other(path const& p); +// bool is_other(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_other_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_other(s)); + ASSERT_NOEXCEPT(is_other(p, ec)); + ASSERT_NOT_NOEXCEPT(is_other(p)); +} + +TEST_CASE(is_other_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, false}, + {file_type::symlink, false}, + {file_type::block, true}, + {file_type::character, true}, + {file_type::fifo, true}, + {file_type::socket, true}, + {file_type::unknown, true} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_other(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_other(p) == false); +} + +TEST_CASE(test_is_other_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_other(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_other(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp new file mode 100644 index 0000000000000..be68dcfc35de3 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// bool is_regular_file(file_status s) noexcept +// bool is_regular_file(path const& p); +// bool is_regular_file(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_regular_file_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_regular_file(s)); + ASSERT_NOEXCEPT(is_regular_file(p, ec)); + ASSERT_NOT_NOEXCEPT(is_regular_file(p)); +} + +TEST_CASE(is_regular_file_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, true}, + {file_type::directory, false}, + {file_type::symlink, false}, + {file_type::block, false}, + {file_type::character, false}, + {file_type::fifo, false}, + {file_type::socket, false}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_regular_file(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_regular_file(p) == false); + std::error_code ec; + TEST_CHECK(is_regular_file(p, ec) == false); + TEST_CHECK(ec); +} + +TEST_CASE(test_is_regular_file_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_regular_file(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_regular_file(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp new file mode 100644 index 0000000000000..49fd402eb546b --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// bool is_socket(file_status s) noexcept +// bool is_socket(path const& p); +// bool is_socket(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_socket_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_socket(s)); + ASSERT_NOEXCEPT(is_socket(p, ec)); + ASSERT_NOT_NOEXCEPT(is_socket(p)); +} + +TEST_CASE(is_socket_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, false}, + {file_type::symlink, false}, + {file_type::block, false}, + {file_type::character, false}, + {file_type::fifo, false}, + {file_type::socket, true}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_socket(s) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_socket(p) == false); +} + +TEST_CASE(test_is_socket_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_socket(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_socket(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp new file mode 100644 index 0000000000000..3de002978683a --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// bool is_symlink(file_status s) noexcept +// bool is_symlink(path const& p); +// bool is_symlink(path const& p, std::error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(is_symlink_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOEXCEPT(is_symlink(s)); + ASSERT_NOEXCEPT(is_symlink(p, ec)); + ASSERT_NOT_NOEXCEPT(is_symlink(p)); +} + +TEST_CASE(is_symlink_status_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, false}, + {file_type::regular, false}, + {file_type::directory, false}, + {file_type::symlink, true}, + {file_type::block, false}, + {file_type::character, false}, + {file_type::fifo, false}, + {file_type::socket, false}, + {file_type::unknown, false} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(is_symlink(s) == TC.expect); + } +} + +TEST_CASE(static_env_test) +{ + struct TestCase { + path p; + bool expect; + }; + const TestCase testCases[] = { + {StaticEnv::File, false}, + {StaticEnv::Dir, false}, + {StaticEnv::SymlinkToFile, true}, + {StaticEnv::SymlinkToDir, true}, + {StaticEnv::BadSymlink, true} + }; + for (auto& TC : testCases) { + TEST_CHECK(is_symlink(TC.p) == TC.expect); + } +} + +TEST_CASE(test_exist_not_found) +{ + const path p = StaticEnv::DNE; + TEST_CHECK(is_symlink(p) == false); + std::error_code ec; + TEST_CHECK(is_symlink(p, ec) == false); + TEST_CHECK(ec); +} + +TEST_CASE(test_is_symlink_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec; + TEST_CHECK(is_symlink(file, ec) == false); + TEST_CHECK(ec); + + TEST_CHECK_THROW(filesystem_error, is_symlink(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp new file mode 100644 index 0000000000000..3c61b26d18e01 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp @@ -0,0 +1,361 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// file_time_type last_write_time(const path& p); +// file_time_type last_write_time(const path& p, std::error_code& ec) noexcept; +// void last_write_time(const path& p, file_time_type new_time); +// void last_write_time(const path& p, file_time_type new_type, +// std::error_code& ec) noexcept; + + +#include <experimental/filesystem> +#include <type_traits> +#include <chrono> +#include <fstream> +#include <cstdlib> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +#include <sys/stat.h> +#include <iostream> + +using namespace std::experimental::filesystem; + + +std::pair<std::time_t, std::time_t> GetTimes(path const& p) { + using Clock = file_time_type::clock; + struct ::stat st; + if (::stat(p.c_str(), &st) == -1) { + std::error_code ec(errno, std::generic_category()); +#ifndef TEST_HAS_NO_EXCEPTIONS + throw ec; +#else + std::cerr << ec.message() << std::endl; + std::exit(EXIT_FAILURE); +#endif + } + return {st.st_atime, st.st_mtime}; +} + +std::time_t LastAccessTime(path const& p) { + return GetTimes(p).first; +} + +std::time_t LastWriteTime(path const& p) { + return GetTimes(p).second; +} + +std::pair<std::time_t, std::time_t> GetSymlinkTimes(path const& p) { + using Clock = file_time_type::clock; + struct ::stat st; + if (::lstat(p.c_str(), &st) == -1) { + std::error_code ec(errno, std::generic_category()); +#ifndef TEST_HAS_NO_EXCEPTIONS + throw ec; +#else + std::cerr << ec.message() << std::endl; + std::exit(EXIT_FAILURE); +#endif + } + return {st.st_atime, st.st_mtime}; +} + +inline bool TimeIsRepresentableAsTimeT(file_time_type tp) { + using namespace std::chrono; + using Lim = std::numeric_limits<std::time_t>; + auto sec = duration_cast<seconds>(tp.time_since_epoch()).count(); + return (sec >= Lim::min() && sec <= Lim::max()); +} + + +TEST_SUITE(exists_test_suite) + +TEST_CASE(signature_test) +{ + const file_time_type t; + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(last_write_time(p)), file_time_type); + ASSERT_SAME_TYPE(decltype(last_write_time(p, ec)), file_time_type); + ASSERT_SAME_TYPE(decltype(last_write_time(p, t)), void); + ASSERT_SAME_TYPE(decltype(last_write_time(p, t, ec)), void); + ASSERT_NOT_NOEXCEPT(last_write_time(p)); + ASSERT_NOT_NOEXCEPT(last_write_time(p, t)); + ASSERT_NOEXCEPT(last_write_time(p, ec)); + ASSERT_NOEXCEPT(last_write_time(p, t, ec)); +} + +TEST_CASE(read_last_write_time_static_env_test) +{ + using C = file_time_type::clock; + file_time_type min = file_time_type::min(); + { + file_time_type ret = last_write_time(StaticEnv::File); + TEST_CHECK(ret != min); + TEST_CHECK(ret < C::now()); + TEST_CHECK(C::to_time_t(ret) == LastWriteTime(StaticEnv::File)); + + file_time_type ret2 = last_write_time(StaticEnv::SymlinkToFile); + TEST_CHECK(ret == ret2); + TEST_CHECK(C::to_time_t(ret2) == LastWriteTime(StaticEnv::SymlinkToFile)); + } + { + file_time_type ret = last_write_time(StaticEnv::Dir); + TEST_CHECK(ret != min); + TEST_CHECK(ret < C::now()); + TEST_CHECK(C::to_time_t(ret) == LastWriteTime(StaticEnv::Dir)); + + file_time_type ret2 = last_write_time(StaticEnv::SymlinkToDir); + TEST_CHECK(ret == ret2); + TEST_CHECK(C::to_time_t(ret2) == LastWriteTime(StaticEnv::SymlinkToDir)); + } +} + +TEST_CASE(get_last_write_time_dynamic_env_test) +{ + using Clock = file_time_type::clock; + using Sec = std::chrono::seconds; + scoped_test_env env; + + const path file = env.create_file("file", 42); + const path dir = env.create_dir("dir"); + + const auto file_times = GetTimes(file); + const std::time_t file_access_time = file_times.first; + const std::time_t file_write_time = file_times.second; + const auto dir_times = GetTimes(dir); + const std::time_t dir_access_time = dir_times.first; + const std::time_t dir_write_time = dir_times.second; + + file_time_type ftime = last_write_time(file); + TEST_CHECK(Clock::to_time_t(ftime) == file_write_time); + + file_time_type dtime = last_write_time(dir); + TEST_CHECK(Clock::to_time_t(dtime) == dir_write_time); + + SleepFor(Sec(2)); + + // update file and add a file to the directory. Make sure the times increase. + std::ofstream of(file, std::ofstream::app); + of << "hello"; + of.close(); + env.create_file("dir/file1", 1); + + file_time_type ftime2 = last_write_time(file); + file_time_type dtime2 = last_write_time(dir); + + TEST_CHECK(ftime2 > ftime); + TEST_CHECK(dtime2 > dtime); + TEST_CHECK(LastAccessTime(file) == file_access_time); + TEST_CHECK(LastAccessTime(dir) == dir_access_time); +} + + +TEST_CASE(set_last_write_time_dynamic_env_test) +{ + using Clock = file_time_type::clock; + using Sec = std::chrono::seconds; + using Hours = std::chrono::hours; + using Minutes = std::chrono::minutes; + using MicroSec = std::chrono::microseconds; + scoped_test_env env; + + const path file = env.create_file("file", 42); + const path dir = env.create_dir("dir"); + const auto now = Clock::now(); + const file_time_type epoch_time = now - now.time_since_epoch(); + + const file_time_type future_time = now + Hours(3) + Sec(42) + MicroSec(17); + const file_time_type past_time = now - Minutes(3) - Sec(42) - MicroSec(17); + const file_time_type before_epoch_time = epoch_time - Minutes(3) - Sec(42) - MicroSec(17); + // FreeBSD has a bug in their utimes implementation where the time is not update + // when the number of seconds is '-1'. +#if defined(__FreeBSD__) + const file_time_type just_before_epoch_time = epoch_time - Sec(2) - MicroSec(17); +#else + const file_time_type just_before_epoch_time = epoch_time - MicroSec(17); +#endif + + struct TestCase { + path p; + file_time_type new_time; + } cases[] = { + {file, epoch_time}, + {dir, epoch_time}, + {file, future_time}, + {dir, future_time}, + {file, past_time}, + {dir, past_time}, + {file, before_epoch_time}, + {dir, before_epoch_time}, + {file, just_before_epoch_time}, + {dir, just_before_epoch_time} + }; + for (const auto& TC : cases) { + const auto old_times = GetTimes(TC.p); + file_time_type old_time(Sec(old_times.second)); + + std::error_code ec = GetTestEC(); + last_write_time(TC.p, TC.new_time, ec); + TEST_CHECK(!ec); + + file_time_type got_time = last_write_time(TC.p); + + TEST_CHECK(got_time != old_time); + if (TC.new_time < epoch_time) { + TEST_CHECK(got_time <= TC.new_time); + TEST_CHECK(got_time > TC.new_time - Sec(1)); + } else { + TEST_CHECK(got_time <= TC.new_time + Sec(1)); + TEST_CHECK(got_time >= TC.new_time - Sec(1)); + } + TEST_CHECK(LastAccessTime(TC.p) == old_times.first); + } +} + +TEST_CASE(last_write_time_symlink_test) +{ + using Clock = file_time_type::clock; + using Sec = std::chrono::seconds; + using Hours = std::chrono::hours; + using Minutes = std::chrono::minutes; + + scoped_test_env env; + + const path file = env.create_file("file", 42); + const path sym = env.create_symlink("file", "sym"); + + const file_time_type new_time = Clock::now() + Hours(3); + + const auto old_times = GetTimes(sym); + const auto old_sym_times = GetSymlinkTimes(sym); + + std::error_code ec = GetTestEC(); + last_write_time(sym, new_time, ec); + TEST_CHECK(!ec); + + const std::time_t new_time_t = Clock::to_time_t(new_time); + file_time_type got_time = last_write_time(sym); + std::time_t got_time_t = Clock::to_time_t(got_time); + + TEST_CHECK(got_time_t != old_times.second); + TEST_CHECK(got_time_t == new_time_t); + TEST_CHECK(LastWriteTime(file) == new_time_t); + TEST_CHECK(LastAccessTime(sym) == old_times.first); + TEST_CHECK(GetSymlinkTimes(sym) == old_sym_times); +} + + +TEST_CASE(test_write_min_time) +{ + using Clock = file_time_type::clock; + using Sec = std::chrono::seconds; + using MicroSec = std::chrono::microseconds; + using Lim = std::numeric_limits<std::time_t>; + scoped_test_env env; + const path p = env.create_file("file", 42); + + std::error_code ec = GetTestEC(); + file_time_type last_time = last_write_time(p); + file_time_type new_time = file_time_type::min(); + + last_write_time(p, new_time, ec); + file_time_type tt = last_write_time(p); + + if (!TimeIsRepresentableAsTimeT(new_time)) { + TEST_CHECK(ec); + TEST_CHECK(ec != GetTestEC()); + TEST_CHECK(tt == last_time); + } else { + TEST_CHECK(!ec); + TEST_CHECK(tt >= new_time); + TEST_CHECK(tt < new_time + Sec(1)); + } + + ec = GetTestEC(); + last_write_time(p, Clock::now()); + last_time = last_write_time(p); + + new_time = file_time_type::min() + MicroSec(1); + + last_write_time(p, new_time, ec); + tt = last_write_time(p); + + if (!TimeIsRepresentableAsTimeT(new_time)) { + TEST_CHECK(ec); + TEST_CHECK(ec != GetTestEC()); + TEST_CHECK(tt == last_time); + } else { + TEST_CHECK(!ec); + TEST_CHECK(tt >= new_time); + TEST_CHECK(tt < new_time + Sec(1)); + } +} + + + +TEST_CASE(test_write_min_max_time) +{ + using Clock = file_time_type::clock; + using Sec = std::chrono::seconds; + using Hours = std::chrono::hours; + using Lim = std::numeric_limits<std::time_t>; + scoped_test_env env; + const path p = env.create_file("file", 42); + + std::error_code ec = GetTestEC(); + file_time_type last_time = last_write_time(p); + file_time_type new_time = file_time_type::max(); + + ec = GetTestEC(); + last_write_time(p, new_time, ec); + file_time_type tt = last_write_time(p); + + if (!TimeIsRepresentableAsTimeT(new_time)) { + TEST_CHECK(ec); + TEST_CHECK(ec != GetTestEC()); + TEST_CHECK(tt == last_time); + } else { + TEST_CHECK(!ec); + TEST_CHECK(tt > new_time - Sec(1)); + TEST_CHECK(tt <= new_time); + } +} + +TEST_CASE(test_value_on_failure) +{ + const path p = StaticEnv::DNE; + std::error_code ec = GetTestEC(); + TEST_CHECK(last_write_time(p, ec) == file_time_type::min()); + TEST_CHECK(ec); + TEST_CHECK(ec != GetTestEC()); +} + +TEST_CASE(test_exists_fails) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + permissions(dir, perms::none); + + std::error_code ec = GetTestEC(); + TEST_CHECK(last_write_time(file, ec) == file_time_type::min()); + TEST_CHECK(ec); + TEST_CHECK(ec != GetTestEC()); + + TEST_CHECK_THROW(filesystem_error, last_write_time(file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp new file mode 100644 index 0000000000000..b177693c09bde --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// void permissions(const path& p, perms prms); +// void permissions(const path& p, perms prms, std::error_code& ec) noexcept; + + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +using PR = fs::perms; + +TEST_SUITE(filesystem_permissions_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + const perms opts{}; ((void)opts); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(fs::permissions(p, opts)); + // Not noexcept because of narrow contract + ASSERT_NOT_NOEXCEPT(fs::permissions(p, opts, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, fs::perms opts, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::permissions(f, opts); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == "" + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path dne_sym = env.create_symlink(dne, "dne_sym"); + { // !exists + std::error_code ec; + fs::permissions(dne, fs::perms{}, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(dne, fs::perms{}, ec)); + } + { + std::error_code ec; + fs::permissions(dne_sym, fs::perms{}, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(dne_sym, fs::perms{}, ec)); + } +} + +TEST_CASE(basic_permissions_test) +{ + scoped_test_env env; + const path file = env.create_file("file1", 42); + const path dir = env.create_dir("dir1"); + const path file_for_sym = env.create_file("file2", 42); + const path sym = env.create_symlink(file_for_sym, "sym"); + const perms AP = perms::add_perms; + const perms RP = perms::remove_perms; + const perms NF = perms::symlink_nofollow; + struct TestCase { + path p; + perms set_perms; + perms expected; + } cases[] = { + // test file + {file, perms::none, perms::none}, + {file, perms::owner_all, perms::owner_all}, + {file, perms::group_all | AP, perms::owner_all | perms::group_all}, + {file, perms::group_all | RP, perms::owner_all}, + // test directory + {dir, perms::none, perms::none}, + {dir, perms::owner_all, perms::owner_all}, + {dir, perms::group_all | AP, perms::owner_all | perms::group_all}, + {dir, perms::group_all | RP, perms::owner_all}, + // test symlink without symlink_nofollow + {sym, perms::none, perms::none}, + {sym, perms::owner_all, perms::owner_all}, + {sym, perms::group_all | AP, perms::owner_all | perms::group_all}, + {sym, perms::group_all | RP , perms::owner_all}, + // test non-symlink with symlink_nofollow. The last test on file/dir + // will have set their permissions to perms::owner_all + {file, perms::group_all | AP | NF, perms::owner_all | perms::group_all}, + {dir, perms::group_all | AP | NF, perms::owner_all | perms::group_all} + }; + for (auto const& TC : cases) { + TEST_CHECK(status(TC.p).permissions() != TC.expected); + // Set the error code to ensure it's cleared. + std::error_code ec = std::make_error_code(std::errc::bad_address); + permissions(TC.p, TC.set_perms, ec); + TEST_CHECK(!ec); + auto pp = status(TC.p).permissions(); + TEST_CHECK(status(TC.p).permissions() == TC.expected); + } +} + +TEST_CASE(test_no_resolve_symlink_on_symlink) +{ + scoped_test_env env; + const path file = env.create_file("file", 42); + const path sym = env.create_symlink(file, "sym"); + const auto file_perms = status(file).permissions(); + + struct TestCase { + perms set_perms; + perms expected; // only expected on platform that support symlink perms. + } cases[] = { + {perms::owner_all, perms::owner_all}, + {perms::group_all | perms::add_perms, perms::owner_all | perms::group_all}, + {perms::owner_all | perms::remove_perms, perms::group_all}, + }; + for (auto const& TC : cases) { +#if defined(__APPLE__) || defined(__FreeBSD__) + // On OS X symlink permissions are supported. We should get an empty + // error code and the expected permissions. + const auto expected_link_perms = TC.expected; + std::error_code expected_ec; +#else + // On linux symlink permissions are not supported. The error code should + // be 'operation_not_supported' and the sylink permissions should be + // unchanged. + const auto expected_link_perms = symlink_status(sym).permissions(); + std::error_code expected_ec = std::make_error_code(std::errc::operation_not_supported); +#endif + std::error_code ec = std::make_error_code(std::errc::bad_address); + permissions(sym, TC.set_perms | perms::symlink_nofollow, ec); + TEST_CHECK(ec == expected_ec); + TEST_CHECK(status(file).permissions() == file_perms); + TEST_CHECK(symlink_status(sym).permissions() == expected_link_perms); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp new file mode 100644 index 0000000000000..00581cbe8bcc4 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.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 + +// <experimental/filesystem> + +// path read_symlink(const path& p); +// path read_symlink(const path& p, error_code& ec); + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_read_symlink_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::read_symlink(p)), fs::path); + ASSERT_SAME_TYPE(decltype(fs::read_symlink(p, ec)), fs::path); + + ASSERT_NOT_NOEXCEPT(fs::read_symlink(p)); + // Not noexcept because of narrow contract + ASSERT_NOT_NOEXCEPT(fs::read_symlink(p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::read_symlink(f); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == "" + && err.code() == ec; + } +#else + return true; +#endif + }; + + scoped_test_env env; + const path cases[] = { + env.make_env_path("dne"), + env.create_file("file", 42), + env.create_dir("dir") + }; + for (path const& p : cases) { + std::error_code ec; + const path ret = fs::read_symlink(p, ec); + TEST_REQUIRE(ec); + TEST_CHECK(ret == path{}); + TEST_CHECK(checkThrow(p, ec)); + } + +} + +TEST_CASE(basic_symlink_test) +{ + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path file = env.create_file("file", 42); + const path dir = env.create_dir("dir"); + const path link = env.create_symlink(dne, "link"); + const path nested_link = env.make_env_path("nested_link"); + create_symlink(link, nested_link); + struct TestCase { + path symlink; + path expected; + } testCases[] = { + {env.create_symlink(dne, "dne_link"), dne}, + {env.create_symlink(file, "file_link"), file}, + {env.create_symlink(dir, "dir_link"), dir}, + {nested_link, link} + }; + for (auto& TC : testCases) { + std::error_code ec = std::make_error_code(std::errc::address_in_use); + const path ret = read_symlink(TC.symlink, ec); + TEST_CHECK(!ec); + TEST_CHECK(ret == TC.expected); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp new file mode 100644 index 0000000000000..edb0c4fc76c9f --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// bool remove(const path& p); +// bool remove(const path& p, error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_remove_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::remove(p)), bool); + ASSERT_SAME_TYPE(decltype(fs::remove(p, ec)), bool); + + ASSERT_NOT_NOEXCEPT(fs::remove(p)); + ASSERT_NOEXCEPT(fs::remove(p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::remove(f); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == "" + && err.code() == ec; + } +#else + return true; +#endif + }; + scoped_test_env env; + const path non_empty_dir = env.create_dir("dir"); + env.create_file(non_empty_dir / "file1", 42); + const path bad_perms_dir = env.create_dir("bad_dir"); + const path file_in_bad_dir = env.create_file(bad_perms_dir / "file", 42); + permissions(bad_perms_dir, perms::none); + const path testCases[] = { + "", + env.make_env_path("dne"), + non_empty_dir, + file_in_bad_dir, + }; + for (auto& p : testCases) { + std::error_code ec; + TEST_CHECK(!fs::remove(p, ec)); + TEST_CHECK(ec); + TEST_CHECK(checkThrow(p, ec)); + } +} + +TEST_CASE(basic_remove_test) +{ + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path link = env.create_symlink(dne, "link"); + const path nested_link = env.make_env_path("nested_link"); + create_symlink(link, nested_link); + const path testCases[] = { + env.create_file("file", 42), + env.create_dir("empty_dir"), + nested_link, + link + }; + for (auto& p : testCases) { + std::error_code ec = std::make_error_code(std::errc::address_in_use); + TEST_CHECK(remove(p, ec)); + TEST_CHECK(!ec); + TEST_CHECK(!exists(symlink_status(p))); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp new file mode 100644 index 0000000000000..aecfce7885e96 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp @@ -0,0 +1,141 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// uintmax_t remove_all(const path& p); +// uintmax_t remove_all(const path& p, error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_remove_all_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::remove_all(p)), std::uintmax_t); + ASSERT_SAME_TYPE(decltype(fs::remove_all(p, ec)), std::uintmax_t); + + ASSERT_NOT_NOEXCEPT(fs::remove_all(p)); + ASSERT_NOEXCEPT(fs::remove_all(p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::remove_all(f); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == "" + && err.code() == ec; + } +#else + return true; +#endif + }; + scoped_test_env env; + const path non_empty_dir = env.create_dir("dir"); + env.create_file(non_empty_dir / "file1", 42); + const path bad_perms_dir = env.create_dir("bad_dir"); + const path file_in_bad_dir = env.create_file(bad_perms_dir / "file", 42); + permissions(bad_perms_dir, perms::none); + const path bad_perms_file = env.create_file("file2", 42); + permissions(bad_perms_file, perms::none); + + const path testCases[] = { + env.make_env_path("dne"), + file_in_bad_dir + }; + const auto BadRet = static_cast<std::uintmax_t>(-1); + for (auto& p : testCases) { + std::error_code ec; + TEST_CHECK(fs::remove_all(p, ec) == BadRet); + TEST_CHECK(ec); + TEST_CHECK(checkThrow(p, ec)); + } +} + +TEST_CASE(basic_remove_all_test) +{ + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path link = env.create_symlink(dne, "link"); + const path nested_link = env.make_env_path("nested_link"); + create_symlink(link, nested_link); + const path testCases[] = { + env.create_file("file", 42), + env.create_dir("empty_dir"), + nested_link, + link + }; + for (auto& p : testCases) { + std::error_code ec = std::make_error_code(std::errc::address_in_use); + TEST_CHECK(remove(p, ec)); + TEST_CHECK(!ec); + TEST_CHECK(!exists(symlink_status(p))); + } +} + +TEST_CASE(symlink_to_dir) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file(dir / "file", 42); + const path link = env.create_symlink(dir, "sym"); + + { + std::error_code ec = std::make_error_code(std::errc::address_in_use); + TEST_CHECK(remove_all(link, ec) == 1); + TEST_CHECK(!ec); + TEST_CHECK(!exists(symlink_status(link))); + TEST_CHECK(exists(dir)); + TEST_CHECK(exists(file)); + } +} + + +TEST_CASE(nested_dir) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path dir1 = env.create_dir(dir / "dir1"); + const path out_of_dir_file = env.create_file("file1", 42); + const path all_files[] = { + dir, dir1, + env.create_file(dir / "file1", 42), + env.create_symlink(out_of_dir_file, dir / "sym1"), + env.create_file(dir1 / "file2", 42), + env.create_symlink(dir, dir1 / "sym2") + }; + const std::size_t expected_count = sizeof(all_files) / sizeof(all_files[0]); + + std::error_code ec = std::make_error_code(std::errc::address_in_use); + TEST_CHECK(remove_all(dir, ec) == expected_count); + TEST_CHECK(!ec); + for (auto const& p : all_files) { + TEST_CHECK(!exists(symlink_status(p))); + } + TEST_CHECK(exists(out_of_dir_file)); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp new file mode 100644 index 0000000000000..c2ae854c0bf6d --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp @@ -0,0 +1,125 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// void rename(const path& old_p, const path& new_p); +// void rename(const path& old_p, const path& new_p, error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_rename_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(fs::rename(p, p)), void); + ASSERT_SAME_TYPE(decltype(fs::rename(p, p, ec)), void); + + ASSERT_NOT_NOEXCEPT(fs::rename(p, p)); + ASSERT_NOEXCEPT(fs::rename(p, p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::rename(f, t); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == t + && err.code() == ec; + } +#else + return true; +#endif + }; + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path file = env.create_file("file1", 42); + const path dir = env.create_dir("dir1"); + struct TestCase { + path from; + path to; + } cases[] = { + {dne, dne}, + {file, dir}, + {dir, file} + }; + for (auto& TC : cases) { + auto from_before = status(TC.from); + auto to_before = status(TC.to); + std::error_code ec; + rename(TC.from, TC.to, ec); + TEST_REQUIRE(ec); + TEST_CHECK(from_before.type() == status(TC.from).type()); + TEST_CHECK(to_before.type() == status(TC.to).type()); + TEST_CHECK(checkThrow(TC.from, TC.to, ec)); + } +} + +TEST_CASE(basic_rename_test) +{ + scoped_test_env env; + + const std::error_code set_ec = std::make_error_code(std::errc::address_in_use); + const path file = env.create_file("file1", 42); + { // same file + std::error_code ec = set_ec; + rename(file, file, ec); + TEST_CHECK(!ec); + TEST_CHECK(is_regular_file(file)); + TEST_CHECK(file_size(file) == 42); + } + const path sym = env.create_symlink(file, "sym"); + { // file -> symlink + std::error_code ec = set_ec; + rename(file, sym, ec); + TEST_CHECK(!ec); + TEST_CHECK(!exists(file)); + TEST_CHECK(is_regular_file(symlink_status(sym))); + TEST_CHECK(file_size(sym) == 42); + } + const path file2 = env.create_file("file2", 42); + const path file3 = env.create_file("file3", 100); + { // file -> file + std::error_code ec = set_ec; + rename(file2, file3, ec); + TEST_CHECK(!ec); + TEST_CHECK(!exists(file2)); + TEST_CHECK(is_regular_file(file3)); + TEST_CHECK(file_size(file3) == 42); + } + const path dne = env.make_env_path("dne"); + const path bad_sym = env.create_symlink(dne, "bad_sym"); + const path bad_sym_dest = env.make_env_path("bad_sym2"); + { // bad-symlink + std::error_code ec = set_ec; + rename(bad_sym, bad_sym_dest, ec); + TEST_CHECK(!ec); + TEST_CHECK(!exists(symlink_status(bad_sym))); + TEST_CHECK(is_symlink(bad_sym_dest)); + TEST_CHECK(read_symlink(bad_sym_dest) == dne); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp new file mode 100644 index 0000000000000..8a6aa09b14c78 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp @@ -0,0 +1,109 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// void resize_file(const path& p, uintmax_t new_size); +// void resize_file(const path& p, uintmax_t new_size, error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; +namespace fs = std::experimental::filesystem; + +TEST_SUITE(filesystem_resize_file_test_suite) + +TEST_CASE(test_signatures) +{ + const path p; ((void)p); + std::uintmax_t i; ((void)i); + std::error_code ec; ((void)ec); + + ASSERT_SAME_TYPE(decltype(fs::resize_file(p, i)), void); + ASSERT_SAME_TYPE(decltype(fs::resize_file(p, i, ec)), void); + + ASSERT_NOT_NOEXCEPT(fs::resize_file(p, i)); + ASSERT_NOEXCEPT(fs::resize_file(p, i, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, std::uintmax_t s, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + fs::resize_file(f, s); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == "" + && err.code() == ec; + } +#else + return true; +#endif + }; + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path bad_sym = env.create_symlink(dne, "sym"); + const path dir = env.create_dir("dir1"); + const path cases[] = { + dne, bad_sym, dir + }; + for (auto& p : cases) { + std::error_code ec; + resize_file(p, 42, ec); + TEST_REQUIRE(ec); + TEST_CHECK(checkThrow(p, 42, ec)); + } +} + +TEST_CASE(basic_resize_file_test) +{ + scoped_test_env env; + const path file1 = env.create_file("file1", 42); + const auto set_ec = std::make_error_code(std::errc::address_in_use); + { // grow file + const std::uintmax_t new_s = 100; + std::error_code ec = set_ec; + resize_file(file1, new_s, ec); + TEST_CHECK(!ec); + TEST_CHECK(file_size(file1) == new_s); + } + { // shrink file + const std::uintmax_t new_s = 1; + std::error_code ec = set_ec; + resize_file(file1, new_s, ec); + TEST_CHECK(!ec); + TEST_CHECK(file_size(file1) == new_s); + } + { // shrink file to zero + const std::uintmax_t new_s = 0; + std::error_code ec = set_ec; + resize_file(file1, new_s, ec); + TEST_CHECK(!ec); + TEST_CHECK(file_size(file1) == new_s); + } + const path sym = env.create_symlink(file1, "sym"); + { // grow file via symlink + const std::uintmax_t new_s = 1024; + std::error_code ec = set_ec; + resize_file(sym, new_s, ec); + TEST_CHECK(!ec); + TEST_CHECK(file_size(file1) == new_s); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp new file mode 100644 index 0000000000000..865191520be3e --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp @@ -0,0 +1,127 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// space_info space(const path& p); +// space_info space(const path& p, error_code& ec) noexcept; + +#include <experimental/filesystem> +#include <sys/statvfs.h> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +bool EqualDelta(std::uintmax_t x, std::uintmax_t y, std::uintmax_t delta) { + if (x >= y) { + return (x - y) <= delta; + } else { + return (y - x) <= delta; + } +} + +TEST_SUITE(filesystem_space_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_SAME_TYPE(decltype(space(p)), space_info); + ASSERT_SAME_TYPE(decltype(space(p, ec)), space_info); + ASSERT_NOT_NOEXCEPT(space(p)); + ASSERT_NOEXCEPT(space(p, ec)); +} + +TEST_CASE(test_error_reporting) +{ + auto checkThrow = [](path const& f, const std::error_code& ec) + { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + space(f); + return false; + } catch (filesystem_error const& err) { + return err.path1() == f + && err.path2() == "" + && err.code() == ec; + } +#else + return true; +#endif + }; + const path cases[] = { + "", + StaticEnv::DNE, + StaticEnv::BadSymlink + }; + for (auto& p : cases) { + const auto expect = static_cast<std::uintmax_t>(-1); + std::error_code ec; + space_info info = space(p, ec); + TEST_CHECK(ec); + TEST_CHECK(info.capacity == expect); + TEST_CHECK(info.free == expect); + TEST_CHECK(info.available == expect); + TEST_CHECK(checkThrow(p, ec)); + } +} + +TEST_CASE(basic_space_test) +{ + // All the test cases should reside on the same filesystem and therefore + // should have the same expected result. Compute this expected result + // one and check that it looks semi-sane. + struct statvfs expect; + TEST_REQUIRE(::statvfs(StaticEnv::Dir.c_str(), &expect) != -1); + TEST_CHECK(expect.f_bavail > 0); + TEST_CHECK(expect.f_bfree > 0); + TEST_CHECK(expect.f_bsize > 0); + TEST_CHECK(expect.f_blocks > 0); + TEST_REQUIRE(expect.f_frsize > 0); + auto do_mult = [&](std::uintmax_t val) { + std::uintmax_t fsize = expect.f_frsize; + std::uintmax_t new_val = val * fsize; + TEST_CHECK(new_val / fsize == val); // Test for overflow + return new_val; + }; + const std::uintmax_t bad_value = static_cast<std::uintmax_t>(-1); + const std::uintmax_t expect_capacity = do_mult(expect.f_blocks); + const std::uintmax_t expect_free = do_mult(expect.f_bfree); + const std::uintmax_t expect_avail = do_mult(expect.f_bavail); + + // Other processes running on the operating system may have changed + // the amount of space available. Check that these are within tolerances. + // Currently 5% of capacity + const std::uintmax_t delta = expect_capacity / 20; + const path cases[] = { + StaticEnv::File, + StaticEnv::Dir, + StaticEnv::Dir2, + StaticEnv::SymlinkToFile, + StaticEnv::SymlinkToDir + }; + for (auto& p : cases) { + std::error_code ec = GetTestEC(); + space_info info = space(p, ec); + TEST_CHECK(!ec); + TEST_CHECK(info.capacity != bad_value); + TEST_CHECK(expect_capacity == info.capacity); + TEST_CHECK(info.free != bad_value); + TEST_CHECK(EqualDelta(expect_free, info.free, delta)); + TEST_CHECK(info.available != bad_value); + TEST_CHECK(EqualDelta(expect_avail, info.available, delta)); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp new file mode 100644 index 0000000000000..2c76caf74c847 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp @@ -0,0 +1,159 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// file_status status(const path& p); +// file_status status(const path& p, error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(filesystem_status_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(status(p)); + ASSERT_NOEXCEPT(status(p, ec)); +} + +TEST_CASE(test_status_not_found) +{ + const std::error_code expect_ec = + std::make_error_code(std::errc::no_such_file_or_directory); + const path cases[] { + StaticEnv::DNE, + StaticEnv::BadSymlink + }; + for (auto& p : cases) { + std::error_code ec = std::make_error_code(std::errc::address_in_use); + // test non-throwing overload. + file_status st = status(p, ec); + TEST_CHECK(ec == expect_ec); + TEST_CHECK(st.type() == file_type::not_found); + TEST_CHECK(st.permissions() == perms::unknown); + // test throwing overload. It should not throw even though it reports + // that the file was not found. + TEST_CHECK_NO_THROW(st = status(p)); + TEST_CHECK(st.type() == file_type::not_found); + TEST_CHECK(st.permissions() == perms::unknown); + } +} + +TEST_CASE(test_status_cannot_resolve) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file = env.create_file("dir/file", 42); + const path sym = env.create_symlink("dir/file", "sym"); + permissions(dir, perms::none); + + const std::error_code set_ec = + std::make_error_code(std::errc::address_in_use); + const std::error_code expect_ec = + std::make_error_code(std::errc::permission_denied); + + const path cases[] = { + file, sym + }; + for (auto& p : cases) + { + { // test non-throwing case + std::error_code ec = set_ec; + file_status st = status(p, ec); + TEST_CHECK(ec == expect_ec); + TEST_CHECK(st.type() == file_type::none); + TEST_CHECK(st.permissions() == perms::unknown); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { // test throwing case + try { + status(p); + } catch (filesystem_error const& err) { + TEST_CHECK(err.path1() == p); + TEST_CHECK(err.path2() == ""); + TEST_CHECK(err.code() == expect_ec); + } + } +#endif + } +} + +TEST_CASE(status_file_types_test) +{ + scoped_test_env env; + struct TestCase { + path p; + file_type expect_type; + } cases[] = { + {StaticEnv::File, file_type::regular}, + {StaticEnv::SymlinkToFile, file_type::regular}, + {StaticEnv::Dir, file_type::directory}, + {StaticEnv::SymlinkToDir, file_type::directory}, + // Block files tested elsewhere + {StaticEnv::CharFile, file_type::character}, +#if !defined(__APPLE__) && !defined(__FreeBSD__) // No support for domain sockets + {env.create_socket("socket"), file_type::socket}, +#endif + {env.create_fifo("fifo"), file_type::fifo} + }; + for (const auto& TC : cases) { + // test non-throwing case + std::error_code ec = std::make_error_code(std::errc::address_in_use); + file_status st = status(TC.p, ec); + TEST_CHECK(!ec); + TEST_CHECK(st.type() == TC.expect_type); + TEST_CHECK(st.permissions() != perms::unknown); + // test throwing case + TEST_REQUIRE_NO_THROW(st = status(TC.p)); + TEST_CHECK(st.type() == TC.expect_type); + TEST_CHECK(st.permissions() != perms::unknown); + } +} + +TEST_CASE(test_block_file) +{ + const path possible_paths[] = { + "/dev/drive0", // Apple + "/dev/sda", + "/dev/loop0" + }; + path p; + for (const path& possible_p : possible_paths) { + std::error_code ec; + if (exists(possible_p, ec)) { + p = possible_p; + break; + } + } + if (p == path{}) { + TEST_UNSUPPORTED(); + } + // test non-throwing case + std::error_code ec = std::make_error_code(std::errc::address_in_use); + file_status st = status(p, ec); + TEST_CHECK(!ec); + TEST_CHECK(st.type() == file_type::block); + TEST_CHECK(st.permissions() != perms::unknown); + // test throwing case + TEST_REQUIRE_NO_THROW(st = status(p)); + TEST_CHECK(st.type() == file_type::block); + TEST_CHECK(st.permissions() != perms::unknown); +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp new file mode 100644 index 0000000000000..169c5be9d9a86 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// bool status_known(file_status s) noexcept; + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(status_known_test_suite) + +TEST_CASE(signature_test) +{ + file_status s; ((void)s); + ASSERT_SAME_TYPE(decltype(status_known(s)), bool); + ASSERT_NOEXCEPT(status_known(s)); +} + +TEST_CASE(status_known_test) +{ + struct TestCase { + file_type type; + bool expect; + }; + const TestCase testCases[] = { + {file_type::none, false}, + {file_type::not_found, true}, + {file_type::regular, true}, + {file_type::directory, true}, + {file_type::symlink, true}, + {file_type::block, true}, + {file_type::character, true}, + {file_type::fifo, true}, + {file_type::socket, true}, + {file_type::unknown, true} + }; + for (auto& TC : testCases) { + file_status s(TC.type); + TEST_CHECK(status_known(s) == TC.expect); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp new file mode 100644 index 0000000000000..647504f6e1a44 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.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 + +// <experimental/filesystem> + +// file_status symlink_status(const path& p); +// file_status symlink_status(const path& p, error_code& ec) noexcept; + +#include <experimental/filesystem> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(filesystem_symlink_status_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(symlink_status(p)); + ASSERT_NOEXCEPT(symlink_status(p, ec)); +} + +TEST_CASE(test_symlink_status_not_found) +{ + const std::error_code expect_ec = + std::make_error_code(std::errc::no_such_file_or_directory); + const path cases[] { + StaticEnv::DNE + }; + for (auto& p : cases) { + std::error_code ec = std::make_error_code(std::errc::address_in_use); + // test non-throwing overload. + file_status st = symlink_status(p, ec); + TEST_CHECK(ec == expect_ec); + TEST_CHECK(st.type() == file_type::not_found); + TEST_CHECK(st.permissions() == perms::unknown); + // test throwing overload. It should not throw even though it reports + // that the file was not found. + TEST_CHECK_NO_THROW(st = status(p)); + TEST_CHECK(st.type() == file_type::not_found); + TEST_CHECK(st.permissions() == perms::unknown); + } +} + +TEST_CASE(test_symlink_status_cannot_resolve) +{ + scoped_test_env env; + const path dir = env.create_dir("dir"); + const path file_in_dir = env.create_file("dir/file", 42); + const path sym_in_dir = env.create_symlink("dir/file", "dir/bad_sym"); + const path sym_points_in_dir = env.create_symlink("dir/file", "sym"); + permissions(dir, perms::none); + + const std::error_code set_ec = + std::make_error_code(std::errc::address_in_use); + const std::error_code expect_ec = + std::make_error_code(std::errc::permission_denied); + + const path fail_cases[] = { + file_in_dir, sym_in_dir + }; + for (auto& p : fail_cases) + { + { // test non-throwing case + std::error_code ec = set_ec; + file_status st = symlink_status(p, ec); + TEST_CHECK(ec == expect_ec); + TEST_CHECK(st.type() == file_type::none); + TEST_CHECK(st.permissions() == perms::unknown); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { // test throwing case + try { + symlink_status(p); + } catch (filesystem_error const& err) { + TEST_CHECK(err.path1() == p); + TEST_CHECK(err.path2() == ""); + TEST_CHECK(err.code() == expect_ec); + } + } +#endif + } + // Test that a symlink that points into a directory without read perms + // can be stat-ed using symlink_status + { + std::error_code ec = set_ec; + file_status st = symlink_status(sym_points_in_dir, ec); + TEST_CHECK(!ec); + TEST_CHECK(st.type() == file_type::symlink); + TEST_CHECK(st.permissions() != perms::unknown); + // test non-throwing version + TEST_REQUIRE_NO_THROW(st = symlink_status(sym_points_in_dir)); + TEST_CHECK(st.type() == file_type::symlink); + TEST_CHECK(st.permissions() != perms::unknown); + } +} + + +TEST_CASE(symlink_status_file_types_test) +{ + scoped_test_env env; + struct TestCase { + path p; + file_type expect_type; + } cases[] = { + {StaticEnv::BadSymlink, file_type::symlink}, + {StaticEnv::File, file_type::regular}, + {StaticEnv::SymlinkToFile, file_type::symlink}, + {StaticEnv::Dir, file_type::directory}, + {StaticEnv::SymlinkToDir, file_type::symlink}, + // Block files tested elsewhere + {StaticEnv::CharFile, file_type::character}, +#if !defined(__APPLE__) && !defined(__FreeBSD__) // No support for domain sockets + {env.create_socket("socket"), file_type::socket}, +#endif + {env.create_fifo("fifo"), file_type::fifo} + }; + for (const auto& TC : cases) { + // test non-throwing case + std::error_code ec = std::make_error_code(std::errc::address_in_use); + file_status st = symlink_status(TC.p, ec); + TEST_CHECK(!ec); + TEST_CHECK(st.type() == TC.expect_type); + TEST_CHECK(st.permissions() != perms::unknown); + // test throwing case + TEST_REQUIRE_NO_THROW(st = symlink_status(TC.p)); + TEST_CHECK(st.type() == TC.expect_type); + TEST_CHECK(st.permissions() != perms::unknown); + } +} + +TEST_CASE(test_block_file) +{ + const path possible_paths[] = { + "/dev/drive0", // Apple + "/dev/sda", // Linux + "/dev/loop0" // Linux + // No FreeBSD files known + }; + path p; + for (const path& possible_p : possible_paths) { + std::error_code ec; + if (exists(possible_p, ec)) { + p = possible_p; + break; + } + } + if (p == path{}) { + TEST_UNSUPPORTED(); + } + scoped_test_env env; + { // test block file + // test non-throwing case + std::error_code ec = std::make_error_code(std::errc::address_in_use); + file_status st = symlink_status(p, ec); + TEST_CHECK(!ec); + TEST_CHECK(st.type() == file_type::block); + TEST_CHECK(st.permissions() != perms::unknown); + // test throwing case + TEST_REQUIRE_NO_THROW(st = symlink_status(p)); + TEST_CHECK(st.type() == file_type::block); + TEST_CHECK(st.permissions() != perms::unknown); + } + const path sym = env.make_env_path("sym"); + create_symlink(p, sym); + { // test symlink to block file + // test non-throwing case + std::error_code ec = std::make_error_code(std::errc::address_in_use); + file_status st = symlink_status(sym, ec); + TEST_CHECK(!ec); + TEST_CHECK(st.type() == file_type::symlink); + TEST_CHECK(st.permissions() != perms::unknown); + // test throwing case + TEST_REQUIRE_NO_THROW(st = symlink_status(sym)); + TEST_CHECK(st.type() == file_type::symlink); + TEST_CHECK(st.permissions() != perms::unknown); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp new file mode 100644 index 0000000000000..634184e24e6d2 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.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: c++98, c++03 + +// <experimental/filesystem> + +// path system_complete(const path& p); +// path system_complete(const path& p, error_code& ec); + +// Note: For POSIX based operating systems, 'system_complete(p)' has the +// same semantics as 'absolute(p, current_path())'. + +#include <experimental/filesystem> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +TEST_SUITE(filesystem_system_complete_test_suite) + +TEST_CASE(signature_test) +{ + const path p; ((void)p); + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(system_complete(p)); + ASSERT_NOT_NOEXCEPT(system_complete(p, ec)); +} + + +TEST_CASE(basic_system_complete_tests) +{ + const path testCases[] = { + "//net/foo", // has_root_name() && has_root_directory() + "/foo", // !has_root_name() && has_root_directory() + "//net", // has_root_name() && !has_root_directory() + "bar/baz" // !has_root_name() && !has_root_directory() + }; + const path base = current_path(); + for (auto& p : testCases) { + const path ret = system_complete(p); + const path expect = absolute(p, base); + TEST_CHECK(ret.is_absolute()); + TEST_CHECK(ret == expect); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp b/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp new file mode 100644 index 0000000000000..215c35a33f302 --- /dev/null +++ b/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// path temp_directory_path(); +// path temp_directory_path(error_code& ec); + +#include <experimental/filesystem> +#include <memory> +#include <cstdlib> +#include <cstring> +#include <cassert> + +#include "test_macros.h" +#include "rapid-cxx-test.hpp" +#include "filesystem_test_helper.hpp" + +using namespace std::experimental::filesystem; + +void PutEnv(std::string var, std::string value) { + assert(::setenv(var.c_str(), value.c_str(), /* overwrite */ 1) == 0); +} + +void UnsetEnv(std::string var) { + assert(::unsetenv(var.c_str()) == 0); +} + +TEST_SUITE(filesystem_temp_directory_path_test_suite) + +TEST_CASE(signature_test) +{ + std::error_code ec; ((void)ec); + ASSERT_NOT_NOEXCEPT(temp_directory_path()); + ASSERT_NOT_NOEXCEPT(temp_directory_path(ec)); +} + +TEST_CASE(basic_tests) +{ + scoped_test_env env; + const path dne = env.make_env_path("dne"); + const path file = env.create_file("file", 42); + const path dir_perms = env.create_dir("bad_perms_dir"); + const path nested_dir = env.create_dir("bad_perms_dir/nested"); + permissions(dir_perms, perms::none); + const std::error_code set_ec = std::make_error_code(std::errc::address_in_use); + const std::error_code expect_ec = std::make_error_code(std::errc::not_a_directory); + struct TestCase { + std::string name; + path p; + } cases[] = { + {"TMPDIR", env.create_dir("dir1")}, + {"TMP", env.create_dir("dir2")}, + {"TEMP", env.create_dir("dir3")}, + {"TEMPDIR", env.create_dir("dir4")} + }; + for (auto& TC : cases) { + PutEnv(TC.name, TC.p); + } + for (auto& TC : cases) { + std::error_code ec = set_ec; + path ret = temp_directory_path(ec); + TEST_CHECK(!ec); + TEST_CHECK(ret == TC.p); + TEST_CHECK(is_directory(ret)); + + // Set the env variable to a path that does not exist and check + // that it fails. + PutEnv(TC.name, dne); + ec = set_ec; + ret = temp_directory_path(ec); + TEST_CHECK(ec == expect_ec); + TEST_CHECK(ret == ""); + + // Set the env variable to point to a file and check that it fails. + PutEnv(TC.name, file); + ec = set_ec; + ret = temp_directory_path(ec); + TEST_CHECK(ec == expect_ec); + TEST_CHECK(ret == ""); + + // Set the env variable to point to a dir we can't access + PutEnv(TC.name, nested_dir); + ec = set_ec; + ret = temp_directory_path(ec); + TEST_CHECK(ec == std::make_error_code(std::errc::permission_denied)); + TEST_CHECK(ret == ""); + + // Finally erase this env variable + UnsetEnv(TC.name); + } + // No env variables are defined + { + std::error_code ec = set_ec; + path ret = temp_directory_path(ec); + TEST_CHECK(!ec); + TEST_CHECK(ret == "/tmp"); + TEST_CHECK(is_directory(ret)); + } +} + +TEST_SUITE_END() diff --git a/test/std/experimental/filesystem/fs.req.macros/feature_macro.pass.cpp b/test/std/experimental/filesystem/fs.req.macros/feature_macro.pass.cpp new file mode 100644 index 0000000000000..d57dff4a7b789 --- /dev/null +++ b/test/std/experimental/filesystem/fs.req.macros/feature_macro.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// #define __cpp_lib_experimental_filesystem 201406L + +#include <experimental/filesystem> + +#ifndef __cpp_lib_experimental_filesystem +#error Filesystem feature test macro is not defined (__cpp_lib_experimental_filesystem) +#elif __cpp_lib_experimental_filesystem != 201406L +#error Filesystem feature test macro has an incorrect value (__cpp_lib_experimental_filesystem) +#endif + +int main() { } diff --git a/test/std/experimental/filesystem/fs.req.namespace/namespace.pass.cpp b/test/std/experimental/filesystem/fs.req.namespace/namespace.pass.cpp new file mode 100644 index 0000000000000..77ae7b0989be8 --- /dev/null +++ b/test/std/experimental/filesystem/fs.req.namespace/namespace.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/filesystem> + +// namespace std::experimental::filesystem::v1 + +#include <experimental/filesystem> +#include <type_traits> + +int main() { + static_assert(std::is_same< + std::experimental::filesystem::path, + std::experimental::filesystem::v1::path + >::value, ""); +} diff --git a/test/std/experimental/filesystem/lit.local.cfg b/test/std/experimental/filesystem/lit.local.cfg new file mode 100644 index 0000000000000..3d9360431f486 --- /dev/null +++ b/test/std/experimental/filesystem/lit.local.cfg @@ -0,0 +1,3 @@ +# Disable all of the filesystem tests if the correct feature is not available. +if 'c++filesystem' not in config.available_features: + config.unsupported = True diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/default.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/default.pass.cpp index 7647b536aa95e..ae1b64222a29f 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/default.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/default.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pass.cpp index 1323044c87041..bc44f1f6cbbfc 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only @@ -44,7 +44,7 @@ template <typename T> struct MyHash { template <typename Iter1, typename Iter2> void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) { - std::experimental::boyer_moore_searcher<Iter2, + std::experimental::boyer_moore_searcher<Iter2, MyHash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>> s{b2, e2}; assert(result == std::experimental::search(b1, e1, s)); diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pred.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pred.pass.cpp index 8fd5b8c9f784e..743ab92156be0 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pred.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pred.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only @@ -54,7 +54,7 @@ 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::boyer_moore_searcher<Iter2, + std::experimental::boyer_moore_searcher<Iter2, MyHash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>, count_equal> s{b2, e2}; diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/pred.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/pred.pass.cpp index d0655c82febb1..b27cabd76ab32 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/pred.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/pred.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only @@ -50,7 +50,7 @@ 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::boyer_moore_searcher<Iter2, + std::experimental::boyer_moore_searcher<Iter2, typename std::hash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>, count_equal> s{b2, e2}; count_equal::count = 0; assert(result == std::experimental::search(b1, e1, s)); diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/default.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/default.pass.cpp index af3bbbafb24e7..cbf9b41d590f8 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/default.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/default.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pass.cpp index ff289f0edeb05..28a3f6d912f87 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only @@ -43,7 +43,7 @@ template <typename T> struct MyHash { template <typename Iter1, typename Iter2> void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) { - std::experimental::boyer_moore_horspool_searcher<Iter2, + std::experimental::boyer_moore_horspool_searcher<Iter2, MyHash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>> s{b2, e2}; assert(result == std::experimental::search(b1, e1, s)); diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pred.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pred.pass.cpp index 1150210a978ad..3a6647dbc7f56 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pred.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pred.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only @@ -53,7 +53,7 @@ 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::boyer_moore_horspool_searcher<Iter2, + std::experimental::boyer_moore_horspool_searcher<Iter2, MyHash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>, count_equal> s{b2, e2}; diff --git a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/pred.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/pred.pass.cpp index 55426874abe55..8c78b9de0b35c 100644 --- a/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/pred.pass.cpp +++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/pred.pass.cpp @@ -19,11 +19,11 @@ // public: // boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, // Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); -// +// // template<class RandomAccessIterator2> -// RandomAccessIterator2 +// pair<RandomAccessIterator2, RandomAccessIterator2> // operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; -// +// // private: // RandomAccessIterator1 pat_first_; // exposition only // RandomAccessIterator1 pat_last_; // exposition only @@ -49,7 +49,7 @@ 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::boyer_moore_horspool_searcher<Iter2, + std::experimental::boyer_moore_horspool_searcher<Iter2, typename std::hash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>, count_equal> s{b2, e2}; count_equal::count = 0; assert(result == std::experimental::search(b1, e1, s)); 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 index 446dcbde42be3..4eaf3a8703906 100644 --- 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 @@ -15,15 +15,16 @@ // template<class _ForwardIterator, class _BinaryPredicate = equal_to<>> // class default_searcher { // public: -// default_searcher(_ForwardIterator __f, _ForwardIterator __l, +// 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 { +// pair<_ForwardIterator2, _ForwardIterator2> +// operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const { // return std::search(__f, __l, __first_, __last_, __pred_); // } -// +// // private: // _ForwardIterator __first_; // _ForwardIterator __last_; 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 index b65c500c31926..a2f690d7b7bfe 100644 --- 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 @@ -15,15 +15,16 @@ // template<class _ForwardIterator, class _BinaryPredicate = equal_to<>> // class default_searcher { // public: -// default_searcher(_ForwardIterator __f, _ForwardIterator __l, +// 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 { +// pair<_ForwardIterator2, _ForwardIterator2> +// operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const { // return std::search(__f, __l, __first_, __last_, __pred_); // } -// +// // private: // _ForwardIterator __first_; // _ForwardIterator __last_; 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 index 9528002d5f2da..7798a6e73f5e7 100644 --- 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 @@ -25,7 +25,7 @@ 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, + assert(result == std::experimental::search(b1, e1, std::experimental::make_default_searcher(b2, e2))); } 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 index 2770202131490..21f50a397e2ae 100644 --- 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 @@ -36,7 +36,7 @@ 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, + assert(result == std::experimental::search(b1, e1, std::experimental::make_default_searcher(b2, e2))); assert(count_equal::count <= max_count); } diff --git a/test/std/experimental/iterator/nothing_to_do.pass.cpp b/test/std/experimental/iterator/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..892d6895a326d --- /dev/null +++ b/test/std/experimental/iterator/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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/iterator> + +int main () {} diff --git a/test/std/experimental/iterator/ostream.joiner/ostream.joiner.cons/ostream_joiner.cons.pass.cpp b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.cons/ostream_joiner.cons.pass.cpp new file mode 100644 index 0000000000000..5c84d210e53eb --- /dev/null +++ b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.cons/ostream_joiner.cons.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: c++98, c++03, c++11 + +// <experimental/iterator> +// +// template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +// class ostream_joiner; +// +// ostream_joiner(ostream_type& __os, _Delim&& __d); +// ostream_joiner(ostream_type& __os, const _Delim& __d); + +#include <experimental/iterator> +#include <iostream> +#include <string> + +#include "test_macros.h" + +namespace exp = std::experimental; + +int main () { + const char eight = '8'; + const std::string nine = "9"; + const std::wstring ten = L"10"; + const int eleven = 11; + +// Narrow streams w/rvalues + { exp::ostream_joiner<char> oj(std::cout, '8'); } + { exp::ostream_joiner<std::string> oj(std::cout, std::string("9")); } + { exp::ostream_joiner<std::wstring> oj(std::cout, std::wstring(L"10")); } + { exp::ostream_joiner<int> oj(std::cout, 11); } + +// Narrow streams w/lvalues + { exp::ostream_joiner<char> oj(std::cout, eight); } + { exp::ostream_joiner<std::string> oj(std::cout, nine); } + { exp::ostream_joiner<std::wstring> oj(std::cout, ten); } + { exp::ostream_joiner<int> oj(std::cout, eleven); } + +// Wide streams w/rvalues + { exp::ostream_joiner<char, wchar_t> oj(std::wcout, '8'); } + { exp::ostream_joiner<std::string, wchar_t> oj(std::wcout, std::string("9")); } + { exp::ostream_joiner<std::wstring, wchar_t> oj(std::wcout, std::wstring(L"10")); } + { exp::ostream_joiner<int, wchar_t> oj(std::wcout, 11); } + +// Wide streams w/lvalues + { exp::ostream_joiner<char, wchar_t> oj(std::wcout, eight); } + { exp::ostream_joiner<std::string, wchar_t> oj(std::wcout, nine); } + { exp::ostream_joiner<std::wstring, wchar_t> oj(std::wcout, ten); } + { exp::ostream_joiner<int, wchar_t> oj(std::wcout, eleven); } + + } diff --git a/test/std/experimental/iterator/ostream.joiner/ostream.joiner.creation/make_ostream_joiner.pass.cpp b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.creation/make_ostream_joiner.pass.cpp new file mode 100644 index 0000000000000..a8c1b286f1de0 --- /dev/null +++ b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.creation/make_ostream_joiner.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/iterator> +// +// template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +// class ostream_joiner; +// +// template <class _CharT, class _Traits, class _Delim> +// ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits> +// make_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d); +// + +#include <experimental/iterator> +#include <iostream> +#include <sstream> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" + +namespace exp = std::experimental; + +template <class Delim, class Iter, class CharT = char, class Traits = std::char_traits<CharT>> +void test (Delim &&d, Iter first, Iter last, const CharT *expected ) { + std::basic_stringstream<CharT, Traits> sstream; + auto joiner = exp::make_ostream_joiner(sstream, d); + typedef exp::ostream_joiner<typename std::decay<Delim>::type, CharT, Traits> Joiner; + static_assert((std::is_same<decltype(joiner), Joiner>::value), "" ); + while (first != last) + joiner = *first++; + assert(sstream.str() == expected); + } + +int main () { + const char chars[] = "0123456789"; + const int ints [] = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + +// There are more of these tests in another file. +// This is just to make sure that the ostream_joiner is created correctly + test('X', chars, chars+10, "0X1X2X3X4X5X6X7X8X9"); + test('x', ints, ints+10, "10x11x12x13x14x15x16x17x18x19"); + test("Z", chars, chars+10, "0Z1Z2Z3Z4Z5Z6Z7Z8Z9"); + test("z", ints, ints+10, "10z11z12z13z14z15z16z17z18z19"); + } diff --git a/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp new file mode 100644 index 0000000000000..b2c294fd034b4 --- /dev/null +++ b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// 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/iterator> +// +// template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +// class ostream_joiner; +// +// template<typename T> +// ostream_joiner & operator=(const T&) +// + +#include <experimental/iterator> +#include <iostream> +#include <sstream> +#include <cassert> + +#include "test_macros.h" +#include "test_iterators.h" + +struct mutating_delimiter { + mutating_delimiter(char c = ' ') : c_(c) {} + char get () const { return c_++; } + mutable char c_; + }; + +template<class _CharT, class _Traits> +std::basic_ostream<_CharT, _Traits>& +operator<<(std::basic_ostream<_CharT, _Traits>& os, const mutating_delimiter &d) +{ return os << d.get(); } + + +struct mutating_delimiter2 { // same as above, w/o the const and the mutable + mutating_delimiter2(char c = ' ') : c_(c) {} + char get () { return c_++; } + char c_; + }; + +template<class _CharT, class _Traits> +std::basic_ostream<_CharT, _Traits>& +operator<<(std::basic_ostream<_CharT, _Traits>& os, mutating_delimiter2 &d) +{ return os << d.get(); } + + +namespace exp = std::experimental; + +template <class Delim, class Iter, class CharT = char, class Traits = std::char_traits<CharT>> +void test (Delim &&d, Iter first, Iter last, const CharT *expected ) { + typedef exp::ostream_joiner<typename std::decay<Delim>::type, CharT, Traits> Joiner; + + static_assert((std::is_copy_constructible<Joiner>::value == std::is_copy_constructible<typename std::decay<Delim>::type>::value), "" ); + static_assert((std::is_move_constructible<Joiner>::value == std::is_move_constructible<typename std::decay<Delim>::type>::value), "" ); + static_assert((std::is_copy_assignable<Joiner> ::value == std::is_copy_assignable<typename std::decay<Delim>::type> ::value), "" ); + static_assert((std::is_move_assignable<Joiner> ::value == std::is_move_assignable<typename std::decay<Delim>::type> ::value), "" ); + + std::basic_stringstream<CharT, Traits> sstream; + Joiner joiner(sstream, d); + while (first != last) + *joiner++ = *first++; + assert(sstream.str() == expected); + } + +int main () { +{ + const char chars[] = "0123456789"; + const int ints [] = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + + test('X', chars, chars+10, "0X1X2X3X4X5X6X7X8X9"); + test('x', ints, ints+10, "10x11x12x13x14x15x16x17x18x19"); + test('X', input_iterator<const char*>(chars), input_iterator<const char*>(chars+10), "0X1X2X3X4X5X6X7X8X9"); + test('x', input_iterator<const int*>(ints), input_iterator<const int*>(ints+10), "10x11x12x13x14x15x16x17x18x19"); + test('X', forward_iterator<const char*>(chars), forward_iterator<const char*>(chars+10), "0X1X2X3X4X5X6X7X8X9"); + test('x', forward_iterator<const int*>(ints), forward_iterator<const int*>(ints+10), "10x11x12x13x14x15x16x17x18x19"); + test('X', random_access_iterator<const char*>(chars), random_access_iterator<const char*>(chars+10), "0X1X2X3X4X5X6X7X8X9"); + test('x', random_access_iterator<const int*>(ints), random_access_iterator<const int*>(ints+10), "10x11x12x13x14x15x16x17x18x19"); + + test("Z", chars, chars+10, "0Z1Z2Z3Z4Z5Z6Z7Z8Z9"); + test("z", ints, ints+10, "10z11z12z13z14z15z16z17z18z19"); + + test<char, const char *, wchar_t> ('X', chars, chars+10, L"0X1X2X3X4X5X6X7X8X9"); + test<char, const int *, wchar_t> ('x', ints, ints+10, L"10x11x12x13x14x15x16x17x18x19"); +// test<char, const char *, char16_t>('X', chars, chars+10, u"0X1X2X3X4X5X6X7X8X9"); +// test<char, const int *, char16_t>('x', ints, ints+10, u"10x11x12x13x14x15x16x17x18x19"); +// test<char, const char *, char32_t>('X', chars, chars+10, U"0X1X2X3X4X5X6X7X8X9"); +// test<char, const int *, char32_t>('x', ints, ints+10, U"10x11x12x13x14x15x16x17x18x19"); + + test(mutating_delimiter(), chars, chars+10, "0 1!2\"3#4$5%6&7'8(9"); + test(mutating_delimiter2(), chars, chars+10, "0 1!2\"3#4$5%6&7'8(9"); + } + + { + const wchar_t chars[] = L"0123456789"; + const int ints [] = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + test(L'X', chars, chars+10, L"0X1X2X3X4X5X6X7X8X9"); + test(L'x', ints, ints+10, L"10x11x12x13x14x15x16x17x18x19"); + test(L'X', input_iterator<const wchar_t*>(chars), input_iterator<const wchar_t*>(chars+10), L"0X1X2X3X4X5X6X7X8X9"); + test(L'x', input_iterator<const int*>(ints), input_iterator<const int*>(ints+10), L"10x11x12x13x14x15x16x17x18x19"); + test(L'X', forward_iterator<const wchar_t*>(chars), forward_iterator<const wchar_t*>(chars+10), L"0X1X2X3X4X5X6X7X8X9"); + test(L'x', forward_iterator<const int*>(ints), forward_iterator<const int*>(ints+10), L"10x11x12x13x14x15x16x17x18x19"); + test(L'X', random_access_iterator<const wchar_t*>(chars), random_access_iterator<const wchar_t*>(chars+10), L"0X1X2X3X4X5X6X7X8X9"); + test(L'x', random_access_iterator<const int*>(ints), random_access_iterator<const int*>(ints+10), L"10x11x12x13x14x15x16x17x18x19"); + + test(L"Z", chars, chars+10, L"0Z1Z2Z3Z4Z5Z6Z7Z8Z9"); + test(L"z", ints, ints+10, L"10z11z12z13z14z15z16z17z18z19"); + + test<char, const wchar_t *, wchar_t> ('X', chars, chars+10, L"0X1X2X3X4X5X6X7X8X9"); + test<char, const int *, wchar_t> ('x', ints, ints+10, L"10x11x12x13x14x15x16x17x18x19"); + + test(mutating_delimiter(), chars, chars+10, L"0 1!2\"3#4$5%6&7'8(9"); + } + +} diff --git a/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.postincrement.pass.cpp b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.postincrement.pass.cpp new file mode 100644 index 0000000000000..e3872c3e030b0 --- /dev/null +++ b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.postincrement.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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/iterator> +// +// template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +// class ostream_joiner; +// +// ostream_joiner & operator++(int) noexcept +// returns *this; + +#include <experimental/iterator> +#include <iostream> +#include <cassert> + +#include "test_macros.h" + +namespace exp = std::experimental; + +template <class Delim, class CharT, class Traits> +void test ( exp::ostream_joiner<Delim, CharT, Traits> &oj ) { + static_assert((noexcept(oj++)), "" ); + exp::ostream_joiner<Delim, CharT, Traits> &ret = oj++; + assert( &ret == &oj ); + } + +int main () { + + { exp::ostream_joiner<char> oj(std::cout, '8'); test(oj); } + { exp::ostream_joiner<std::string> oj(std::cout, std::string("9")); test(oj); } + { exp::ostream_joiner<std::wstring> oj(std::cout, std::wstring(L"10")); test(oj); } + { exp::ostream_joiner<int> oj(std::cout, 11); test(oj); } + + { exp::ostream_joiner<char, wchar_t> oj(std::wcout, '8'); test(oj); } + { exp::ostream_joiner<std::string, wchar_t> oj(std::wcout, std::string("9")); test(oj); } + { exp::ostream_joiner<std::wstring, wchar_t> oj(std::wcout, std::wstring(L"10")); test(oj); } + { exp::ostream_joiner<int, wchar_t> oj(std::wcout, 11); test(oj); } + } diff --git a/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.pretincrement.pass.cpp b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.pretincrement.pass.cpp new file mode 100644 index 0000000000000..87b493e6393a8 --- /dev/null +++ b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.pretincrement.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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/iterator> +// +// template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +// class ostream_joiner; +// +// ostream_joiner & operator++() noexcept +// returns *this; + +#include <experimental/iterator> +#include <iostream> +#include <cassert> + +#include "test_macros.h" + +namespace exp = std::experimental; + +template <class Delim, class CharT, class Traits> +void test ( exp::ostream_joiner<Delim, CharT, Traits> &oj ) { + static_assert((noexcept(++oj)), "" ); + exp::ostream_joiner<Delim, CharT, Traits> &ret = ++oj; + assert( &ret == &oj ); + } + +int main () { + + { exp::ostream_joiner<char> oj(std::cout, '8'); test(oj); } + { exp::ostream_joiner<std::string> oj(std::cout, std::string("9")); test(oj); } + { exp::ostream_joiner<std::wstring> oj(std::cout, std::wstring(L"10")); test(oj); } + { exp::ostream_joiner<int> oj(std::cout, 11); test(oj); } + + { exp::ostream_joiner<char, wchar_t> oj(std::wcout, '8'); test(oj); } + { exp::ostream_joiner<std::string, wchar_t> oj(std::wcout, std::string("9")); test(oj); } + { exp::ostream_joiner<std::wstring, wchar_t> oj(std::wcout, std::wstring(L"10")); test(oj); } + { exp::ostream_joiner<int, wchar_t> oj(std::wcout, 11); test(oj); } + } diff --git a/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.star.pass.cpp b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.star.pass.cpp new file mode 100644 index 0000000000000..794346d75e7fe --- /dev/null +++ b/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.star.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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/iterator> +// +// template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +// class ostream_joiner; +// +// ostream_joiner & operator*() noexcept +// returns *this; + +#include <experimental/iterator> +#include <iostream> +#include <cassert> + +#include "test_macros.h" + +namespace exp = std::experimental; + +template <class Delim, class CharT, class Traits> +void test ( exp::ostream_joiner<Delim, CharT, Traits> &oj ) { + static_assert((noexcept(*oj)), "" ); + exp::ostream_joiner<Delim, CharT, Traits> &ret = *oj; + assert( &ret == &oj ); + } + +int main () { + + { exp::ostream_joiner<char> oj(std::cout, '8'); test(oj); } + { exp::ostream_joiner<std::string> oj(std::cout, std::string("9")); test(oj); } + { exp::ostream_joiner<std::wstring> oj(std::cout, std::wstring(L"10")); test(oj); } + { exp::ostream_joiner<int> oj(std::cout, 11); test(oj); } + + { exp::ostream_joiner<char, wchar_t> oj(std::wcout, '8'); test(oj); } + { exp::ostream_joiner<std::string, wchar_t> oj(std::wcout, std::string("9")); test(oj); } + { exp::ostream_joiner<std::wstring, wchar_t> oj(std::wcout, std::wstring(L"10")); test(oj); } + { exp::ostream_joiner<int, wchar_t> oj(std::wcout, 11); test(oj); } + } diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.cpp new file mode 100644 index 0000000000000..c4309d9097aab --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator operator=(polymorphic_allocator const &) = delete + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> T; + static_assert(!std::is_copy_assignable<T>::value, ""); + static_assert(!std::is_move_assignable<T>::value, ""); +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.pass.cpp new file mode 100644 index 0000000000000..ba3710d4de1ba --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator<T>::polymorphic_allocator(polymorphic_allocator const &); + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A1; + { + static_assert( + std::is_copy_constructible<A1>::value, "" + ); + static_assert( + std::is_move_constructible<A1>::value, "" + ); + } + // copy + { + A1 const a((ex::memory_resource*)42); + A1 const a2(a); + assert(a.resource() == a2.resource()); + } + // move + { + A1 a((ex::memory_resource*)42); + A1 a2(std::move(a)); + assert(a.resource() == a2.resource()); + assert(a2.resource() == (ex::memory_resource*)42); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.pass.cpp new file mode 100644 index 0000000000000..b696d0c13fb31 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator<T>::polymorphic_allocator() noexcept + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + { + static_assert( + std::is_nothrow_default_constructible<ex::polymorphic_allocator<void>>::value + , "Must me nothrow default constructible" + ); + } + { + // test that the allocator gets its resource from get_default_resource + TestResource R1(42); + ex::set_default_resource(&R1); + + typedef ex::polymorphic_allocator<void> A; + A const a; + assert(a.resource() == &R1); + + ex::set_default_resource(nullptr); + A const a2; + assert(a.resource() == &R1); + assert(a2.resource() == ex::new_delete_resource()); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.pass.cpp new file mode 100644 index 0000000000000..19d9646ad6162 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.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 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator<T>::polymorphic_allocator(memory_resource *) + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + { + typedef ex::polymorphic_allocator<void> A; + static_assert( + std::is_convertible<decltype(nullptr), A>::value + , "Must be convertible" + ); + static_assert( + std::is_convertible<ex::memory_resource *, A>::value + , "Must be convertible" + ); + } + { + typedef ex::polymorphic_allocator<void> A; + TestResource R; + A const a(&R); + assert(a.resource() == &R); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp new file mode 100644 index 0000000000000..aadfbcc322fce --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U> +// polymorphic_allocator<T>::polymorphic_allocator(polymorphic_allocator<U> const &); + + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A1; + typedef ex::polymorphic_allocator<char> A2; + { // Test that the conversion is implicit and noexcept. + static_assert( + std::is_convertible<A1 const &, A2>::value, "" + ); + static_assert( + std::is_convertible<A2 const &, A1>::value, "" + ); + static_assert( + std::is_nothrow_constructible<A1, A2 const &>::value, "" + ); + static_assert( + std::is_nothrow_constructible<A2, A1 const &>::value, "" + ); + } + // copy other type + { + A1 const a((ex::memory_resource*)42); + A2 const a2(a); + assert(a.resource() == a2.resource()); + assert(a2.resource() == (ex::memory_resource*)42); + } + { + A1 a((ex::memory_resource*)42); + A2 const a2(std::move(a)); + assert(a.resource() == a2.resource()); + assert(a2.resource() == (ex::memory_resource*)42); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp new file mode 100644 index 0000000000000..d4aea1cf5f216 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp @@ -0,0 +1,134 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator; + +// template <class T, class U> +// bool operator==( +// polymorphic_allocator<T> const & +// , polymorphic_allocator<U> const &) noexcept + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A1; + typedef ex::polymorphic_allocator<int> A2; + // check return types + { + A1 const a1; + A2 const a2; + static_assert(std::is_same<decltype(a1 == a2), bool>::value, ""); + static_assert(noexcept(a1 == a2), ""); + } + // equal same type (different resource) + { + TestResource d1(1); + TestResource d2(1); + A1 const a1(&d1); + A1 const a2(&d2); + + assert(a1 == a2); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(a2 == a1); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + } + // equal same type (same resource) + { + TestResource d1; + A1 const a1(&d1); + A1 const a2(&d1); + + assert(a1 == a2); + assert(d1.checkIsEqualCalledEq(0)); + + assert(a2 == a1); + assert(d1.checkIsEqualCalledEq(0)); + } + // equal different type (different resource) + { + TestResource d1(42); + TestResource d2(42); + A1 const a1(&d1); + A2 const a2(&d2); + + assert(a1 == a2); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + assert(a2 == a1); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(1)); + + } + // equal different type (same resource) + { + TestResource d1(42); + A1 const a1(&d1); + A2 const a2(&d1); + + assert(a1 == a2); + assert(d1.checkIsEqualCalledEq(0)); + + assert(a2 == a1); + assert(d1.checkIsEqualCalledEq(0)); + + } + // not equal same type + { + TestResource d1(1); + TestResource d2(2); + A1 const a1(&d1); + A1 const a2(&d2); + + assert(!(a1 == a2)); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(!(a2 == a1)); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + + } + // not equal different types + { + TestResource d1; + TestResource1 d2; + A1 const a1(&d1); + A2 const a2(&d2); + + assert(!(a1 == a2)); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(!(a2 == a1)); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp new file mode 100644 index 0000000000000..7b9b1d3857b7c --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator; + +// template <class T> +// bool operator!=( +// polymorphic_allocator<T> const & +// , polymorphic_allocator<T> const &) noexcept + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A1; + typedef ex::polymorphic_allocator<int> A2; + // check return types + { + A1 const a1; + A2 const a2; + static_assert(std::is_same<decltype(a1 != a2), bool>::value, ""); + static_assert(noexcept(a1 != a2), ""); + } + // not equal same type (different resource) + { + TestResource d1(1); + TestResource d2(2); + A1 const a1(&d1); + A1 const a2(&d2); + + assert(a1 != a2); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(a2 != a1); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + } + // equal same type (same resource) + { + TestResource d1; + A1 const a1(&d1); + A1 const a2(&d1); + + assert(!(a1 != a2)); + assert(d1.checkIsEqualCalledEq(0)); + + assert(!(a2 != a1)); + assert(d1.checkIsEqualCalledEq(0)); + } + // equal same type + { + TestResource d1(1); + TestResource d2(1); + A1 const a1(&d1); + A1 const a2(&d2); + + assert(!(a1 != a2)); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(!(a2 != a1)); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + + } + // not equal different types + { + TestResource d1; + TestResource1 d2; + A1 const a1(&d1); + A2 const a2(&d2); + + assert(a1 != a2); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(a2 != a1); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp new file mode 100644 index 0000000000000..a7efad1156dc0 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// T* polymorphic_allocator<T>::allocate(size_t n) + +#include <experimental/memory_resource> +#include <limits> +#include <memory> +#include <exception> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +template <size_t S, size_t Align> +void testForSizeAndAlign() { + using T = typename std::aligned_storage<S, Align>::type; + TestResource R; + ex::polymorphic_allocator<T> a(&R); + + for (int N = 1; N <= 5; ++N) { + auto ret = a.allocate(N); + assert(R.checkAlloc(ret, N * sizeof(T), alignof(T))); + + a.deallocate(ret, N); + R.reset(); + } +} + +#ifndef TEST_HAS_NO_EXCEPTIONS +template <size_t S> +void testAllocForSizeThrows() { + using T = typename std::aligned_storage<S>::type; + using Alloc = ex::polymorphic_allocator<T>; + using Traits = std::allocator_traits<Alloc>; + NullResource R; + Alloc a(&R); + + // Test that allocating exactly the max size does not throw. + size_t maxSize = Traits::max_size(a); + try { + a.allocate(maxSize); + } catch (...) { + assert(false); + } + + size_t sizeTypeMax = std::numeric_limits<std::size_t>::max(); + if (maxSize != sizeTypeMax) + { + // Test that allocating size_t(~0) throws bad alloc. + try { + a.allocate(sizeTypeMax); + assert(false); + } catch (std::exception const&) { + } + + // Test that allocating even one more than the max size does throw. + size_t overSize = maxSize + 1; + try { + a.allocate(overSize); + assert(false); + } catch (std::exception const&) { + } + } +} +#endif // TEST_HAS_NO_EXCEPTIONS + +int main() +{ + { + ex::polymorphic_allocator<int> a; + static_assert(std::is_same<decltype(a.allocate(0)), int*>::value, ""); + static_assert(!noexcept(a.allocate(0)), ""); + } + { + constexpr std::size_t MA = alignof(std::max_align_t); + testForSizeAndAlign<1, 1>(); + testForSizeAndAlign<1, 2>(); + testForSizeAndAlign<1, MA>(); + testForSizeAndAlign<2, 2>(); + testForSizeAndAlign<73, alignof(void*)>(); + testForSizeAndAlign<73, MA>(); + testForSizeAndAlign<13, MA>(); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + testAllocForSizeThrows<1>(); + testAllocForSizeThrows<2>(); + testAllocForSizeThrows<4>(); + testAllocForSizeThrows<8>(); + testAllocForSizeThrows<16>(); + testAllocForSizeThrows<73>(); + testAllocForSizeThrows<13>(); + } +#endif +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.pass.cpp new file mode 100644 index 0000000000000..2b43594756b70 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U1, class U2> +// void polymorphic_allocator<T>::construct(pair<U1, U2>*) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" + +namespace ex = std::experimental::pmr; + +int constructed = 0; + +struct default_constructible +{ + default_constructible() : x(42) { ++constructed; } + int x{0}; +}; + +int main() +{ + // pair<default_constructible, default_constructible> as T() + { + typedef default_constructible T; + typedef std::pair<T, T> P; + typedef ex::polymorphic_allocator<void> A; + P * ptr = (P*)std::malloc(sizeof(P)); + A a; + a.construct(ptr); + assert(constructed == 2); + assert(ptr->first.x == 42); + assert(ptr->second.x == 42); + std::free(ptr); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp new file mode 100644 index 0000000000000..50a71eeca82b1 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class P1, class P2, class U1, class U2> +// void polymorphic_allocator<T>::construct(pair<P1, P2>*, pair<U1, U2> const&) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" + +namespace ex = std::experimental::pmr; + + +template <class UA1, class UA2, class TT, class UU> +bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, + std::pair<TT, UU> const& p) +{ + using P = std::pair<UA1, UA2>; + TestResource R; + ex::memory_resource * M = &R; + ex::polymorphic_allocator<P> A(M); + P * ptr = (P*)std::malloc(sizeof(P)); + P * ptr2 = (P*)std::malloc(sizeof(P)); + + // UNDER TEST // + A.construct(ptr, p); + + A.construct(ptr2, std::piecewise_construct, + std::forward_as_tuple(p.first), + std::forward_as_tuple(p.second)); + // ------- // + + bool tres = checkConstruct<decltype((p.first))>(ptr->first, TExpect, M) && + checkConstructionEquiv(ptr->first, ptr2->first); + + bool ures = checkConstruct<decltype((p.second))>(ptr->second, UExpect, M) && + checkConstructionEquiv(ptr->second, ptr2->second); + + A.destroy(ptr); + std::free(ptr); + A.destroy(ptr2); + std::free(ptr2); + return tres && ures; + +} + +template <class Alloc, class TT, class UU> +void test_pmr_uses_allocator(std::pair<TT, UU> const& p) +{ + { + using T = NotUsesAllocator<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_None, UA_None, p))); + } + { + using T = UsesAllocatorV1<Alloc, 1>; + using U = UsesAllocatorV2<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, p))); + } + { + using T = UsesAllocatorV2<Alloc, 1>; + using U = UsesAllocatorV3<Alloc, 1>; + assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, p))); + } + { + using T = UsesAllocatorV3<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_None, p))); + } +} +template <class Tp> +struct Print; + +int main() +{ + using ERT = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<char>; + { + int x = 42; + int y = 42; + const std::pair<int, int&> p(x, y); + test_pmr_uses_allocator<ERT>(p); + test_pmr_uses_allocator<PMR>(p); + test_pmr_uses_allocator<PMA>(p); + } + { + int x = 42; + int y = 42; + const std::pair<int&, int&&> p(x, std::move(y)); + test_pmr_uses_allocator<ERT>(p); + test_pmr_uses_allocator<PMR>(p); + test_pmr_uses_allocator<PMA>(p); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp new file mode 100644 index 0000000000000..b6adb558b1e47 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp @@ -0,0 +1,109 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class P1, class P2, class U1, class U2> +// void polymorphic_allocator<T>::construct(pair<P1, P2>*, pair<U1, U2> &&) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" + +namespace ex = std::experimental::pmr; + + + +template <class UA1, class UA2, class TT, class UU> +bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, + std::pair<TT, UU>&& p) +{ + using P = std::pair<UA1, UA2>; + TestResource R; + ex::memory_resource * M = &R; + ex::polymorphic_allocator<P> A(M); + P * ptr = A.allocate(2); + P * ptr2 = ptr + 1; + + // UNDER TEST // + A.construct(ptr, std::move(p)); + + A.construct(ptr2, std::piecewise_construct, + std::forward_as_tuple(std::forward<TT>(p.first)), + std::forward_as_tuple(std::forward<UU>(p.second))); + // ------- // + + bool tres = checkConstruct<TT&&>(ptr->first, TExpect, M) && + checkConstructionEquiv(ptr->first, ptr2->first); + + bool ures = checkConstruct<UU&&>(ptr->second, UExpect, M) && + checkConstructionEquiv(ptr->second, ptr2->second); + + A.destroy(ptr); + A.destroy(ptr2); + A.deallocate(ptr, 2); + return tres && ures; +} + +template <class Alloc, class TT, class UU> +void test_pmr_uses_allocator(std::pair<TT, UU>&& p) +{ + { + using T = NotUsesAllocator<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_None, UA_None, std::move(p)))); + } + { + using T = UsesAllocatorV1<Alloc, 1>; + using U = UsesAllocatorV2<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, std::move(p)))); + } + { + using T = UsesAllocatorV2<Alloc, 1>; + using U = UsesAllocatorV3<Alloc, 1>; + assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, std::move(p)))); + } + { + using T = UsesAllocatorV3<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_None, std::move(p)))); + } +} + +int main() +{ + using ERT = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<char>; + { + int x = 42; + int y = 42; + std::pair<int&, int&&> p(x, std::move(y)); + test_pmr_uses_allocator<ERT>(std::move(p)); + test_pmr_uses_allocator<PMR>(std::move(p)); + test_pmr_uses_allocator<PMA>(std::move(p)); + } + { + int x = 42; + int y = 42; + std::pair<int&&, int&> p(std::move(x), y); + test_pmr_uses_allocator<ERT>(std::move(p)); + test_pmr_uses_allocator<PMR>(std::move(p)); + test_pmr_uses_allocator<PMA>(std::move(p)); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp new file mode 100644 index 0000000000000..a913742a854bd --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class P1, class P2, class U1, class U2> +// void polymorphic_allocator<T>::construct(pair<P1, P2>*, U1&&, U2&&) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" + +namespace ex = std::experimental::pmr; + + +template <class UA1, class UA2, class TT, class UU> +bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, + TT&& t, UU&& u) +{ + using P = std::pair<UA1, UA2>; + TestResource R; + ex::memory_resource * M = &R; + ex::polymorphic_allocator<P> A(M); + P * ptr = (P*)std::malloc(sizeof(P)); + P * ptr2 = (P*)std::malloc(sizeof(P)); + + // UNDER TEST // + A.construct(ptr, std::forward<TT>(t), std::forward<UU>(u)); + A.construct(ptr2, std::piecewise_construct, + std::forward_as_tuple(std::forward<TT>(t)), + std::forward_as_tuple(std::forward<UU>(u))); + // ------- // + + bool tres = checkConstruct<TT&&>(ptr->first, TExpect, M) && + checkConstructionEquiv(ptr->first, ptr2->first); + + bool ures = checkConstruct<UU&&>(ptr->second, UExpect, M) && + checkConstructionEquiv(ptr->second, ptr2->second); + + A.destroy(ptr); + A.destroy(ptr2); + std::free(ptr); + std::free(ptr2); + return tres && ures; +} + +template <class Alloc, class TT, class UU> +void test_pmr_uses_allocator(TT&& t, UU&& u) +{ + { + using T = NotUsesAllocator<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_None, UA_None, + std::forward<TT>(t), std::forward<UU>(u)))); + } + { + using T = UsesAllocatorV1<Alloc, 1>; + using U = UsesAllocatorV2<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, + std::forward<TT>(t), std::forward<UU>(u)))); + } + { + using T = UsesAllocatorV2<Alloc, 1>; + using U = UsesAllocatorV3<Alloc, 1>; + assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, + std::forward<TT>(t), std::forward<UU>(u)))); + } + { + using T = UsesAllocatorV3<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_None, + std::forward<TT>(t), std::forward<UU>(u)))); + } +} + +int main() +{ + using ERT = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<char>; + { + int x = 42; + int y = 42; + test_pmr_uses_allocator<ERT>(x, std::move(y)); + test_pmr_uses_allocator<PMR>(x, std::move(y)); + test_pmr_uses_allocator<PMA>(x, std::move(y)); + } + { + int x = 42; + const int y = 42; + test_pmr_uses_allocator<ERT>(std::move(x), y); + test_pmr_uses_allocator<PMR>(std::move(x), y); + test_pmr_uses_allocator<PMA>(std::move(x), y); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp new file mode 100644 index 0000000000000..d0d76503da50d --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp @@ -0,0 +1,130 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U1, class U2, class ...Args1, class ...Args2> +// void polymorphic_allocator<T>::construct(pair<U1, U2>*, piecewise_construct_t +// tuple<Args1...>, tuple<Args2...>) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" +#include "test_allocator.h" + +namespace ex = std::experimental::pmr; + +template <class T, class U, class ...TTuple, class ...UTuple> +bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, + std::tuple<TTuple...> ttuple, std::tuple<UTuple...> utuple) +{ + using P = std::pair<T, U>; + TestResource R; + ex::memory_resource * M = &R; + ex::polymorphic_allocator<P> A(M); + P * ptr = A.allocate(1); + + // UNDER TEST // + A.construct(ptr, std::piecewise_construct, std::move(ttuple), std::move(utuple)); + // ------- // + bool tres = checkConstruct<TTuple&&...>(ptr->first, TExpect, M); + bool ures = checkConstruct<UTuple&&...>(ptr->second, UExpect, M); + + A.destroy(ptr); + A.deallocate(ptr, 1); + return tres && ures; +} + +template <class Alloc, class ...TTypes, class ...UTypes> +void test_pmr_uses_allocator(std::tuple<TTypes...> ttuple, std::tuple<UTypes...> utuple) +{ + { + using T = NotUsesAllocator<Alloc, sizeof...(TTypes)>; + using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>; + assert((doTest<T, U>(UA_None, UA_None, + std::move(ttuple), std::move(utuple)))); + } + { + using T = UsesAllocatorV1<Alloc, sizeof...(TTypes)>; + using U = UsesAllocatorV2<Alloc, sizeof...(UTypes)>; + assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, + std::move(ttuple), std::move(utuple)))); + } + { + using T = UsesAllocatorV2<Alloc, sizeof...(TTypes)>; + using U = UsesAllocatorV3<Alloc, sizeof...(UTypes)>; + assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, + std::move(ttuple), std::move(utuple)))); + } + { + using T = UsesAllocatorV3<Alloc, sizeof...(TTypes)>; + using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>; + assert((doTest<T, U>(UA_AllocArg, UA_None, + std::move(ttuple), std::move(utuple)))); + } +} + +int main() +{ + using ERT = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<char>; + { + std::tuple<> t1; + test_pmr_uses_allocator<ERT>(t1, t1); + test_pmr_uses_allocator<PMR>(t1, t1); + test_pmr_uses_allocator<PMA>(t1, t1); + } + { + std::tuple<int> t1(42); + std::tuple<> t2; + test_pmr_uses_allocator<ERT>(t1, t2); + test_pmr_uses_allocator<ERT>(t2, t1); + test_pmr_uses_allocator<PMR>(t1, t2); + test_pmr_uses_allocator<PMR>(t2, t1); + test_pmr_uses_allocator<PMA>(t1, t2); + test_pmr_uses_allocator<PMA>(t2, t1); + } + { + std::tuple<int> t1(42); + int x = 55; + double dx = 42.42; + std::tuple<int&, double&&> t2(x, std::move(dx)); + test_pmr_uses_allocator<ERT>( t1, std::move(t2)); + test_pmr_uses_allocator<ERT>(std::move(t2), t1); + test_pmr_uses_allocator<PMR>( t1, std::move(t2)); + test_pmr_uses_allocator<PMR>(std::move(t2), t1); + test_pmr_uses_allocator<PMA>( t1, std::move(t2)); + test_pmr_uses_allocator<PMA>(std::move(t2), t1); + } + { + void* xptr = nullptr; + long y = 4242; + std::tuple<int, long const&, void*&> t1(42, y, xptr); + int x = 55; + double dx = 42.42; + const char* s = "hello World"; + std::tuple<int&, double&&, const char*> t2(x, std::move(dx), s); + test_pmr_uses_allocator<ERT>( t1, std::move(t2)); + test_pmr_uses_allocator<ERT>(std::move(t2), t1); + test_pmr_uses_allocator<PMR>( t1, std::move(t2)); + test_pmr_uses_allocator<PMR>(std::move(t2), t1); + test_pmr_uses_allocator<PMA>( t1, std::move(t2)); + test_pmr_uses_allocator<PMA>(std::move(t2), t1); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp new file mode 100644 index 0000000000000..73e4f0e101a8c --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U, class ...Args> +// void polymorphic_allocator<T>::construct(U *, Args &&...) + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" +#include "test_allocator.h" + +namespace ex = std::experimental::pmr; + +template <class T> +struct PMATest { + TestResource R; + ex::polymorphic_allocator<T> A; + T* ptr; + bool constructed; + + PMATest() : A(&R), ptr(A.allocate(1)), constructed(false) {} + + template <class ...Args> + void construct(Args&&... args) { + A.construct(ptr, std::forward<Args>(args)...); + constructed = true; + } + + ~PMATest() { + if (constructed) A.destroy(ptr); + A.deallocate(ptr, 1); + } +}; + +template <class T, class ...Args> +bool doTest(UsesAllocatorType UAExpect, Args&&... args) +{ + PMATest<T> TH; + // UNDER TEST // + TH.construct(std::forward<Args>(args)...); + return checkConstruct<Args&&...>(*TH.ptr, UAExpect, &TH.R); + // ------- // +} + + +template <class T, class ...Args> +bool doTestUsesAllocV0(Args&&... args) +{ + PMATest<T> TH; + // UNDER TEST // + TH.construct(std::forward<Args>(args)...); + return checkConstruct<Args&&...>(*TH.ptr, UA_None); + // -------- // +} + + +template <class T, class EAlloc, class ...Args> +bool doTestUsesAllocV1(EAlloc const& ealloc, Args&&... args) +{ + PMATest<T> TH; + // UNDER TEST // + TH.construct(std::allocator_arg, ealloc, std::forward<Args>(args)...); + return checkConstruct<Args&&...>(*TH.ptr, UA_AllocArg, ealloc); + // -------- // +} + +template <class T, class EAlloc, class ...Args> +bool doTestUsesAllocV2(EAlloc const& ealloc, Args&&... args) +{ + PMATest<T> TH; + // UNDER TEST // + TH.construct(std::forward<Args>(args)..., ealloc); + return checkConstruct<Args&&...>(*TH.ptr, UA_AllocLast, ealloc); + // -------- // +} + +template <class Alloc, class ...Args> +void test_pmr_uses_alloc(Args&&... args) +{ + TestResource R(12435); + ex::memory_resource* M = &R; + { + // NotUsesAllocator provides valid signatures for each uses-allocator + // construction but does not supply the required allocator_type typedef. + // Test that we can call these constructors manually without + // polymorphic_allocator interfering. + using T = NotUsesAllocator<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV1<T>(M, std::forward<Args>(args)...))); + assert((doTestUsesAllocV2<T>(M, std::forward<Args>(args)...))); + } + { + // Test T(std::allocator_arg_t, Alloc const&, Args...) construction + using T = UsesAllocatorV1<Alloc, sizeof...(Args)>; + assert((doTest<T>(UA_AllocArg, std::forward<Args>(args)...))); + } + { + // Test T(Args..., Alloc const&) construction + using T = UsesAllocatorV2<Alloc, sizeof...(Args)>; + assert((doTest<T>(UA_AllocLast, std::forward<Args>(args)...))); + } + { + // Test that T(std::allocator_arg_t, Alloc const&, Args...) construction + // is prefered when T(Args..., Alloc const&) is also available. + using T = UsesAllocatorV3<Alloc, sizeof...(Args)>; + assert((doTest<T>(UA_AllocArg, std::forward<Args>(args)...))); + } +} + +// Test that polymorphic_allocator does not prevent us from manually +// doing non-pmr uses-allocator construction. +template <class Alloc, class AllocObj, class ...Args> +void test_non_pmr_uses_alloc(AllocObj const& A, Args&&... args) +{ + { + using T = NotUsesAllocator<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...))); + assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...))); + } + { + using T = UsesAllocatorV1<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...))); + } + { + using T = UsesAllocatorV2<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...))); + } + { + using T = UsesAllocatorV3<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...))); + assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...))); + } +} + +int main() +{ + using ET = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<void>; + using STDA = std::allocator<char>; + using TESTA = test_allocator<char>; + + int value = 42; + const int cvalue = 43; + { + test_pmr_uses_alloc<ET>(); + test_pmr_uses_alloc<PMR>(); + test_pmr_uses_alloc<PMA>(); + test_pmr_uses_alloc<ET>(value); + test_pmr_uses_alloc<PMR>(value); + test_pmr_uses_alloc<PMA>(value); + test_pmr_uses_alloc<ET>(cvalue); + test_pmr_uses_alloc<PMR>(cvalue); + test_pmr_uses_alloc<PMA>(cvalue); + test_pmr_uses_alloc<ET>(cvalue, std::move(value)); + test_pmr_uses_alloc<PMR>(cvalue, std::move(value)); + test_pmr_uses_alloc<PMA>(cvalue, std::move(value)); + } + { + STDA std_alloc; + TESTA test_alloc(42); + test_non_pmr_uses_alloc<STDA>(std_alloc); + test_non_pmr_uses_alloc<TESTA>(test_alloc); + test_non_pmr_uses_alloc<STDA>(std_alloc, value); + test_non_pmr_uses_alloc<TESTA>(test_alloc, value); + test_non_pmr_uses_alloc<STDA>(std_alloc, cvalue); + test_non_pmr_uses_alloc<TESTA>(test_alloc, cvalue); + test_non_pmr_uses_alloc<STDA>(std_alloc, cvalue, std::move(value)); + test_non_pmr_uses_alloc<TESTA>(test_alloc, cvalue, std::move(value)); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp new file mode 100644 index 0000000000000..d60c2f2d90f6d --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// T* polymorphic_allocator<T>::deallocate(T*, size_t size) + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +template <size_t S, size_t Align> +void testForSizeAndAlign() { + using T = typename std::aligned_storage<S, Align>::type; + + TestResource R; + ex::polymorphic_allocator<T> a(&R); + + for (int N = 1; N <= 5; ++N) { + auto ret = a.allocate(N); + assert(R.checkAlloc(ret, N * sizeof(T), alignof(T))); + + a.deallocate(ret, N); + assert(R.checkDealloc(ret, N * sizeof(T), alignof(T))); + + R.reset(); + } +} + +int main() +{ + { + ex::polymorphic_allocator<int> a; + static_assert( + std::is_same<decltype(a.deallocate(nullptr, 0)), void>::value, ""); + } + { + constexpr std::size_t MA = alignof(std::max_align_t); + testForSizeAndAlign<1, 1>(); + testForSizeAndAlign<1, 2>(); + testForSizeAndAlign<1, MA>(); + testForSizeAndAlign<2, 2>(); + testForSizeAndAlign<73, alignof(void*)>(); + testForSizeAndAlign<73, MA>(); + testForSizeAndAlign<13, MA>(); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.pass.cpp new file mode 100644 index 0000000000000..5d907660dce27 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U> +// void polymorphic_allocator<T>::destroy(U * ptr); + +#include <experimental/memory_resource> +#include <type_traits> +#include <new> +#include <cassert> +#include <cstdlib> + +namespace ex = std::experimental::pmr; + +int count = 0; + +struct destroyable +{ + destroyable() { ++count; } + ~destroyable() { --count; } +}; + +int main() +{ + typedef ex::polymorphic_allocator<double> A; + { + A a; + static_assert( + std::is_same<decltype(a.destroy((destroyable*)nullptr)), void>::value, + ""); + } + { + destroyable * ptr = ::new (std::malloc(sizeof(destroyable))) destroyable(); + assert(count == 1); + A{}.destroy(ptr); + assert(count == 0); + std::free(ptr); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp new file mode 100644 index 0000000000000..b59606b9e80de --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// memory_resource * +// polymorphic_allocator<T>::resource() const + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A; + { + A const a; + static_assert( + std::is_same<decltype(a.resource()), ex::memory_resource*>::value + , "" + ); + } + { + ex::memory_resource * mptr = (ex::memory_resource*)42; + A const a(mptr); + assert(a.resource() == mptr); + } + { + A const a(nullptr); + assert(a.resource() == nullptr); + assert(a.resource() == nullptr); + } + { + A const a; + assert(a.resource() == ex::get_default_resource()); + } + { + ex::memory_resource * mptr = (ex::memory_resource*)42; + ex::set_default_resource(mptr); + A const a; + assert(a.resource() == mptr); + assert(a.resource() == ex::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.pass.cpp new file mode 100644 index 0000000000000..353fcafed740f --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator +// polymorphic_allocator<T>::select_on_container_copy_construction() const + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A; + { + A const a; + static_assert( + std::is_same<decltype(a.select_on_container_copy_construction()), A>::value, + ""); + } + { + ex::memory_resource * mptr = (ex::memory_resource*)42; + A const a(mptr); + assert(a.resource() == mptr); + A const other = a.select_on_container_copy_construction(); + assert(other.resource() == ex::get_default_resource()); + assert(a.resource() == mptr); + } + { + ex::memory_resource * mptr = (ex::memory_resource*)42; + ex::set_default_resource(mptr); + A const a(nullptr); + assert(a.resource() == nullptr); + A const other = a.select_on_container_copy_construction(); + assert(other.resource() == ex::get_default_resource()); + assert(other.resource() == mptr); + assert(a.resource() == nullptr); + } +} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..86bf8cc11bb95 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp @@ -0,0 +1,10 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main () {} diff --git a/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..86bf8cc11bb95 --- /dev/null +++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp @@ -0,0 +1,10 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main () {} diff --git a/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.pass.cpp b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.pass.cpp new file mode 100644 index 0000000000000..4de30bccb8169 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.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 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// resource_adaptor_imp<Alloc>::resource_adaptor_imp(Alloc const &) + +#include <experimental/memory_resource> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef CountingAllocator<char> AllocT; + typedef ex::resource_adaptor<AllocT> R; + { + AllocController P; + AllocT const a(P); + R const r(a); + assert(P.copy_constructed == 1); + assert(P.move_constructed == 0); + assert(r.get_allocator() == a); + } + { + AllocController P; + AllocT a(P); + R const r(a); + assert(P.copy_constructed == 1); + assert(P.move_constructed == 0); + assert(r.get_allocator() == a); + } + { + AllocController P; + AllocT const a(P); + R const r(std::move(a)); + assert(P.copy_constructed == 1); + assert(P.move_constructed == 0); + assert(r.get_allocator() == a); + } +} diff --git a/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp new file mode 100644 index 0000000000000..f3ecc98eeaa99 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// resource_adaptor_imp<Alloc>::resource_adaptor_imp(Alloc &&) + +#include <experimental/memory_resource> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef CountingAllocator<char> AllocT; + typedef ex::resource_adaptor<AllocT> R; + { + AllocController P; + AllocT a(P); + R const r(std::move(a)); + assert(P.copy_constructed == 0); + assert(P.move_constructed == 1); + assert(r.get_allocator() == a); + } + { + AllocController P; + R const r(AllocT{P}); + assert(P.copy_constructed == 0); + assert(P.move_constructed == 1); + assert(r.get_allocator() == AllocT{P}); + } +} diff --git a/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.pass.cpp b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.pass.cpp new file mode 100644 index 0000000000000..4abc69f0b3d17 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.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 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// resource_adaptor_imp<Alloc>::resource_adaptor_imp() = default; + +#include <experimental/memory_resource> +#include <memory> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + { + typedef CountingAllocator<char> AllocT; // Not default constructible + typedef ex::resource_adaptor<AllocT> R; + static_assert(!std::is_default_constructible<R>::value, ""); + } + { + typedef std::allocator<char> AllocT; // Is default constructible + typedef ex::resource_adaptor<AllocT> R; + static_assert(std::is_default_constructible<R>::value, ""); + R r; ((void)r); + } +} diff --git a/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp new file mode 100644 index 0000000000000..16b72697593da --- /dev/null +++ b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// void * do_allocate(size_t size, size_t align) +// void do_deallocate(void*, size_t, size_t) + + +#include <experimental/memory_resource> +#include <type_traits> +#include <memory> +#include <exception> +#include <cassert> + +#include "test_macros.h" +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +template <class Alloc> +void check_allocate_deallocate() +{ + typedef ex::resource_adaptor<Alloc> R1; + const std::size_t max_align = alignof(std::max_align_t); + + for (std::size_t s = 1; s < 5012; ++s) + { + for(std::size_t align_req = 1; align_req <= (max_align * 2); align_req *= 2) + { + const std::size_t align_exp = align_req > max_align + ? max_align : align_req; + AllocController P; + R1 r{Alloc(P)}; + ex::memory_resource & m1 = r; + + void * const ret = m1.allocate(s, align_req); + assert(P.alive == 1); + assert(P.alloc_count == 1); + assert(P.checkAllocAtLeast(ret, s, align_exp)); + + assert(((std::size_t)ret % align_exp) == 0); + + m1.deallocate(ret, s, align_req); + assert(P.alive == 0); + assert(P.dealloc_count == 1); + assert(P.checkDeallocMatchesAlloc()); + } + } +} + +void check_alloc_max_size() { + using Alloc = NullAllocator<char>; + using R1 = ex::resource_adaptor<Alloc>; + const std::size_t max_align = alignof(std::max_align_t); + + auto check = [=](std::size_t s, std::size_t align_req) { + const std::size_t align_exp = align_req > max_align + ? max_align : align_req; + AllocController P; + R1 r{Alloc(P)}; + ex::memory_resource & m1 = r; + + void * const ret = m1.allocate(s, align_req); + assert(P.alive == 1); + assert(P.alloc_count == 1); + assert(P.checkAllocAtLeast(ret, s, align_exp)); + + m1.deallocate(ret, s, align_req); + assert(P.alive == 0); + assert(P.dealloc_count == 1); + assert(P.checkDeallocMatchesAlloc()); + }; + + const std::size_t sizeTypeMax = ~0; + const std::size_t testSizeStart = sizeTypeMax - (max_align * 3); + const std::size_t testSizeEnd = sizeTypeMax - max_align; + + for (std::size_t size = testSizeStart; size <= testSizeEnd; ++size) { + for (std::size_t align=1; align <= (max_align * 2); align *= 2) { + check(size, align); + } + } + +#ifndef TEST_HAS_NO_EXCEPTIONS + for (std::size_t size = sizeTypeMax; size > testSizeEnd; --size) { + AllocController P; + R1 r{Alloc(P)}; + ex::memory_resource & m1 = r; + + try { + m1.allocate(size); + assert(false); + } catch (std::exception const&) { + } + } +#endif +} + +int main() +{ + check_allocate_deallocate<CountingAllocator<char>>(); + check_allocate_deallocate<MinAlignedAllocator<char>>(); + check_alloc_max_size(); +} diff --git a/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp new file mode 100644 index 0000000000000..ff4b3179a42ab --- /dev/null +++ b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// bool do_is_equal(memory_resource const &) const noexcept; + +#include <experimental/memory_resource> +#include <type_traits> +#include <memory> +#include <cassert> +#include "test_memory_resource.hpp" + +using std::size_t; +namespace ex = std::experimental::pmr; + +int main() +{ + + typedef CountingAllocator<char> Alloc1; + typedef CountingAllocator<int> RAlloc1; + typedef ex::resource_adaptor<Alloc1> R1; + typedef ex::resource_adaptor<RAlloc1> RR1; + static_assert(std::is_same<R1, RR1>::value, ""); + + typedef std::allocator<char> Alloc2; + typedef ex::resource_adaptor<Alloc2> R2; + static_assert(!std::is_same<R1, R2>::value, ""); + + // equal same type + { + AllocController C; + Alloc1 a1(C); + R1 const r1(a1); + ex::memory_resource const & m1 = r1; + + Alloc1 a2(C); + R1 const r2(a2); + ex::memory_resource const & m2 = r2; + + assert(m1.is_equal(m2)); + assert(m2.is_equal(m1)); + } + // not equal same type + { + AllocController C; + Alloc1 a1(C); + R1 const r1(a1); + ex::memory_resource const & m1 = r1; + + AllocController C2; + Alloc1 a2(C2); + R1 const r2(a2); + ex::memory_resource const & m2 = r2; + + assert(!m1.is_equal(m2)); + assert(!m2.is_equal(m1)); + } + // different allocator types + { + AllocController C; + Alloc1 a1(C); + R1 const r1(a1); + ex::memory_resource const & m1 = r1; + + Alloc2 a2; + R2 const r2(a2); + ex::memory_resource const & m2 = r2; + + assert(!m1.is_equal(m2)); + assert(!m2.is_equal(m1)); + } +} diff --git a/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.pass.cpp b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.pass.cpp new file mode 100644 index 0000000000000..898543fbce4be --- /dev/null +++ b/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +#include <experimental/memory_resource> +#include <type_traits> +#include <memory> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::resource_adaptor<std::allocator<void>> R; + typedef ex::resource_adaptor<std::allocator<long>> R2; + static_assert(std::is_same<R, R2>::value, ""); + { + static_assert(std::is_base_of<ex::memory_resource, R>::value, ""); + static_assert(std::is_same<R::allocator_type, std::allocator<char>>::value, ""); + } + { + static_assert(std::is_default_constructible<R>::value, ""); + static_assert(std::is_copy_constructible<R>::value, ""); + static_assert(std::is_move_constructible<R>::value, ""); + static_assert(std::is_copy_assignable<R>::value, ""); + static_assert(std::is_move_assignable<R>::value, ""); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_deque_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_deque_synop.pass.cpp new file mode 100644 index 0000000000000..5654a785aebb7 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_deque_synop.pass.cpp @@ -0,0 +1,37 @@ +// -*- 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/deque> + +// namespace std { namespace experimental { namespace pmr { +// template <class T> +// using deque = +// ::std::deque<T, polymorphic_allocator<T>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/deque> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +int main() +{ + using StdDeque = std::deque<int, pmr::polymorphic_allocator<int>>; + using PmrDeque = pmr::deque<int>; + static_assert(std::is_same<StdDeque, PmrDeque>::value, ""); + PmrDeque d; + assert(d.get_allocator().resource() == pmr::get_default_resource()); +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_forward_list_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_forward_list_synop.pass.cpp new file mode 100644 index 0000000000000..e834be3912f93 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_forward_list_synop.pass.cpp @@ -0,0 +1,37 @@ +// -*- 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/forward_list> + +// namespace std { namespace experimental { namespace pmr { +// template <class T> +// using forward_list = +// ::std::forward_list<T, polymorphic_allocator<T>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/forward_list> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +int main() +{ + using StdForwardList = std::forward_list<int, pmr::polymorphic_allocator<int>>; + using PmrForwardList = pmr::forward_list<int>; + static_assert(std::is_same<StdForwardList, PmrForwardList>::value, ""); + PmrForwardList d; + assert(d.get_allocator().resource() == pmr::get_default_resource()); +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_list_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_list_synop.pass.cpp new file mode 100644 index 0000000000000..a53b528e877ed --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_list_synop.pass.cpp @@ -0,0 +1,37 @@ +// -*- 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/list> + +// namespace std { namespace experimental { namespace pmr { +// template <class T> +// using list = +// ::std::list<T, polymorphic_allocator<T>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/list> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +int main() +{ + using StdList = std::list<int, pmr::polymorphic_allocator<int>>; + using PmrList = pmr::list<int>; + static_assert(std::is_same<StdList, PmrList>::value, ""); + PmrList d; + assert(d.get_allocator().resource() == pmr::get_default_resource()); +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_map_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_map_synop.pass.cpp new file mode 100644 index 0000000000000..4996d4e6dd252 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_map_synop.pass.cpp @@ -0,0 +1,69 @@ +// -*- 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/map> + +// namespace std { namespace experimental { namespace pmr { +// template <class K, class V, class Compare = less<Key> > +// using map = +// ::std::map<K, V, Compare, polymorphic_allocator<pair<const K, V>>> +// +// template <class K, class V, class Compare = less<Key> > +// using multimap = +// ::std::multimap<K, V, Compare, polymorphic_allocator<pair<const K, V>>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/map> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +int main() +{ + using K = int; + using V = char; + using DC = std::less<int>; + using OC = std::greater<int>; + using P = std::pair<const K, V>; + { + using StdMap = std::map<K, V, DC, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::map<K, V>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + using StdMap = std::map<K, V, OC, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::map<K, V, OC>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + pmr::map<int, int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } + { + using StdMap = std::multimap<K, V, DC, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::multimap<K, V>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + using StdMap = std::multimap<K, V, OC, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::multimap<K, V, OC>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + pmr::multimap<int, int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_regex_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_regex_synop.pass.cpp new file mode 100644 index 0000000000000..f371c8a52f1dc --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_regex_synop.pass.cpp @@ -0,0 +1,57 @@ +// -*- 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/regex> + +// namespace std { namespace experimental { namespace pmr { +// +// template <class BidirectionalIterator> +// using match_results = +// std::match_results<BidirectionalIterator, +// polymorphic_allocator<sub_match<BidirectionalIterator>>>; +// +// typedef match_results<const char*> cmatch; +// typedef match_results<const wchar_t*> wcmatch; +// typedef match_results<string::const_iterator> smatch; +// typedef match_results<wstring::const_iterator> wsmatch; +// +// }}} // namespace std::experimental::pmr + +#include <experimental/regex> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +template <class Iter, class PmrTypedef> +void test_match_result_typedef() { + using StdMR = std::match_results<Iter, pmr::polymorphic_allocator<std::sub_match<Iter>>>; + using PmrMR = pmr::match_results<Iter>; + static_assert(std::is_same<StdMR, PmrMR>::value, ""); + static_assert(std::is_same<PmrMR, PmrTypedef>::value, ""); +} + +int main() +{ + { + test_match_result_typedef<const char*, pmr::cmatch>(); + test_match_result_typedef<const wchar_t*, pmr::wcmatch>(); + test_match_result_typedef<pmr::string::const_iterator, pmr::smatch>(); + test_match_result_typedef<pmr::wstring::const_iterator, pmr::wsmatch>(); + } + { + // Check that std::match_results has been included and is complete. + pmr::smatch s; + assert(s.get_allocator().resource() == pmr::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_set_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_set_synop.pass.cpp new file mode 100644 index 0000000000000..3af1d700504e6 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_set_synop.pass.cpp @@ -0,0 +1,67 @@ +// -*- 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/set> + +// namespace std { namespace experimental { namespace pmr { +// template <class V, class Compare = less<V> > +// using set = +// ::std::set<V, Compare, polymorphic_allocator<V>> +// +// template <class V, class Compare = less<V> > +// using multiset = +// ::std::multiset<V, Compare, polymorphic_allocator<V>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/set> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +int main() +{ + using V = char; + using DC = std::less<V>; + using OC = std::greater<V>; + { + using StdSet = std::set<V, DC, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::set<V>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + using StdSet = std::set<V, OC, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::set<V, OC>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + pmr::set<int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } + { + using StdSet = std::multiset<V, DC, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::multiset<V>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + using StdSet = std::multiset<V, OC, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::multiset<V, OC>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + pmr::multiset<int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_string_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_string_synop.pass.cpp new file mode 100644 index 0000000000000..21889c2da3d2f --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_string_synop.pass.cpp @@ -0,0 +1,73 @@ +// -*- 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/string> + +// namespace std { namespace experimental { namespace pmr { +// template <class Char, class Traits = ...> +// using basic_string = +// ::std::basic_string<Char, Traits, polymorphic_allocator<Char>> +// +// typedef ... string +// typedef ... u16string +// typedef ... u32string +// typedef ... wstring +// +// }}} // namespace std::experimental::pmr + +#include <experimental/string> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "constexpr_char_traits.hpp" + +namespace pmr = std::experimental::pmr; + +template <class Char, class PmrTypedef> +void test_string_typedef() { + using StdStr = std::basic_string<Char, std::char_traits<Char>, + pmr::polymorphic_allocator<Char>>; + using PmrStr = pmr::basic_string<Char>; + static_assert(std::is_same<StdStr, PmrStr>::value, ""); + static_assert(std::is_same<PmrStr, PmrTypedef>::value, ""); +} + +template <class Char, class Traits> +void test_basic_string_alias() { + using StdStr = std::basic_string<Char, Traits, + pmr::polymorphic_allocator<Char>>; + using PmrStr = pmr::basic_string<Char, Traits>; + static_assert(std::is_same<StdStr, PmrStr>::value, ""); +} + +int main() +{ + { + test_string_typedef<char, pmr::string>(); + test_string_typedef<wchar_t, pmr::wstring>(); + test_string_typedef<char16_t, pmr::u16string>(); + test_string_typedef<char32_t, pmr::u32string>(); + } + { + test_basic_string_alias<char, constexpr_char_traits<char>>(); + test_basic_string_alias<wchar_t, constexpr_char_traits<wchar_t>>(); + test_basic_string_alias<char16_t, constexpr_char_traits<char16_t>>(); + test_basic_string_alias<char32_t, constexpr_char_traits<char32_t>>(); + } + { + // Check that std::basic_string has been included and is complete. + pmr::string s; + assert(s.get_allocator().resource() == pmr::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_unordered_map_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_unordered_map_synop.pass.cpp new file mode 100644 index 0000000000000..99c928b7a9fde --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_unordered_map_synop.pass.cpp @@ -0,0 +1,87 @@ +// -*- 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/unordered_map> + +// namespace std { namespace experimental { namespace pmr { +// template <class K, class V, class H = hash<K>, class P = equal_to<K> > +// using unordered_map = +// ::std::unordered_map<K, V, H, P, polymorphic_allocator<pair<const K, V>>> +// +// template <class K, class V, class H = hash<K>, class P = equal_to<K> > +// using unordered_multimap = +// ::std::unordered_multimap<K, V, H, P, polymorphic_allocator<pair<const K, V>>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/unordered_map> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +template <class T> +struct MyHash : std::hash<T> {}; + +template <class T> +struct MyPred : std::equal_to<T> {}; + +int main() +{ + using K = int; + using V = char; + using DH = std::hash<K>; + using MH = MyHash<K>; + using DP = std::equal_to<K>; + using MP = MyPred<K>; + using P = std::pair<const K, V>; + { + using StdMap = std::unordered_map<K, V, DH, DP, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::unordered_map<K, V>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + using StdMap = std::unordered_map<K, V, MH, DP, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::unordered_map<K, V, MH>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + using StdMap = std::unordered_map<K, V, MH, MP, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::unordered_map<K, V, MH, MP>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + pmr::unordered_map<int, int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } + { + using StdMap = std::unordered_multimap<K, V, DH, DP, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::unordered_multimap<K, V>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + using StdMap = std::unordered_multimap<K, V, MH, DP, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::unordered_multimap<K, V, MH>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + using StdMap = std::unordered_multimap<K, V, MH, MP, pmr::polymorphic_allocator<P>>; + using PmrMap = pmr::unordered_multimap<K, V, MH, MP>; + static_assert(std::is_same<StdMap, PmrMap>::value, ""); + } + { + pmr::unordered_multimap<int, int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_unordered_set_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_unordered_set_synop.pass.cpp new file mode 100644 index 0000000000000..d427fe7c4ab01 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_unordered_set_synop.pass.cpp @@ -0,0 +1,85 @@ +// -*- 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/unordered_set> + +// namespace std { namespace experimental { namespace pmr { +// template <class V, class H = hash<V>, class P = equal_to<V> > +// using unordered_set = +// ::std::unordered_set<V, H, P, polymorphic_allocator<V>> +// +// template <class V, class H = hash<V>, class P = equal_to<V> > +// using unordered_multiset = +// ::std::unordered_multiset<V, H, P, polymorphic_allocator<V>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/unordered_set> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +template <class T> +struct MyHash : std::hash<T> {}; + +template <class T> +struct MyPred : std::equal_to<T> {}; + +int main() +{ + using V = char; + using DH = std::hash<V>; + using MH = MyHash<V>; + using DP = std::equal_to<V>; + using MP = MyPred<V>; + { + using StdSet = std::unordered_set<V, DH, DP, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::unordered_set<V>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + using StdSet = std::unordered_set<V, MH, DP, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::unordered_set<V, MH>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + using StdSet = std::unordered_set<V, MH, MP, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::unordered_set<V, MH, MP>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + pmr::unordered_set<int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } + { + using StdSet = std::unordered_multiset<V, DH, DP, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::unordered_multiset<V>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + using StdSet = std::unordered_multiset<V, MH, DP, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::unordered_multiset<V, MH>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + using StdSet = std::unordered_multiset<V, MH, MP, pmr::polymorphic_allocator<V>>; + using PmrSet = pmr::unordered_multiset<V, MH, MP>; + static_assert(std::is_same<StdSet, PmrSet>::value, ""); + } + { + pmr::unordered_multiset<int> m; + assert(m.get_allocator().resource() == pmr::get_default_resource()); + } +} diff --git a/test/std/experimental/memory/memory.resource.aliases/header_vector_synop.pass.cpp b/test/std/experimental/memory/memory.resource.aliases/header_vector_synop.pass.cpp new file mode 100644 index 0000000000000..7dfd3b820b364 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.aliases/header_vector_synop.pass.cpp @@ -0,0 +1,37 @@ +// -*- 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/vector> + +// namespace std { namespace experimental { namespace pmr { +// template <class T> +// using vector = +// ::std::vector<T, polymorphic_allocator<T>> +// +// }}} // namespace std::experimental::pmr + +#include <experimental/vector> +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace pmr = std::experimental::pmr; + +int main() +{ + using StdVector = std::vector<int, pmr::polymorphic_allocator<int>>; + using PmrVector = pmr::vector<int>; + static_assert(std::is_same<StdVector, PmrVector>::value, ""); + PmrVector d; + assert(d.get_allocator().resource() == pmr::get_default_resource()); +} diff --git a/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp b/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp new file mode 100644 index 0000000000000..7aa16ab506fef --- /dev/null +++ b/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +//----------------------------------------------------------------------------- +// TESTING memory_resource * get_default_resource() noexcept; +// memory_resource * set_default_resource(memory_resource*) noexcept; +// +// Concerns: +// A) 'get_default_resource()' returns a non-null memory_resource pointer. +// B) 'get_default_resource()' returns the value set by the last call to +// 'set_default_resource(...)' and 'new_delete_resource()' if no call +// to 'set_default_resource(...)' has occurred. +// C) 'set_default_resource(...)' returns the previous value of the default +// resource. +// D) 'set_default_resource(T* p)' for a non-null 'p' sets the default resource +// to be 'p'. +// E) 'set_default_resource(null)' sets the default resource to +// 'new_delete_resource()'. +// F) 'get_default_resource' and 'set_default_resource' are noexcept. + + +#include <experimental/memory_resource> +#include <cassert> + +#include "test_memory_resource.hpp" + +using namespace std::experimental::pmr; + +int main() { + TestResource R; + { // Test (A) and (B) + memory_resource* p = get_default_resource(); + assert(p != nullptr); + assert(p == new_delete_resource()); + assert(p == get_default_resource()); + } + { // Test (C) and (D) + memory_resource *expect = &R; + memory_resource *old = set_default_resource(expect); + assert(old != nullptr); + assert(old == new_delete_resource()); + + memory_resource *p = get_default_resource(); + assert(p != nullptr); + assert(p == expect); + assert(p == get_default_resource()); + } + { // Test (E) + memory_resource* old = set_default_resource(nullptr); + assert(old == &R); + memory_resource* p = get_default_resource(); + assert(p != nullptr); + assert(p == new_delete_resource()); + assert(p == get_default_resource()); + } + { // Test (F) + static_assert(noexcept(get_default_resource()), + "get_default_resource() must be noexcept"); + + static_assert(noexcept(set_default_resource(nullptr)), + "set_default_resource() must be noexcept"); + } +} diff --git a/test/std/experimental/memory/memory.resource.global/new_delete_resource.pass.cpp b/test/std/experimental/memory/memory.resource.global/new_delete_resource.pass.cpp new file mode 100644 index 0000000000000..412e3323d1bad --- /dev/null +++ b/test/std/experimental/memory/memory.resource.global/new_delete_resource.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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// memory_resource * new_delete_resource() + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "count_new.hpp" + +namespace ex = std::experimental::pmr; + +struct assert_on_compare : public ex::memory_resource +{ +protected: + virtual void * do_allocate(size_t, size_t) + { assert(false); } + + virtual void do_deallocate(void *, size_t, size_t) + { assert(false); } + + virtual bool do_is_equal(ex::memory_resource const &) const noexcept + { assert(false); } +}; + +void test_return() +{ + { + static_assert(std::is_same< + decltype(ex::new_delete_resource()), ex::memory_resource* + >::value, ""); + } + // assert not null + { + assert(ex::new_delete_resource()); + } + // assert same return value + { + assert(ex::new_delete_resource() == ex::new_delete_resource()); + } +} + +void test_equality() +{ + // Same object + { + ex::memory_resource & r1 = *ex::new_delete_resource(); + ex::memory_resource & r2 = *ex::new_delete_resource(); + // check both calls returned the same object + assert(&r1 == &r2); + // check for proper equality semantics + assert(r1 == r2); + assert(r2 == r1); + assert(!(r1 != r2)); + assert(!(r2 != r1)); + } + // Different types + { + ex::memory_resource & r1 = *ex::new_delete_resource(); + assert_on_compare c; + ex::memory_resource & r2 = c; + assert(r1 != r2); + assert(!(r1 == r2)); + } +} + +void test_allocate_deallocate() +{ + ex::memory_resource & r1 = *ex::new_delete_resource(); + + globalMemCounter.reset(); + + void *ret = r1.allocate(50); + assert(ret); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkLastNewSizeEq(50)); + + r1.deallocate(ret, 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + +} + +int main() +{ + static_assert(noexcept(ex::new_delete_resource()), "Must be noexcept"); + test_return(); + test_equality(); + test_allocate_deallocate(); +} diff --git a/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp b/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp new file mode 100644 index 0000000000000..f263df30ef4d9 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp @@ -0,0 +1,118 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++experimental +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// memory_resource * null_memory_resource() + +#include <experimental/memory_resource> +#include <new> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "count_new.hpp" + +namespace ex = std::experimental::pmr; + +struct assert_on_compare : public ex::memory_resource +{ +protected: + virtual void * do_allocate(size_t, size_t) + { assert(false); } + + virtual void do_deallocate(void *, size_t, size_t) + { assert(false); } + + virtual bool do_is_equal(ex::memory_resource const &) const noexcept + { assert(false); } +}; + +void test_return() +{ + { + static_assert(std::is_same< + decltype(ex::null_memory_resource()), ex::memory_resource* + >::value, ""); + } + // Test that the returned value is not null + { + assert(ex::null_memory_resource()); + } + // Test the same value is returned by repeated calls. + { + assert(ex::null_memory_resource() == ex::null_memory_resource()); + } +} + +void test_equality() +{ + // Same object + { + ex::memory_resource & r1 = *ex::null_memory_resource(); + ex::memory_resource & r2 = *ex::null_memory_resource(); + // check both calls returned the same object + assert(&r1 == &r2); + // check for proper equality semantics + assert(r1 == r2); + assert(r2 == r1); + assert(!(r1 != r2)); + assert(!(r2 != r1)); + // check the is_equal method + assert(r1.is_equal(r2)); + assert(r2.is_equal(r1)); + } + // Different types + { + ex::memory_resource & r1 = *ex::null_memory_resource(); + assert_on_compare c; + ex::memory_resource & r2 = c; + assert(r1 != r2); + assert(!(r1 == r2)); + assert(!r1.is_equal(r2)); + } +} + +void test_allocate() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + DisableAllocationGuard g; // null_memory_resource shouldn't allocate. + try { + ex::null_memory_resource()->allocate(1); + assert(false); + } catch (std::bad_alloc const &) { + // do nothing + } catch (...) { + assert(false); + } +#endif +} + +void test_deallocate() +{ + globalMemCounter.reset(); + + int x = 42; + ex::null_memory_resource()->deallocate(nullptr, 0); + ex::null_memory_resource()->deallocate(&x, 0); + + assert(globalMemCounter.checkDeleteCalledEq(0)); + assert(globalMemCounter.checkDeleteArrayCalledEq(0)); +} + +int main() +{ + test_return(); + test_equality(); + test_allocate(); + test_deallocate(); +} diff --git a/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp b/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..9a59227abdd98 --- /dev/null +++ b/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp @@ -0,0 +1,13 @@ +// -*- 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/experimental/memory/memory.resource/construct.fail.cpp b/test/std/experimental/memory/memory.resource/construct.fail.cpp new file mode 100644 index 0000000000000..d990714acfd14 --- /dev/null +++ b/test/std/experimental/memory/memory.resource/construct.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 + +// <experimental/memory_resource> + +// Check that memory_resource is not constructible + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + ex::memory_resource m; // expected-error {{variable type 'ex::memory_resource' is an abstract class}} +} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.pass.cpp new file mode 100644 index 0000000000000..0ccdeed3c54f7 --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.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 + +// <experimental/memory_resource> + +// bool operator==(memory_resource const &, memory_resource const &) noexcept; + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + // check return types + { + ex::memory_resource const * mr1(nullptr); + ex::memory_resource const * mr2(nullptr); + static_assert(std::is_same<decltype(*mr1 == *mr2), bool>::value, ""); + static_assert(noexcept(*mr1 == *mr2), ""); + } + // equal + { + TestResource r1(1); + TestResource r2(1); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r2; + + assert(mr1 == mr2); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(0)); + + assert(mr2 == mr1); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(1)); + } + // equal same object + { + TestResource r1(1); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r1; + + assert(mr1 == mr2); + assert(r1.checkIsEqualCalledEq(0)); + + assert(mr2 == mr1); + assert(r1.checkIsEqualCalledEq(0)); + } + // not equal + { + TestResource r1(1); + TestResource r2(2); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r2; + + assert(!(mr1 == mr2)); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(0)); + + assert(!(mr2 == mr1)); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(1)); + } +} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.eq/not_equal.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.eq/not_equal.pass.cpp new file mode 100644 index 0000000000000..ede1bfdf9baca --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.eq/not_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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// bool operator!=(memory_resource const &, memory_resource const &) noexcept; + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + // check return types + { + ex::memory_resource const * mr1(nullptr); + ex::memory_resource const * mr2(nullptr); + static_assert(std::is_same<decltype(*mr1 != *mr2), bool>::value, ""); + static_assert(noexcept(*mr1 != *mr2), ""); + } + // not equal + { + TestResource r1(1); + TestResource r2(2); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r2; + + assert(mr1 != mr2); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(0)); + + assert(mr2 != mr1); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(1)); + } + // equal + { + TestResource r1(1); + TestResource r2(1); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r2; + + assert(!(mr1 != mr2)); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(0)); + + assert(!(mr2 != mr1)); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(1)); + } + // equal same object + { + TestResource r1(1); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r1; + + assert(!(mr1 != mr2)); + assert(r1.checkIsEqualCalledEq(0)); + + assert(!(mr2 != mr1)); + assert(r1.checkIsEqualCalledEq(0)); + } +} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..86bf8cc11bb95 --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp @@ -0,0 +1,10 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main () {} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp b/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp new file mode 100644 index 0000000000000..eddfede29630f --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/memory_resource> + +// memory_resource::do_allocate(size_t, size_t); /* protected */ +// memory_resource::do_deallocate(void*, size_t, size_t); /* protected */ +// memory_resource::do_is_equal(memory_resource const&); /* protected */ + +#include <experimental/memory_resource> + +namespace ex = std::experimental::pmr; + +int main() { + ex::memory_resource *m = ex::new_delete_resource(); + m->do_allocate(0, 0); // expected-error{{'do_allocate' is a protected member}} + m->do_deallocate(nullptr, 0, 0); // expected-error{{'do_deallocate' is a protected member}} + m->do_is_equal(*m); // expected-error{{'do_is_equal' is a protected member}} +}
\ No newline at end of file diff --git a/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp new file mode 100644 index 0000000000000..26cf903fe0d8e --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <experimental/memory_resource> + +// UNSUPPORTED: c++98, c++03 + +//------------------------------------------------------------------------------ +// TESTING void * memory_resource::allocate(size_t, size_t = max_align) +// +// Concerns: +// A) 'memory_resource' contains a member 'allocate' with the required +// signature, including the default alignment parameter. +// B) The return type of 'allocate' is 'void*'. +// C) 'allocate' is not marked as 'noexcept'. +// D) Invoking 'allocate' invokes 'do_allocate' with the same arguments. +// E) If 'do_allocate' throws then 'allocate' propagates that exception. + +#include <experimental/memory_resource> +#include <type_traits> +#include <cstddef> +#include <cassert> + +#include "test_macros.h" +#include "test_memory_resource.hpp" + +using std::experimental::pmr::memory_resource; + +int main() +{ + TestResource R(42); + auto& P = R.getController(); + memory_resource& M = R; + { + static_assert( + std::is_same<decltype(M.allocate(0, 0)), void*>::value + , "Must be void*" + ); + static_assert( + std::is_same<decltype(M.allocate(0)), void*>::value + , "Must be void*" + ); + } + { + static_assert( + ! noexcept(M.allocate(0, 0)) + , "Must not be noexcept." + ); + static_assert( + ! noexcept(M.allocate(0)) + , "Must not be noexcept." + ); + } + { + int s = 42; + int a = 64; + void* p = M.allocate(s, a); + assert(P.alloc_count == 1); + assert(P.checkAlloc(p, s, a)); + + s = 128; + a = MaxAlignV; + p = M.allocate(s); + assert(P.alloc_count == 2); + assert(P.checkAlloc(p, s, a)); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + TestResource R2; + auto& P = R2.getController(); + P.throw_on_alloc = true; + memory_resource& M2 = R2; + try { + M2.allocate(42); + assert(false); + } catch (TestException const&) { + // do nothing. + } catch (...) { + assert(false); + } + } +#endif +} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp new file mode 100644 index 0000000000000..d1a4ab2b8196f --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <experimental/memory_resource> + +// UNSUPPORTED: c++98, c++03 + +//------------------------------------------------------------------------------ +// TESTING void * memory_resource::deallocate(void *, size_t, size_t = max_align) +// +// Concerns: +// A) 'memory_resource' contains a member 'deallocate' with the required +// signature, including the default alignment parameter. +// B) The return type of 'deallocate' is 'void'. +// C) 'deallocate' is not marked as 'noexcept'. +// D) Invoking 'deallocate' invokes 'do_deallocate' with the same arguments. + + +#include <experimental/memory_resource> +#include <type_traits> +#include <cstddef> +#include <cassert> + +#include "test_memory_resource.hpp" + +using std::experimental::pmr::memory_resource; + +int main() +{ + NullResource R(42); + auto& P = R.getController(); + memory_resource& M = R; + { + static_assert( + std::is_same<decltype(M.deallocate(nullptr, 0, 0)), void>::value + , "Must be void" + ); + static_assert( + std::is_same<decltype(M.deallocate(nullptr, 0)), void>::value + , "Must be void" + ); + } + { + static_assert( + ! noexcept(M.deallocate(nullptr, 0, 0)) + , "Must not be noexcept." + ); + static_assert( + ! noexcept(M.deallocate(nullptr, 0)) + , "Must not be noexcept." + ); + } + { + int s = 100; + int a = 64; + void* p = reinterpret_cast<void*>(640); + M.deallocate(p, s, a); + assert(P.dealloc_count == 1); + assert(P.checkDealloc(p, s, a)); + + s = 128; + a = alignof(std::max_align_t); + p = reinterpret_cast<void*>(12800); + M.deallocate(p, s); + assert(P.dealloc_count == 2); + assert(P.checkDealloc(p, s, a)); + } +} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp new file mode 100644 index 0000000000000..9e1d28618f92d --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/memory_resource> + +//------------------------------------------------------------------------------ +// TESTING virtual ~memory_resource() +// +// Concerns: +// A) 'memory_resource' is destructible. +// B) The destructor is implicitly marked noexcept. +// C) The destructor is marked virtual. + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +using std::experimental::pmr::memory_resource; + +int main() +{ + static_assert( + std::has_virtual_destructor<memory_resource>::value + , "Must have virtual destructor" + ); + static_assert( + std::is_nothrow_destructible<memory_resource>::value, + "Must be nothrow destructible" + ); + static_assert( + std::is_abstract<memory_resource>::value + , "Must be abstract" + ); + // Check that the destructor of `TestResource` is called when + // it is deleted as a pointer to `memory_resource` + { + using TR = TestResource; + memory_resource* M = new TR(42); + assert(TR::resource_alive == 1); + assert(TR::resource_constructed == 1); + assert(TR::resource_destructed == 0); + + delete M; + + assert(TR::resource_alive == 0); + assert(TR::resource_constructed == 1); + assert(TR::resource_destructed == 1); + } +} diff --git a/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp new file mode 100644 index 0000000000000..32792cf867a61 --- /dev/null +++ b/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <experimental/memory_resource> + +//------------------------------------------------------------------------------ +// TESTING virtual bool is_equal(memory_resource const &) const noexcept +// +// Concerns: +// A) 'memory_resource' provides a function 'is_equal' with the required +// signature. +// B) 'is_equal' is noexcept. +// C) 'do_is_equal' is called using the same arguments passed to 'is_equal' +// and the resulting value is returned. +// D) 'do_is_equal' is called on the LHS object and not the RHS object. + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> +#include "test_memory_resource.hpp" + +using std::experimental::pmr::memory_resource; + +int main() +{ + { + memory_resource const* r1 = nullptr; + memory_resource const* r2 = nullptr; + static_assert( + noexcept(r1->is_equal(*r2)) + , "is_equal must be noexcept" + ); + } + { + TestResource1 R1(1); + auto& P1 = R1.getController(); + memory_resource const& M1 = R1; + + TestResource2 R2(1); + auto& P2 = R2.getController(); + memory_resource const& M2 = R2; + + assert(M1.is_equal(M2) == false); + assert(P1.checkIsEqualCalledEq(1)); + assert(P2.checkIsEqualCalledEq(0)); + + assert(M2.is_equal(M1) == false); + assert(P2.checkIsEqualCalledEq(1)); + assert(P1.checkIsEqualCalledEq(1)); + } + { + TestResource1 R1(1); + auto& P1 = R1.getController(); + memory_resource const& M1 = R1; + + TestResource1 R2(2); + auto& P2 = R2.getController(); + memory_resource const& M2 = R2; + + assert(M1.is_equal(M2) == false); + assert(P1.checkIsEqualCalledEq(1)); + assert(P2.checkIsEqualCalledEq(0)); + + assert(M2.is_equal(M1) == false); + assert(P2.checkIsEqualCalledEq(1)); + assert(P1.checkIsEqualCalledEq(1)); + } + { + TestResource1 R1(1); + auto& P1 = R1.getController(); + memory_resource const& M1 = R1; + + TestResource1 R2(1); + auto& P2 = R2.getController(); + memory_resource const& M2 = R2; + + assert(M1.is_equal(M2) == true); + assert(P1.checkIsEqualCalledEq(1)); + assert(P2.checkIsEqualCalledEq(0)); + + assert(M2.is_equal(M1) == true); + assert(P2.checkIsEqualCalledEq(1)); + assert(P1.checkIsEqualCalledEq(1)); + } +} diff --git a/test/std/experimental/memory/nothing_to_do.pass.cpp b/test/std/experimental/memory/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..9a59227abdd98 --- /dev/null +++ b/test/std/experimental/memory/nothing_to_do.pass.cpp @@ -0,0 +1,13 @@ +// -*- 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/experimental/optional/optional.bad_optional_access/default.pass.cpp b/test/std/experimental/optional/optional.bad_optional_access/default.pass.cpp index cecf98a3518b3..c166bb72a8379 100644 --- a/test/std/experimental/optional/optional.bad_optional_access/default.pass.cpp +++ b/test/std/experimental/optional/optional.bad_optional_access/default.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 + // <optional> // class bad_optional_access is default constructible @@ -16,8 +18,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::bad_optional_access; bad_optional_access ex; -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.bad_optional_access/derive.pass.cpp b/test/std/experimental/optional/optional.bad_optional_access/derive.pass.cpp index c13d6603990a1..4630165f07080 100644 --- a/test/std/experimental/optional/optional.bad_optional_access/derive.pass.cpp +++ b/test/std/experimental/optional/optional.bad_optional_access/derive.pass.cpp @@ -7,19 +7,19 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 + // <optional> -// class bad_optional_access : public logic_error +// class bad_optional_access : public logic_error #include <experimental/optional> #include <type_traits> int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::bad_optional_access; static_assert(std::is_base_of<std::logic_error, bad_optional_access>::value, ""); static_assert(std::is_convertible<bad_optional_access*, std::logic_error*>::value, ""); -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.comp_with_t/equal.pass.cpp b/test/std/experimental/optional/optional.comp_with_t/equal.pass.cpp index e796723cc097c..749fa7dcf0a1e 100644 --- a/test/std/experimental/optional/optional.comp_with_t/equal.pass.cpp +++ b/test/std/experimental/optional/optional.comp_with_t/equal.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator==(const optional<T>& x, const T& v); @@ -14,8 +15,6 @@ #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,16 +26,13 @@ struct X constexpr bool operator == ( const X &lhs, const X &rhs ) { return lhs.i_ == rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 { typedef X T; typedef optional<T> O; - + constexpr T val(2); constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -47,12 +43,11 @@ int main() static_assert ( !(o3 == T(1)), "" ); static_assert ( (o3 == T(2)), "" ); static_assert ( (o3 == val), "" ); - + static_assert ( !(T(1) == o1), "" ); static_assert ( (T(1) == o2), "" ); static_assert ( !(T(1) == o3), "" ); static_assert ( (T(2) == o3), "" ); static_assert ( (val == o3), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.comp_with_t/greater.pass.cpp b/test/std/experimental/optional/optional.comp_with_t/greater.pass.cpp index cf3923bb4fb0b..c4d95a1c878ff 100644 --- a/test/std/experimental/optional/optional.comp_with_t/greater.pass.cpp +++ b/test/std/experimental/optional/optional.comp_with_t/greater.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator>(const optional<T>& x, const T& v); @@ -14,8 +15,6 @@ #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,13 +26,9 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 - { typedef X T; typedef optional<T> O; @@ -57,5 +52,4 @@ int main() static_assert ( !(val > o3), "" ); // equal static_assert ( (T(3) > o3), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.comp_with_t/greater_equal.pass.cpp b/test/std/experimental/optional/optional.comp_with_t/greater_equal.pass.cpp index 85fea1377b3cd..ce1cd9f984812 100644 --- a/test/std/experimental/optional/optional.comp_with_t/greater_equal.pass.cpp +++ b/test/std/experimental/optional/optional.comp_with_t/greater_equal.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator>=(const optional<T>& x, const T& v); @@ -14,8 +15,6 @@ #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,13 +26,9 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 - { typedef X T; typedef optional<T> O; @@ -57,5 +52,4 @@ int main() static_assert ( (val >= o3), "" ); // equal static_assert ( (T(3) >= o3), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.comp_with_t/less_equal.pass.cpp b/test/std/experimental/optional/optional.comp_with_t/less_equal.pass.cpp index 333f7cdea2197..c519bde1e9f29 100644 --- a/test/std/experimental/optional/optional.comp_with_t/less_equal.pass.cpp +++ b/test/std/experimental/optional/optional.comp_with_t/less_equal.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator<=(const optional<T>& x, const T& v); @@ -14,8 +15,6 @@ #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,13 +26,9 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 - { typedef X T; typedef optional<T> O; @@ -57,5 +52,4 @@ int main() static_assert ( (val <= o3), "" ); // equal static_assert ( !(T(3) <= o3), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.comp_with_t/less_than.pass.cpp b/test/std/experimental/optional/optional.comp_with_t/less_than.pass.cpp index e35df21bbabb2..ee1e98f2b8c9d 100644 --- a/test/std/experimental/optional/optional.comp_with_t/less_than.pass.cpp +++ b/test/std/experimental/optional/optional.comp_with_t/less_than.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator<(const optional<T>& x, const T& v); @@ -14,8 +15,6 @@ #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,13 +26,9 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 - { typedef X T; typedef optional<T> O; @@ -57,5 +52,4 @@ int main() static_assert ( !(val < o3), "" ); // equal static_assert ( !(T(3) < o3), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.comp_with_t/not_equal.pass.cpp b/test/std/experimental/optional/optional.comp_with_t/not_equal.pass.cpp index 0dad68d386354..a3daa02d5dbb2 100644 --- a/test/std/experimental/optional/optional.comp_with_t/not_equal.pass.cpp +++ b/test/std/experimental/optional/optional.comp_with_t/not_equal.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator!=(const optional<T>& x, const T& v); @@ -14,8 +15,6 @@ #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,16 +26,13 @@ struct X constexpr bool operator == ( const X &lhs, const X &rhs ) { return lhs.i_ == rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 { typedef X T; typedef optional<T> O; - + constexpr T val(2); constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -47,12 +43,11 @@ int main() static_assert ( (o3 != T(1)), "" ); static_assert ( !(o3 != T(2)), "" ); static_assert ( !(o3 != val), "" ); - + static_assert ( (T(1) != o1), "" ); static_assert ( !(T(1) != o2), "" ); static_assert ( (T(1) != o3), "" ); static_assert ( !(T(2) != o3), "" ); static_assert ( !(val != o3), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.hash/hash.pass.cpp b/test/std/experimental/optional/optional.hash/hash.pass.cpp index 9e5fb55c833fa..21126740bf860 100644 --- a/test/std/experimental/optional/optional.hash/hash.pass.cpp +++ b/test/std/experimental/optional/optional.hash/hash.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> struct hash<optional<T>>; @@ -19,7 +20,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; { @@ -43,5 +43,4 @@ int main() opt = std::unique_ptr<int>(new int(3)); assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt)); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.inplace/in_place_t.pass.cpp b/test/std/experimental/optional/optional.inplace/in_place_t.pass.cpp index 360b9d91671e0..b63977bb69ff2 100644 --- a/test/std/experimental/optional/optional.inplace/in_place_t.pass.cpp +++ b/test/std/experimental/optional/optional.inplace/in_place_t.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // struct in_place_t{}; @@ -15,8 +16,6 @@ #include <experimental/optional> #include <type_traits> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::in_place_t; using std::experimental::in_place; @@ -28,15 +27,10 @@ test(const in_place_t&) return 3; } -#endif - int main() { -#if _LIBCPP_STD_VER > 11 - static_assert((std::is_class<in_place_t>::value), ""); static_assert((std::is_empty<in_place_t>::value), ""); - + static_assert(test(in_place) == 3, ""); -#endif } diff --git a/test/std/experimental/optional/optional.nullops/equal.pass.cpp b/test/std/experimental/optional/optional.nullops/equal.pass.cpp index 931db61442563..79a5a7e06fa46 100644 --- a/test/std/experimental/optional/optional.nullops/equal.pass.cpp +++ b/test/std/experimental/optional/optional.nullops/equal.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// - +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept; @@ -17,15 +17,14 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; - + { typedef int T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -37,5 +36,4 @@ int main() static_assert (noexcept(nullopt == o1), ""); static_assert (noexcept(o1 == nullopt), ""); } -#endif } diff --git a/test/std/experimental/optional/optional.nullops/greater.pass.cpp b/test/std/experimental/optional/optional.nullops/greater.pass.cpp index b72a4d3f1a6a4..15b22005b830a 100644 --- a/test/std/experimental/optional/optional.nullops/greater.pass.cpp +++ b/test/std/experimental/optional/optional.nullops/greater.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// - +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept; @@ -17,7 +17,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; @@ -25,7 +24,7 @@ int main() { typedef int T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -37,5 +36,4 @@ int main() static_assert (noexcept(nullopt > o1), ""); static_assert (noexcept(o1 > nullopt), ""); } -#endif } diff --git a/test/std/experimental/optional/optional.nullops/greater_equal.pass.cpp b/test/std/experimental/optional/optional.nullops/greater_equal.pass.cpp index 86c8743b55589..313770ff408e2 100644 --- a/test/std/experimental/optional/optional.nullops/greater_equal.pass.cpp +++ b/test/std/experimental/optional/optional.nullops/greater_equal.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// - +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator>=(const optional<T>& x, nullopt_t) noexcept; @@ -17,7 +17,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; @@ -25,7 +24,7 @@ int main() { typedef int T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -37,5 +36,4 @@ int main() static_assert (noexcept(nullopt >= o1), ""); static_assert (noexcept(o1 >= nullopt), ""); } -#endif } diff --git a/test/std/experimental/optional/optional.nullops/less_equal.pass.cpp b/test/std/experimental/optional/optional.nullops/less_equal.pass.cpp index 3e8444bc73f0b..cddb27e93a6a4 100644 --- a/test/std/experimental/optional/optional.nullops/less_equal.pass.cpp +++ b/test/std/experimental/optional/optional.nullops/less_equal.pass.cpp @@ -25,7 +25,7 @@ int main() { typedef int T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2{1}; // engaged diff --git a/test/std/experimental/optional/optional.nullops/less_than.pass.cpp b/test/std/experimental/optional/optional.nullops/less_than.pass.cpp index 149c809b04035..fdb400700d832 100644 --- a/test/std/experimental/optional/optional.nullops/less_than.pass.cpp +++ b/test/std/experimental/optional/optional.nullops/less_than.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// - +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator<(const optional<T>& x, nullopt_t) noexcept; @@ -17,7 +17,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; @@ -25,7 +24,7 @@ int main() { typedef int T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -37,5 +36,4 @@ int main() static_assert (noexcept(nullopt < o1), ""); static_assert (noexcept(o1 < nullopt), ""); } -#endif } diff --git a/test/std/experimental/optional/optional.nullops/not_equal.pass.cpp b/test/std/experimental/optional/optional.nullops/not_equal.pass.cpp index 6f28edf6d266e..70ae0f1d885ca 100644 --- a/test/std/experimental/optional/optional.nullops/not_equal.pass.cpp +++ b/test/std/experimental/optional/optional.nullops/not_equal.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// - +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept; @@ -17,15 +17,14 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; - + { typedef int T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2{1}; // engaged @@ -37,5 +36,4 @@ int main() static_assert (noexcept(nullopt != o1), ""); static_assert (noexcept(o1 != nullopt), ""); } -#endif } diff --git a/test/std/experimental/optional/optional.nullopt/nullopt_t.pass.cpp b/test/std/experimental/optional/optional.nullopt/nullopt_t.pass.cpp index de1e83b653ce1..8ad49c7485d0e 100644 --- a/test/std/experimental/optional/optional.nullopt/nullopt_t.pass.cpp +++ b/test/std/experimental/optional/optional.nullopt/nullopt_t.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // struct nullopt_t{see below}; @@ -15,8 +16,6 @@ #include <experimental/optional> #include <type_traits> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; @@ -28,16 +27,12 @@ test(const nullopt_t&) return 3; } -#endif - int main() { -#if _LIBCPP_STD_VER > 11 static_assert((std::is_class<nullopt_t>::value), ""); static_assert((std::is_empty<nullopt_t>::value), ""); static_assert((std::is_literal_type<nullopt_t>::value), ""); static_assert((!std::is_default_constructible<nullopt_t>::value), ""); - + static_assert(test(nullopt) == 3, ""); -#endif } diff --git a/test/std/experimental/optional/optional.object/optional.object.assign/assign_value.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.assign/assign_value.pass.cpp index e256a098f1ac7..3d0d2e03158b0 100644 --- a/test/std/experimental/optional/optional.object/optional.object.assign/assign_value.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.assign/assign_value.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class U> optional<T>& operator=(U&& v); @@ -16,19 +17,14 @@ #include <cassert> #include <memory> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X { }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 static_assert(std::is_assignable<optional<int>, int>::value, ""); static_assert(std::is_assignable<optional<int>, int&>::value, ""); static_assert(std::is_assignable<optional<int>&, int>::value, ""); @@ -68,5 +64,4 @@ int main() assert(static_cast<bool>(opt) == true); assert(**opt == 3); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.assign/copy.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.assign/copy.pass.cpp index 999d03d3a8855..89ea345029c2f 100644 --- a/test/std/experimental/optional/optional.object/optional.object.assign/copy.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.assign/copy.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -16,8 +17,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -34,11 +33,8 @@ struct X bool X::throw_now = false; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<int> opt; constexpr optional<int> opt2; @@ -87,5 +83,4 @@ int main() assert(static_cast<bool>(opt) == false); } } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.assign/emplace.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.assign/emplace.pass.cpp index ec98ef4491538..94f2bb21a4759 100644 --- a/test/std/experimental/optional/optional.object/optional.object.assign/emplace.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.assign/emplace.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -17,8 +18,6 @@ #include <cassert> #include <memory> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; class X @@ -55,11 +54,8 @@ public: bool Z::dtor_called = false; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<int> opt; opt.emplace(); @@ -145,5 +141,4 @@ int main() assert(Z::dtor_called == true); } } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp index aada0f4ec535e..fec37408e43b5 100644 --- a/test/std/experimental/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -18,8 +19,6 @@ #include <cassert> #include <vector> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; class X @@ -60,7 +59,7 @@ public: static bool dtor_called; constexpr Z() : i_(0) {} constexpr Z(int i) : i_(i) {} - constexpr Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) + Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {throw 6;} ~Z() {dtor_called = true;} @@ -70,11 +69,8 @@ public: bool Z::dtor_called = false; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { X x; { @@ -113,5 +109,4 @@ int main() assert(Z::dtor_called == true); } } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.assign/move.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.assign/move.pass.cpp index 3e084e5b7dc24..fa00f5602c7fd 100644 --- a/test/std/experimental/optional/optional.object/optional.object.assign/move.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.assign/move.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -18,8 +19,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -42,11 +41,8 @@ struct Y {}; bool X::throw_now = false; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { static_assert(std::is_nothrow_move_assignable<optional<int>>::value, ""); optional<int> opt; @@ -100,5 +96,4 @@ int main() { static_assert(std::is_nothrow_move_assignable<optional<Y>>::value, ""); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp index 7f39744f0557d..b1d851b32f4cd 100644 --- a/test/std/experimental/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // optional<T>& operator=(nullopt_t) noexcept; @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; @@ -29,11 +28,8 @@ struct X bool X::dtor_called = false; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<int> opt; static_assert(noexcept(opt = nullopt) == true, ""); @@ -63,5 +59,4 @@ int main() assert(static_cast<bool>(opt) == false); } } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/copy.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/copy.pass.cpp index 7d401de1d9789..144af2e3a7dc7 100644 --- a/test/std/experimental/optional/optional.object/optional.object.ctor/copy.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.ctor/copy.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -16,8 +17,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; template <class T> @@ -76,11 +75,8 @@ public: }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { typedef int T; optional<T> rhs; @@ -121,5 +117,4 @@ int main() optional<T> rhs(Z(3)); test(rhs, true); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/default.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/default.pass.cpp index 6a1763de22bd6..d24a1ac69b866 100644 --- a/test/std/experimental/optional/optional.object/optional.object.ctor/default.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.ctor/default.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr optional() noexcept; @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; template <class Opt> @@ -55,13 +54,9 @@ struct X X(); }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 test_constexpr<optional<int>>(); test_constexpr<optional<int*>>(); test<optional<X>>(); -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp index 014ee859e8a97..dc1666b103625 100644 --- a/test/std/experimental/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp @@ -69,7 +69,7 @@ int main() struct test_constexpr_ctor : public optional<int> { - constexpr test_constexpr_ctor(in_place_t, int i) + constexpr test_constexpr_ctor(in_place_t, int i) : optional<int>(in_place, i) {} }; @@ -97,7 +97,7 @@ int main() struct test_constexpr_ctor : public optional<Y> { - constexpr test_constexpr_ctor(in_place_t) + constexpr test_constexpr_ctor(in_place_t) : optional<Y>(in_place) {} }; @@ -110,7 +110,7 @@ int main() struct test_constexpr_ctor : public optional<Y> { - constexpr test_constexpr_ctor(in_place_t, int i) + constexpr test_constexpr_ctor(in_place_t, int i) : optional<Y>(in_place, i) {} }; @@ -123,7 +123,7 @@ int main() struct test_constexpr_ctor : public optional<Y> { - constexpr test_constexpr_ctor(in_place_t, int i, int j) + constexpr test_constexpr_ctor(in_place_t, int i, int j) : optional<Y>(in_place, i, j) {} }; diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp index 7a98e0bf31f3e..9bd6b18989fc9 100644 --- a/test/std/experimental/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -19,8 +20,6 @@ #include <vector> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::in_place_t; using std::experimental::in_place; @@ -60,19 +59,15 @@ class Z public: constexpr Z() : i_(0) {} constexpr Z(int i) : i_(i) {} - constexpr Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) + Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {throw 6;} friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_ && x.j_ == y.j_;} }; - -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { static_assert(!std::is_constructible<X, std::initializer_list<int>&>::value, ""); static_assert(!std::is_constructible<optional<X>, std::initializer_list<int>&>::value, ""); @@ -98,10 +93,12 @@ int main() struct test_constexpr_ctor : public optional<Y> { - constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i) + constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i) : optional<Y>(in_place, i) {} }; + constexpr test_constexpr_ctor dopt(in_place, {42, 101, -1}); + static_assert(*dopt == Y{42, 101, -1}, ""); } { static_assert(std::is_constructible<optional<Z>, std::initializer_list<int>&>::value, ""); @@ -114,14 +111,5 @@ int main() { assert(i == 6); } - - struct test_constexpr_ctor - : public optional<Z> - { - constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i) - : optional<Z>(in_place, i) {} - }; - } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/move.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/move.pass.cpp index 40d55f9189933..851157f960f91 100644 --- a/test/std/experimental/optional/optional.object/optional.object.ctor/move.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.ctor/move.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -16,8 +17,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; template <class T> @@ -75,12 +74,8 @@ public: friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} }; - -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { typedef int T; optional<T> rhs; @@ -121,5 +116,4 @@ int main() optional<T> rhs(Z(3)); test(rhs, true); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp index c307a2e1e258b..40c96581ed847 100644 --- a/test/std/experimental/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr optional(nullopt_t) noexcept; @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; @@ -56,13 +55,9 @@ struct X X(); }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 test_constexpr<optional<int>>(); test_constexpr<optional<int*>>(); test<optional<X>>(); -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.dtor/dtor.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.dtor/dtor.pass.cpp index 2697799f0e5ee..2bec19e6b4f43 100644 --- a/test/std/experimental/optional/optional.object/optional.object.dtor/dtor.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.dtor/dtor.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // ~optional(); @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; class X @@ -29,11 +28,8 @@ public: bool X::dtor_called = false; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { typedef int T; static_assert(std::is_trivially_destructible<T>::value, ""); @@ -55,5 +51,4 @@ int main() } assert(X::dtor_called == true); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/bool.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/bool.pass.cpp index a3724375cf4d0..a5bfae240073c 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/bool.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/bool.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr explicit optional<T>::operator bool() const noexcept; @@ -17,7 +18,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; { @@ -28,5 +28,4 @@ int main() constexpr optional<int> opt(0); static_assert(opt, ""); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/dereference.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/dereference.pass.cpp index 98e5dac9719ed..faba8d256067c 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/dereference.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/dereference.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // T& optional<T>::operator*(); @@ -19,8 +20,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -29,11 +28,8 @@ struct X int test() {return 4;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<X> opt(X{}); assert((*opt).test() == 4); @@ -45,5 +41,4 @@ int main() assert(false); } #endif // _LIBCPP_DEBUG -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/dereference_const.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/dereference_const.pass.cpp index c72a57852a327..f1bdc36424daf 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/dereference_const.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/dereference_const.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr const T& optional<T>::operator*() const; @@ -19,8 +20,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -33,11 +32,8 @@ struct Y int test() const {return 2;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { constexpr optional<X> opt(X{}); static_assert((*opt).test() == 3, ""); @@ -53,5 +49,4 @@ int main() assert(false); } #endif // _LIBCPP_DEBUG -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow.pass.cpp index b17fcf8d30506..954ccd71ff538 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr T* optional<T>::operator->(); @@ -19,8 +20,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -28,11 +27,8 @@ struct X constexpr int test() const {return 3;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { constexpr optional<X> opt(X{}); static_assert(opt->test() == 3, ""); @@ -44,5 +40,4 @@ int main() assert(false); } #endif // _LIBCPP_DEBUG -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp index e813dd992a5b2..cf900d7029e1d 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr const T* optional<T>::operator->() const; @@ -19,8 +20,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -39,11 +38,8 @@ struct Z constexpr int test() const {return 1;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { constexpr optional<X> opt(X{}); static_assert(opt->test() == 3, ""); @@ -63,5 +59,4 @@ int main() assert(false); } #endif // _LIBCPP_DEBUG -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/value.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/value.pass.cpp index 85f9be6998a01..b998f3067f4fb 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/value.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/value.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -16,8 +17,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::bad_optional_access; @@ -29,11 +28,8 @@ struct X int test() {return 4;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<X> opt; opt.emplace(); @@ -50,5 +46,4 @@ int main() { } } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/value_const.fail.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/value_const.fail.cpp index f0f8af6da45df..baad3b47f3ec7 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/value_const.fail.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/value_const.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // constexpr const T& optional<T>::value() const; @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -25,16 +24,10 @@ struct X int test() {return 4;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { constexpr optional<X> opt; static_assert(opt.value().test() == 3, ""); } -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/value_const.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/value_const.pass.cpp index c99baab8b6e42..a38b1f930c72f 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/value_const.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/value_const.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -16,8 +17,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::in_place_t; using std::experimental::in_place; @@ -31,11 +30,8 @@ struct X int test() {return 4;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { constexpr optional<X> opt(in_place); static_assert(opt.value().test() == 3, ""); @@ -55,5 +51,4 @@ int main() { } } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/value_or.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/value_or.pass.cpp index 6118c44bb5baa..6fca8c82cebdc 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/value_or.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/value_or.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class U> T optional<T>::value_or(U&& v) &&; @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; using std::experimental::in_place_t; using std::experimental::in_place; @@ -40,11 +39,8 @@ struct X {return x.i_ == y.i_;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<X> opt(in_place, 2); Y y(3); @@ -67,5 +63,4 @@ int main() assert(std::move(opt).value_or(Y(3)) == 4); assert(!opt); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.observe/value_or_const.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.observe/value_or_const.pass.cpp index d51f18abbd28b..4a008dce23863 100644 --- a/test/std/experimental/optional/optional.object/optional.object.observe/value_or_const.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.observe/value_or_const.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class U> constexpr T optional<T>::value_or(U&& v) const&; @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct Y @@ -37,11 +36,8 @@ struct X {return x.i_ == y.i_;} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { constexpr optional<X> opt(2); constexpr Y y(3); @@ -78,5 +74,4 @@ int main() const optional<X> opt; assert(opt.value_or(Y(3)) == 4); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional.object.swap/swap.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.swap/swap.pass.cpp index d24a2d06b9d5b..620dda19e3ff1 100644 --- a/test/std/experimental/optional/optional.object/optional.object.swap/swap.pass.cpp +++ b/test/std/experimental/optional/optional.object/optional.object.swap/swap.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -18,8 +19,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; class X @@ -63,12 +62,8 @@ public: friend void swap(Z& x, Z& y) {throw 6;} }; - -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<int> opt1; optional<int> opt2; @@ -303,5 +298,4 @@ int main() assert(static_cast<bool>(opt2) == true); assert(*opt2 == 2); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional_const_void.fail.cpp b/test/std/experimental/optional/optional.object/optional_const_void.fail.cpp index 6999cf2451f1e..02c0a3a63a5e6 100644 --- a/test/std/experimental/optional/optional.object/optional_const_void.fail.cpp +++ b/test/std/experimental/optional/optional.object/optional_const_void.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // T shall be an object type and shall satisfy the requirements of Destructible @@ -15,11 +16,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; optional<const void> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional_not_destructible.fail.cpp b/test/std/experimental/optional/optional.object/optional_not_destructible.fail.cpp index 61470af01195a..da8bd05f2c9be 100644 --- a/test/std/experimental/optional/optional.object/optional_not_destructible.fail.cpp +++ b/test/std/experimental/optional/optional.object/optional_not_destructible.fail.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // T shall be an object type and shall satisfy the requirements of Destructible #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -23,13 +22,7 @@ private: ~X() {} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 optional<X> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional_not_noexcept_destructible.fail.cpp b/test/std/experimental/optional/optional.object/optional_not_noexcept_destructible.fail.cpp index eaee02014c2ff..7aa179afeaf6a 100644 --- a/test/std/experimental/optional/optional.object/optional_not_noexcept_destructible.fail.cpp +++ b/test/std/experimental/optional/optional.object/optional_not_noexcept_destructible.fail.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // T shall be an object type and shall satisfy the requirements of Destructible #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -22,13 +21,7 @@ struct X ~X() noexcept(false) {} }; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 optional<X> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/optional_void.fail.cpp b/test/std/experimental/optional/optional.object/optional_void.fail.cpp index f911e9a2d6d48..73f689c56720e 100644 --- a/test/std/experimental/optional/optional.object/optional_void.fail.cpp +++ b/test/std/experimental/optional/optional.object/optional_void.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // T shall be an object type and shall satisfy the requirements of Destructible @@ -15,11 +16,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; optional<void> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.object/types.pass.cpp b/test/std/experimental/optional/optional.object/types.pass.cpp index 8b9ad2e195707..af8da2df8fd51 100644 --- a/test/std/experimental/optional/optional.object/types.pass.cpp +++ b/test/std/experimental/optional/optional.object/types.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> @@ -19,8 +20,6 @@ #include <experimental/optional> #include <type_traits> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; template <class Opt, class T> @@ -30,14 +29,10 @@ test() static_assert(std::is_same<typename Opt::value_type, T>::value, ""); } -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 test<optional<int>, int>(); test<optional<const int>, const int>(); test<optional<double>, double>(); test<optional<const double>, const double>(); -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.relops/equal.pass.cpp b/test/std/experimental/optional/optional.relops/equal.pass.cpp index 03b9d3fda5cff..413e7c8b3780b 100644 --- a/test/std/experimental/optional/optional.relops/equal.pass.cpp +++ b/test/std/experimental/optional/optional.relops/equal.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator==(const optional<T>& x, const optional<T>& y); @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -28,16 +27,13 @@ struct X constexpr bool operator == ( const X &lhs, const X &rhs ) { return lhs.i_ == rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 { typedef X T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2; // disengaged constexpr O o3{1}; // engaged @@ -75,5 +71,4 @@ int main() static_assert ( o5 == o5 , "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.relops/greater_equal.pass.cpp b/test/std/experimental/optional/optional.relops/greater_equal.pass.cpp index 98d6855f93131..c0739dda6b832 100644 --- a/test/std/experimental/optional/optional.relops/greater_equal.pass.cpp +++ b/test/std/experimental/optional/optional.relops/greater_equal.pass.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator>= (const optional<T>& x, const optional<T>& y); #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,20 +26,17 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } -#endif - int main() { -#if _LIBCPP_STD_VER > 11 { typedef optional<X> O; - + constexpr O o1; // disengaged constexpr O o2; // disengaged constexpr O o3{1}; // engaged constexpr O o4{2}; // engaged constexpr O o5{1}; // engaged - + static_assert ( (o1 >= o1), "" ); static_assert ( (o1 >= o2), "" ); static_assert ( !(o1 >= o3), "" ); @@ -71,5 +67,4 @@ int main() static_assert ( !(o5 >= o4), "" ); static_assert ( (o5 >= o5), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.relops/greater_than.pass.cpp b/test/std/experimental/optional/optional.relops/greater_than.pass.cpp index d51bd4f2ac466..df7dbb64717fb 100644 --- a/test/std/experimental/optional/optional.relops/greater_than.pass.cpp +++ b/test/std/experimental/optional/optional.relops/greater_than.pass.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator> (const optional<T>& x, const optional<T>& y); #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,20 +26,17 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } -#endif - int main() { -#if _LIBCPP_STD_VER > 11 { typedef optional<X> O; - + constexpr O o1; // disengaged constexpr O o2; // disengaged constexpr O o3{1}; // engaged constexpr O o4{2}; // engaged constexpr O o5{1}; // engaged - + static_assert ( !(o1 > o1), "" ); static_assert ( !(o1 > o2), "" ); static_assert ( !(o1 > o3), "" ); @@ -71,5 +67,4 @@ int main() static_assert ( !(o5 > o4), "" ); static_assert ( !(o5 > o5), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.relops/less_equal.pass.cpp b/test/std/experimental/optional/optional.relops/less_equal.pass.cpp index 326f3a8964939..d4874d17b2405 100644 --- a/test/std/experimental/optional/optional.relops/less_equal.pass.cpp +++ b/test/std/experimental/optional/optional.relops/less_equal.pass.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator<= (const optional<T>& x, const optional<T>& y); #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,20 +26,17 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } -#endif - int main() { -#if _LIBCPP_STD_VER > 11 { typedef optional<X> O; - + constexpr O o1; // disengaged constexpr O o2; // disengaged constexpr O o3{1}; // engaged constexpr O o4{2}; // engaged constexpr O o5{1}; // engaged - + static_assert ( (o1 <= o1), "" ); static_assert ( (o1 <= o2), "" ); static_assert ( (o1 <= o3), "" ); @@ -71,5 +67,4 @@ int main() static_assert ( (o5 <= o4), "" ); static_assert ( (o5 <= o5), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.relops/less_than.pass.cpp b/test/std/experimental/optional/optional.relops/less_than.pass.cpp index 37f7e1942982c..4113408268e8f 100644 --- a/test/std/experimental/optional/optional.relops/less_than.pass.cpp +++ b/test/std/experimental/optional/optional.relops/less_than.pass.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator< (const optional<T>& x, const optional<T>& y); #include <experimental/optional> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -27,20 +26,17 @@ struct X constexpr bool operator < ( const X &lhs, const X &rhs ) { return lhs.i_ < rhs.i_ ; } -#endif - int main() { -#if _LIBCPP_STD_VER > 11 { typedef optional<X> O; - + constexpr O o1; // disengaged constexpr O o2; // disengaged constexpr O o3{1}; // engaged constexpr O o4{2}; // engaged constexpr O o5{1}; // engaged - + static_assert ( !(o1 < o1), "" ); static_assert ( !(o1 < o2), "" ); static_assert ( (o1 < o3), "" ); @@ -71,5 +67,4 @@ int main() static_assert ( (o5 < o4), "" ); static_assert ( !(o5 < o5), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.relops/not_equal.pass.cpp b/test/std/experimental/optional/optional.relops/not_equal.pass.cpp index f386c7e361ecd..19a196317d4f8 100644 --- a/test/std/experimental/optional/optional.relops/not_equal.pass.cpp +++ b/test/std/experimental/optional/optional.relops/not_equal.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> constexpr bool operator!=(const optional<T>& x, const optional<T>& y); @@ -15,8 +16,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; struct X @@ -28,16 +27,13 @@ struct X constexpr bool operator == ( const X &lhs, const X &rhs ) { return lhs.i_ == rhs.i_ ; } - -#endif int main() { -#if _LIBCPP_STD_VER > 11 { typedef X T; typedef optional<T> O; - + constexpr O o1; // disengaged constexpr O o2; // disengaged constexpr O o3{1}; // engaged @@ -75,5 +71,4 @@ int main() static_assert ( !(o5 != o5), "" ); } -#endif } diff --git a/test/std/experimental/optional/optional.specalg/make_optional.pass.cpp b/test/std/experimental/optional/optional.specalg/make_optional.pass.cpp index cc95e6110e8d7..9abd87bd40513 100644 --- a/test/std/experimental/optional/optional.specalg/make_optional.pass.cpp +++ b/test/std/experimental/optional/optional.specalg/make_optional.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // template <class T> @@ -19,9 +20,10 @@ #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::make_optional; @@ -38,7 +40,7 @@ int main() std::string s("123"); optional<std::string> opt = make_optional(std::move(s)); assert(*opt == "123"); - assert(s.empty()); + LIBCPP_ASSERT(s.empty()); } { std::unique_ptr<int> s(new int(3)); @@ -46,5 +48,4 @@ int main() assert(**opt == 3); assert(s == nullptr); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.specalg/swap.pass.cpp b/test/std/experimental/optional/optional.specalg/swap.pass.cpp index 6c5f7b0e860c1..d339c53c1f771 100644 --- a/test/std/experimental/optional/optional.specalg/swap.pass.cpp +++ b/test/std/experimental/optional/optional.specalg/swap.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // XFAIL: libcpp-no-exceptions // <optional> @@ -17,8 +18,6 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - using std::experimental::optional; class X @@ -62,12 +61,8 @@ public: friend void swap(Z& x, Z& y) {throw 6;} }; - -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 { optional<int> opt1; optional<int> opt2; @@ -302,5 +297,4 @@ int main() assert(static_cast<bool>(opt2) == true); assert(*opt2 == 2); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_const_in_place_t.fail.cpp b/test/std/experimental/optional/optional.syn/optional_const_in_place_t.fail.cpp index 60836ae2396ea..bdf01eba406f7 100644 --- a/test/std/experimental/optional/optional.syn/optional_const_in_place_t.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_const_in_place_t.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for @@ -16,13 +17,9 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::in_place_t; using std::experimental::in_place; optional<const in_place_t> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_const_lvalue_ref.fail.cpp b/test/std/experimental/optional/optional.syn/optional_const_lvalue_ref.fail.cpp index 9a4ba1a027a10..61393c105e959 100644 --- a/test/std/experimental/optional/optional.syn/optional_const_lvalue_ref.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_const_lvalue_ref.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for a @@ -16,11 +17,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; optional<const int&> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_const_nullopt_t.fail.cpp b/test/std/experimental/optional/optional.syn/optional_const_nullopt_t.fail.cpp index f6220bda69c4e..89c207306aba8 100644 --- a/test/std/experimental/optional/optional.syn/optional_const_nullopt_t.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_const_nullopt_t.fail.cpp @@ -7,22 +7,19 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for -// (possibly cv-qualified) null_opt_t is ill-formed. +// (possibly cv-qualified) nullopt_t is ill-formed. #include <experimental/optional> int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; optional<const nullopt_t> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_in_place_t.fail.cpp b/test/std/experimental/optional/optional.syn/optional_in_place_t.fail.cpp index 12f291fcd228f..47c2be7da0d0a 100644 --- a/test/std/experimental/optional/optional.syn/optional_in_place_t.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_in_place_t.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for @@ -16,13 +17,9 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::in_place_t; using std::experimental::in_place; optional<in_place_t> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_includes_initializer_list.pass.cpp b/test/std/experimental/optional/optional.syn/optional_includes_initializer_list.pass.cpp index 7e6697ff6e508..8cf11b553e745 100644 --- a/test/std/experimental/optional/optional.syn/optional_includes_initializer_list.pass.cpp +++ b/test/std/experimental/optional/optional.syn/optional_includes_initializer_list.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // #include <initializer_list> @@ -15,9 +16,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; std::initializer_list<int> list; -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_lvalue_ref.fail.cpp b/test/std/experimental/optional/optional.syn/optional_lvalue_ref.fail.cpp index 850df342aef04..de2f18991b246 100644 --- a/test/std/experimental/optional/optional.syn/optional_lvalue_ref.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_lvalue_ref.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for a @@ -16,11 +17,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; optional<int&> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_nullopt_t.fail.cpp b/test/std/experimental/optional/optional.syn/optional_nullopt_t.fail.cpp index 20955ace834ae..3d276d6420226 100644 --- a/test/std/experimental/optional/optional.syn/optional_nullopt_t.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_nullopt_t.fail.cpp @@ -7,22 +7,19 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for -// (possibly cv-qualified) null_opt_t is ill-formed. +// (possibly cv-qualified) nullopt_t is ill-formed. #include <experimental/optional> int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; using std::experimental::nullopt_t; using std::experimental::nullopt; optional<nullopt_t> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/optional/optional.syn/optional_rvalue_ref.fail.cpp b/test/std/experimental/optional/optional.syn/optional_rvalue_ref.fail.cpp index d773e993df227..fd6da18e8c161 100644 --- a/test/std/experimental/optional/optional.syn/optional_rvalue_ref.fail.cpp +++ b/test/std/experimental/optional/optional.syn/optional_rvalue_ref.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <optional> // A program that necessitates the instantiation of template optional for a @@ -16,11 +17,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 using std::experimental::optional; optional<int&&> opt; -#else -#error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/experimental/string.view/string.view.access/at.pass.cpp b/test/std/experimental/string.view/string.view.access/at.pass.cpp index 46804d4df3af8..7ceaf5ab3d9f3 100644 --- a/test/std/experimental/string.view/string.view.access/at.pass.cpp +++ b/test/std/experimental/string.view/string.view.access/at.pass.cpp @@ -10,7 +10,7 @@ // NOTE: Older versions of clang have a bug where they fail to evalute // string_view::at as a constant expression. // XFAIL: clang-3.4, clang-3.3 -// XFAIL: libcpp-no-exceptions + // <string_view> @@ -20,6 +20,8 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" + template <typename CharT> void test ( const CharT *s, size_t len ) { std::experimental::basic_string_view<CharT> sv ( s, len ); @@ -27,12 +29,14 @@ void test ( const CharT *s, size_t len ) { for ( size_t i = 0; i < len; ++i ) { assert ( sv.at(i) == s[i] ); assert ( &sv.at(i) == s + i ); - } + } +#ifndef TEST_HAS_NO_EXCEPTIONS try { sv.at(len); } catch ( const std::out_of_range & ) { return ; } assert ( false ); - } - +#endif +} + int main () { test ( "ABCDE", 5 ); test ( "a", 1 ); @@ -40,7 +44,7 @@ int main () { test ( L"ABCDE", 5 ); test ( L"a", 1 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); @@ -48,7 +52,7 @@ int main () { test ( U"a", 1 ); #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { constexpr std::experimental::basic_string_view<char> sv ( "ABC", 2 ); static_assert ( sv.length() == 2, "" ); diff --git a/test/std/experimental/string.view/string.view.access/back.pass.cpp b/test/std/experimental/string.view/string.view.access/back.pass.cpp index 093a858a48055..09f7950341a8d 100644 --- a/test/std/experimental/string.view/string.view.access/back.pass.cpp +++ b/test/std/experimental/string.view/string.view.access/back.pass.cpp @@ -15,6 +15,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <typename CharT> bool test ( const CharT *s, size_t len ) { std::experimental::basic_string_view<CharT> sv ( s, len ); @@ -22,7 +24,7 @@ bool test ( const CharT *s, size_t len ) { assert ( sv.back() == s[len-1] ); return &sv.back() == s + len - 1; } - + int main () { assert ( test ( "ABCDE", 5 )); assert ( test ( "a", 1 )); @@ -30,7 +32,7 @@ int main () { assert ( test ( L"ABCDE", 5 )); assert ( test ( L"a", 1 )); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert ( test ( u"ABCDE", 5 )); assert ( test ( u"a", 1 )); @@ -38,7 +40,7 @@ int main () { assert ( test ( U"a", 1 )); #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { constexpr std::experimental::basic_string_view<char> sv ( "ABC", 2 ); static_assert ( sv.length() == 2, "" ); diff --git a/test/std/experimental/string.view/string.view.access/data.pass.cpp b/test/std/experimental/string.view/string.view.access/data.pass.cpp index 562a765f50ceb..53e95ddaea31a 100644 --- a/test/std/experimental/string.view/string.view.access/data.pass.cpp +++ b/test/std/experimental/string.view/string.view.access/data.pass.cpp @@ -15,13 +15,15 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <typename CharT> void test ( const CharT *s, size_t len ) { std::experimental::basic_string_view<CharT> sv ( s, len ); assert ( sv.length() == len ); assert ( sv.data() == s ); } - + int main () { test ( "ABCDE", 5 ); test ( "a", 1 ); @@ -29,7 +31,7 @@ int main () { test ( L"ABCDE", 5 ); test ( L"a", 1 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); diff --git a/test/std/experimental/string.view/string.view.access/front.pass.cpp b/test/std/experimental/string.view/string.view.access/front.pass.cpp index e9df44b19b1af..acb00a46a2e54 100644 --- a/test/std/experimental/string.view/string.view.access/front.pass.cpp +++ b/test/std/experimental/string.view/string.view.access/front.pass.cpp @@ -15,6 +15,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <typename CharT> bool test ( const CharT *s, size_t len ) { std::experimental::basic_string_view<CharT> sv ( s, len ); @@ -22,7 +24,7 @@ bool test ( const CharT *s, size_t len ) { assert ( sv.front() == s[0] ); return &sv.front() == s; } - + int main () { assert ( test ( "ABCDE", 5 )); assert ( test ( "a", 1 )); @@ -30,7 +32,7 @@ int main () { assert ( test ( L"ABCDE", 5 )); assert ( test ( L"a", 1 )); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert ( test ( u"ABCDE", 5 )); assert ( test ( u"a", 1 )); @@ -38,7 +40,7 @@ int main () { assert ( test ( U"a", 1 )); #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { constexpr std::experimental::basic_string_view<char> sv ( "ABC", 2 ); static_assert ( sv.length() == 2, "" ); diff --git a/test/std/experimental/string.view/string.view.access/index.pass.cpp b/test/std/experimental/string.view/string.view.access/index.pass.cpp index 4491207cbb85e..2c1bd1dc91cb5 100644 --- a/test/std/experimental/string.view/string.view.access/index.pass.cpp +++ b/test/std/experimental/string.view/string.view.access/index.pass.cpp @@ -15,6 +15,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <typename CharT> void test ( const CharT *s, size_t len ) { std::experimental::basic_string_view<CharT> sv ( s, len ); @@ -24,7 +26,7 @@ void test ( const CharT *s, size_t len ) { assert ( &sv[i] == s + i ); } } - + int main () { test ( "ABCDE", 5 ); test ( "a", 1 ); @@ -32,7 +34,7 @@ int main () { test ( L"ABCDE", 5 ); test ( L"a", 1 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); diff --git a/test/std/experimental/string.view/string.view.capacity/capacity.pass.cpp b/test/std/experimental/string.view/string.view.capacity/capacity.pass.cpp index eb802165930d1..9f5d86f2f82b2 100644 --- a/test/std/experimental/string.view/string.view.capacity/capacity.pass.cpp +++ b/test/std/experimental/string.view/string.view.capacity/capacity.pass.cpp @@ -19,6 +19,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename SV> void test1 () { #if _LIBCPP_STD_VER > 11 @@ -30,7 +32,7 @@ void test1 () { static_assert ( sv1.max_size() > sv1.size(), ""); } #endif - + { SV sv1; assert ( sv1.size() == 0 ); @@ -73,7 +75,7 @@ int main () { test2 ( L"a", 1 ); test2 ( L"", 0 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test2 ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE", 105 ); test2 ( u"ABCDE", 5 ); test2 ( u"a", 1 ); diff --git a/test/std/experimental/string.view/string.view.comparison/opeq.string_view.pointer.pass.cpp b/test/std/experimental/string.view/string.view.comparison/opeq.string_view.pointer.pass.cpp index 148dc18d7ec81..0df37a6ffd9f8 100644 --- a/test/std/experimental/string.view/string.view.comparison/opeq.string_view.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/opeq.string_view.pointer.pass.cpp @@ -58,7 +58,7 @@ int main() static_assert ( "" == sv1, "" ); static_assert (!(sv1 == "abcde"), "" ); static_assert (!("abcde" == sv1), "" ); - + static_assert ( sv2 == "abcde", "" ); static_assert ( "abcde" == sv2, "" ); static_assert (!(sv2 == "abcde0"), "" ); diff --git a/test/std/experimental/string.view/string.view.comparison/opeq.string_view.string.pass.cpp b/test/std/experimental/string.view/string.view.comparison/opeq.string_view.string.pass.cpp index 23a2aef242d7f..1fd72d7964b6c 100644 --- a/test/std/experimental/string.view/string.view.comparison/opeq.string_view.string.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/opeq.string_view.string.pass.cpp @@ -17,8 +17,6 @@ #include <experimental/string_view> #include <cassert> -#if _LIBCPP_STD_VER > 11 - template <class S> void test(const std::string &lhs, S rhs, bool x) @@ -49,6 +47,4 @@ int main() test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), true); } } -#else -int main () {} -#endif + diff --git a/test/std/experimental/string.view/string.view.comparison/opge.string_view.pointer.pass.cpp b/test/std/experimental/string.view/string.view.comparison/opge.string_view.pointer.pass.cpp index f02459b01c49b..f5bcb7e97b73b 100644 --- a/test/std/experimental/string.view/string.view.comparison/opge.string_view.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/opge.string_view.pointer.pass.cpp @@ -59,7 +59,7 @@ int main() static_assert ( "" >= sv1, "" ); static_assert (!(sv1 >= "abcde"), "" ); static_assert ( "abcde" >= sv1, "" ); - + static_assert ( sv2 >= "", "" ); static_assert (!("" >= sv2), "" ); static_assert ( sv2 >= "abcde", "" ); diff --git a/test/std/experimental/string.view/string.view.comparison/opgt.string_view.pointer.pass.cpp b/test/std/experimental/string.view/string.view.comparison/opgt.string_view.pointer.pass.cpp index 48703cac612f2..63002a5c415c7 100644 --- a/test/std/experimental/string.view/string.view.comparison/opgt.string_view.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/opgt.string_view.pointer.pass.cpp @@ -59,7 +59,7 @@ int main() static_assert (!("" > sv1), "" ); static_assert (!(sv1 > "abcde"), "" ); static_assert ( "abcde" > sv1, "" ); - + static_assert ( sv2 > "", "" ); static_assert (!("" > sv2), "" ); static_assert (!(sv2 > "abcde"), "" ); diff --git a/test/std/experimental/string.view/string.view.comparison/ople.string_view.pointer.pass.cpp b/test/std/experimental/string.view/string.view.comparison/ople.string_view.pointer.pass.cpp index 539f5fa5402e4..c542efea99a7e 100644 --- a/test/std/experimental/string.view/string.view.comparison/ople.string_view.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/ople.string_view.pointer.pass.cpp @@ -59,7 +59,7 @@ int main() static_assert ( "" <= sv1, "" ); static_assert ( sv1 <= "abcde", "" ); static_assert (!("abcde" <= sv1), "" ); - + static_assert (!(sv2 <= ""), "" ); static_assert ( "" <= sv2, "" ); static_assert ( sv2 <= "abcde", "" ); diff --git a/test/std/experimental/string.view/string.view.comparison/oplt.string_view.pointer.pass.cpp b/test/std/experimental/string.view/string.view.comparison/oplt.string_view.pointer.pass.cpp index a1013e4d81523..2c0461481e783 100644 --- a/test/std/experimental/string.view/string.view.comparison/oplt.string_view.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/oplt.string_view.pointer.pass.cpp @@ -59,7 +59,7 @@ int main() static_assert (!("" < sv1), "" ); static_assert ( sv1 < "abcde", "" ); static_assert (!("abcde" < sv1), "" ); - + static_assert (!(sv2 < ""), "" ); static_assert ( "" < sv2, "" ); static_assert (!(sv2 < "abcde"), "" ); diff --git a/test/std/experimental/string.view/string.view.comparison/opne.string_view.pointer.pass.cpp b/test/std/experimental/string.view/string.view.comparison/opne.string_view.pointer.pass.cpp index 299be934a8119..1deee9ac7fc6b 100644 --- a/test/std/experimental/string.view/string.view.comparison/opne.string_view.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.comparison/opne.string_view.pointer.pass.cpp @@ -59,7 +59,7 @@ int main() static_assert (!("" != sv1), "" ); static_assert ( sv1 != "abcde", "" ); static_assert ( "abcde" != sv1, "" ); - + static_assert (!(sv2 != "abcde"), "" ); static_assert (!("abcde" != sv2), "" ); static_assert ( sv2 != "abcde0", "" ); diff --git a/test/std/experimental/string.view/string.view.cons/default.pass.cpp b/test/std/experimental/string.view/string.view.cons/default.pass.cpp index e1d69f4a3dfe2..e817bfffb89da 100644 --- a/test/std/experimental/string.view/string.view.cons/default.pass.cpp +++ b/test/std/experimental/string.view/string.view.cons/default.pass.cpp @@ -24,7 +24,7 @@ void test () { static_assert ( sv1.empty(), ""); } #endif - + { T sv1; assert ( sv1.size() == 0 ); diff --git a/test/std/experimental/string.view/string.view.cons/from_literal.pass.cpp b/test/std/experimental/string.view/string.view.cons/from_literal.pass.cpp index 82d0d79541490..9de3a30395234 100644 --- a/test/std/experimental/string.view/string.view.cons/from_literal.pass.cpp +++ b/test/std/experimental/string.view/string.view.cons/from_literal.pass.cpp @@ -40,12 +40,12 @@ int main () { test ( "QBCDE" ); test ( "A" ); test ( "" ); - + test ( L"QBCDE" ); test ( L"A" ); test ( L"" ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"QBCDE" ); test ( u"A" ); test ( u"" ); diff --git a/test/std/experimental/string.view/string.view.cons/from_ptr_len.pass.cpp b/test/std/experimental/string.view/string.view.cons/from_ptr_len.pass.cpp index 1038d0484f8cb..663d25e954f93 100644 --- a/test/std/experimental/string.view/string.view.cons/from_ptr_len.pass.cpp +++ b/test/std/experimental/string.view/string.view.cons/from_ptr_len.pass.cpp @@ -18,6 +18,8 @@ #include <string> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test ( const CharT *s, size_t sz ) { { @@ -53,7 +55,7 @@ int main () { } #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"QBCDE", 5 ); test ( u"QBCDE", 2 ); test ( u"", 0 ); diff --git a/test/std/experimental/string.view/string.view.cons/from_string.pass.cpp b/test/std/experimental/string.view/string.view.cons/from_string.pass.cpp index 670c033a653fe..4ecd2cdff9ba9 100644 --- a/test/std/experimental/string.view/string.view.cons/from_string.pass.cpp +++ b/test/std/experimental/string.view/string.view.cons/from_string.pass.cpp @@ -18,6 +18,8 @@ #include <string> #include <cassert> +#include "test_macros.h" + struct dummy_char_traits : public std::char_traits<char> {}; template<typename CharT, typename Traits> @@ -32,12 +34,12 @@ int main () { test ( std::string("QBCDE") ); test ( std::string("") ); test ( std::string() ); - + test ( std::wstring(L"QBCDE") ); test ( std::wstring(L"") ); test ( std::wstring() ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( std::u16string{u"QBCDE"} ); test ( std::u16string{u""} ); test ( std::u16string{} ); @@ -46,7 +48,7 @@ int main () { test ( std::u32string{U""} ); test ( std::u32string{} ); #endif - + test ( std::basic_string<char, dummy_char_traits>("QBCDE") ); test ( std::basic_string<char, dummy_char_traits>("") ); test ( std::basic_string<char, dummy_char_traits>() ); diff --git a/test/std/experimental/string.view/string.view.cons/from_string1.fail.cpp b/test/std/experimental/string.view/string.view.cons/from_string1.fail.cpp index 6ef4b9669bf45..b2ffa61c29d99 100644 --- a/test/std/experimental/string.view/string.view.cons/from_string1.fail.cpp +++ b/test/std/experimental/string.view/string.view.cons/from_string1.fail.cpp @@ -22,7 +22,7 @@ struct dummy_char_traits : public std::char_traits<char> {}; int main () { using string_view = std::experimental::basic_string_view<char>; using string = std:: basic_string <char, dummy_char_traits>; - + { string s{"QBCDE"}; string_view sv1 ( s ); diff --git a/test/std/experimental/string.view/string.view.cons/from_string2.fail.cpp b/test/std/experimental/string.view/string.view.cons/from_string2.fail.cpp index 6c77a3f99a2b1..a14e131c85aaf 100644 --- a/test/std/experimental/string.view/string.view.cons/from_string2.fail.cpp +++ b/test/std/experimental/string.view/string.view.cons/from_string2.fail.cpp @@ -22,7 +22,7 @@ struct dummy_char_traits : public std::char_traits<char> {}; int main () { using string_view = std::experimental::basic_string_view<char, dummy_char_traits>; using string = std:: basic_string <char>; - + { string s{"QBCDE"}; string_view sv1 ( s ); diff --git a/test/std/experimental/string.view/string.view.iterators/begin.pass.cpp b/test/std/experimental/string.view/string.view.iterators/begin.pass.cpp index 07f3b36e1d2b0..8040b81d4efe5 100644 --- a/test/std/experimental/string.view/string.view.iterators/begin.pass.cpp +++ b/test/std/experimental/string.view/string.view.iterators/begin.pass.cpp @@ -14,6 +14,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <class S> void test(S s) @@ -30,7 +32,7 @@ test(S s) assert(&*cb1 == &s[0]); assert( *cb2 == s[0]); assert(&*cb2 == &s[0]); - + } assert( b == cb1); assert( b == cb2); @@ -51,7 +53,7 @@ int main() test(wstring_view ()); test(string_view ( "123")); test(wstring_view (L"123")); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test(u16string_view{u"123"}); test(u32string_view{U"123"}); #endif @@ -62,7 +64,7 @@ int main() constexpr u16string_view u16sv {u"123", 3 }; constexpr u32string_view u32sv {U"123", 3 }; constexpr wstring_view wsv {L"123", 3 }; - + static_assert ( *sv.begin() == sv[0], "" ); static_assert ( *u16sv.begin() == u16sv[0], "" ); static_assert ( *u32sv.begin() == u32sv[0], "" ); diff --git a/test/std/experimental/string.view/string.view.iterators/end.pass.cpp b/test/std/experimental/string.view/string.view.iterators/end.pass.cpp index 2ed52b8de947d..3a1091e9983c2 100644 --- a/test/std/experimental/string.view/string.view.iterators/end.pass.cpp +++ b/test/std/experimental/string.view/string.view.iterators/end.pass.cpp @@ -14,6 +14,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <class S> void test(S s) @@ -35,7 +37,7 @@ test(S s) assert(ce1 != cs.begin()); assert(ce2 != s.begin()); } - + assert( e - s.begin() == s.size()); assert(ce1 - cs.begin() == cs.size()); assert(ce2 - s.cbegin() == s.size()); @@ -59,7 +61,7 @@ int main() test(wstring_view ()); test(string_view ( "123")); test(wstring_view (L"123")); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test(u16string_view{u"123"}); test(u32string_view{U"123"}); #endif @@ -70,7 +72,7 @@ int main() constexpr u16string_view u16sv {u"123", 3 }; constexpr u32string_view u32sv {U"123", 3 }; constexpr wstring_view wsv {L"123", 3 }; - + static_assert ( sv.begin() != sv.end(), "" ); static_assert ( u16sv.begin() != u16sv.end(), "" ); static_assert ( u32sv.begin() != u32sv.end(), "" ); diff --git a/test/std/experimental/string.view/string.view.iterators/rbegin.pass.cpp b/test/std/experimental/string.view/string.view.iterators/rbegin.pass.cpp index 7d1c7003eaf49..068557e398635 100644 --- a/test/std/experimental/string.view/string.view.iterators/rbegin.pass.cpp +++ b/test/std/experimental/string.view/string.view.iterators/rbegin.pass.cpp @@ -14,6 +14,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <class S> void test(S s) @@ -31,7 +33,7 @@ test(S s) assert(&*cb1 == &s[last]); assert( *cb2 == s[last]); assert(&*cb2 == &s[last]); - + } assert( b == cb1); assert( b == cb2); @@ -52,7 +54,7 @@ int main() test(wstring_view ()); test(string_view ( "123")); test(wstring_view (L"123")); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test(u16string_view{u"123"}); test(u32string_view{U"123"}); #endif diff --git a/test/std/experimental/string.view/string.view.iterators/rend.pass.cpp b/test/std/experimental/string.view/string.view.iterators/rend.pass.cpp index 57002f30518f3..55e28a2669486 100644 --- a/test/std/experimental/string.view/string.view.iterators/rend.pass.cpp +++ b/test/std/experimental/string.view/string.view.iterators/rend.pass.cpp @@ -14,6 +14,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template <class S> void test(S s) @@ -35,7 +37,7 @@ test(S s) assert(ce1 != cs.rbegin()); assert(ce2 != s.rbegin()); } - + assert( e - s.rbegin() == s.size()); assert(ce1 - cs.rbegin() == cs.size()); assert(ce2 - s.crbegin() == s.size()); @@ -52,14 +54,14 @@ int main() typedef std::experimental::u16string_view u16string_view; typedef std::experimental::u32string_view u32string_view; typedef std::experimental::wstring_view wstring_view; - + test(string_view ()); test(u16string_view()); test(u32string_view()); test(wstring_view ()); test(string_view ( "123")); test(wstring_view (L"123")); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test(u16string_view{u"123"}); test(u32string_view{U"123"}); #endif diff --git a/test/std/experimental/string.view/string.view.modifiers/clear.pass.cpp b/test/std/experimental/string.view/string.view.modifiers/clear.pass.cpp index 6a9982e0d3a56..9a4891c8f2599 100644 --- a/test/std/experimental/string.view/string.view.modifiers/clear.pass.cpp +++ b/test/std/experimental/string.view/string.view.modifiers/clear.pass.cpp @@ -15,6 +15,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test ( const CharT *s, size_t len ) { typedef std::experimental::basic_string_view<CharT> SV; @@ -48,7 +50,7 @@ int main () { test ( L"a", 1 ); test ( L"", 0 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); test ( u"", 0 ); diff --git a/test/std/experimental/string.view/string.view.modifiers/remove_prefix.pass.cpp b/test/std/experimental/string.view/string.view.modifiers/remove_prefix.pass.cpp index 0a2dd6d9329cc..4a31486afaa0b 100644 --- a/test/std/experimental/string.view/string.view.modifiers/remove_prefix.pass.cpp +++ b/test/std/experimental/string.view/string.view.modifiers/remove_prefix.pass.cpp @@ -16,6 +16,8 @@ #include <cassert> #include <iostream> +#include "test_macros.h" + template<typename CharT> void test ( const CharT *s, size_t len ) { typedef std::experimental::basic_string_view<CharT> SV; @@ -30,10 +32,10 @@ void test ( const CharT *s, size_t len ) { assert ( sv1.data() == (s + 1)); sv1.remove_prefix ( len - 1 ); } - + assert ( sv1.size() == 0 ); sv1.remove_prefix ( 0 ); - assert ( sv1.size() == 0 ); + assert ( sv1.size() == 0 ); } } @@ -55,7 +57,7 @@ int main () { test ( L"a", 1 ); test ( L"", 0 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); test ( u"", 0 ); diff --git a/test/std/experimental/string.view/string.view.modifiers/remove_suffix.pass.cpp b/test/std/experimental/string.view/string.view.modifiers/remove_suffix.pass.cpp index 9dd59882cce6e..9ddc6de84bf32 100644 --- a/test/std/experimental/string.view/string.view.modifiers/remove_suffix.pass.cpp +++ b/test/std/experimental/string.view/string.view.modifiers/remove_suffix.pass.cpp @@ -15,6 +15,8 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test ( const CharT *s, size_t len ) { typedef std::experimental::basic_string_view<CharT> SV; @@ -29,10 +31,10 @@ void test ( const CharT *s, size_t len ) { assert ( sv1.data() == s); sv1.remove_suffix ( len - 1 ); } - + assert ( sv1.size() == 0 ); sv1.remove_suffix ( 0 ); - assert ( sv1.size() == 0 ); + assert ( sv1.size() == 0 ); } } @@ -55,7 +57,7 @@ int main () { test ( L"a", 1 ); test ( L"", 0 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); test ( u"", 0 ); diff --git a/test/std/experimental/string.view/string.view.modifiers/swap.pass.cpp b/test/std/experimental/string.view/string.view.modifiers/swap.pass.cpp index cacb8ed40b885..d747def8549e1 100644 --- a/test/std/experimental/string.view/string.view.modifiers/swap.pass.cpp +++ b/test/std/experimental/string.view/string.view.modifiers/swap.pass.cpp @@ -15,13 +15,15 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test ( const CharT *s, size_t len ) { typedef std::experimental::basic_string_view<CharT> SV; { SV sv1(s); SV sv2; - + assert ( sv1.size() == len ); assert ( sv1.data() == s ); assert ( sv2.size() == 0 ); @@ -54,7 +56,7 @@ int main () { test ( L"a", 1 ); test ( L"", 0 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDE", 5 ); test ( u"a", 1 ); test ( u"", 0 ); diff --git a/test/std/experimental/string.view/string.view.nonmem/quoted.pass.cpp b/test/std/experimental/string.view/string.view.nonmem/quoted.pass.cpp index c86e9619f1930..6ba03212d42b6 100644 --- a/test/std/experimental/string.view/string.view.nonmem/quoted.pass.cpp +++ b/test/std/experimental/string.view/string.view.nonmem/quoted.pass.cpp @@ -103,7 +103,7 @@ void round_trip ( const wchar_t *p ) { assert ( s == sv ); assert ( skippingws == is_skipws ( &ss )); } - + void round_trip_ws ( const wchar_t *p ) { std::wstringstream ss; @@ -165,31 +165,31 @@ int main() round_trip_ws ( "" ); round_trip_d ( "", 'q' ); round_trip_e ( "", 'q' ); - + round_trip ( L"" ); round_trip_ws ( L"" ); round_trip_d ( L"", 'q' ); round_trip_e ( L"", 'q' ); - + round_trip ( "Hi" ); round_trip_ws ( "Hi" ); round_trip_d ( "Hi", '!' ); round_trip_e ( "Hi", '!' ); assert ( quote ( "Hi", '!' ) == "!Hi!" ); assert ( quote ( "Hi!", '!' ) == R"(!Hi\!!)" ); - + round_trip ( L"Hi" ); round_trip_ws ( L"Hi" ); round_trip_d ( L"Hi", '!' ); round_trip_e ( L"Hi", '!' ); assert ( quote ( L"Hi", '!' ) == L"!Hi!" ); assert ( quote ( L"Hi!", '!' ) == LR"(!Hi\!!)" ); - + round_trip ( "Hi Mom" ); round_trip_ws ( "Hi Mom" ); round_trip ( L"Hi Mom" ); round_trip_ws ( L"Hi Mom" ); - + assert ( quote ( "" ) == "\"\"" ); assert ( quote ( L"" ) == L"\"\"" ); assert ( quote ( "a" ) == "\"a\"" ); @@ -198,7 +198,7 @@ int main() // missing end quote - must not hang assert ( unquote ( "\"abc" ) == "abc" ); assert ( unquote ( L"\"abc" ) == L"abc" ); - + assert ( unquote ( "abc" ) == "abc" ); // no delimiter assert ( unquote ( L"abc" ) == L"abc" ); // no delimiter assert ( unquote ( "abc def" ) == "abc" ); // no delimiter diff --git a/test/std/experimental/string.view/string.view.ops/basic_string.pass.cpp b/test/std/experimental/string.view/string.view.ops/basic_string.pass.cpp index 29f5064d81dca..a29bb15f5ac9c 100644 --- a/test/std/experimental/string.view/string.view.ops/basic_string.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/basic_string.pass.cpp @@ -16,11 +16,13 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test ( const CharT *s ) { typedef std::experimental::basic_string_view<CharT> string_view_t; typedef std::basic_string<CharT> string_t; - + { string_view_t sv1 ( s ); string_t str = (string_t) sv1; @@ -49,7 +51,7 @@ int main () { test ( L"a" ); test ( L"" ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( u"ABCDE" ); test ( u"a" ); diff --git a/test/std/experimental/string.view/string.view.ops/compare.pointer.pass.cpp b/test/std/experimental/string.view/string.view.ops/compare.pointer.pass.cpp index 6ccec9b3729ad..583395451fd49 100644 --- a/test/std/experimental/string.view/string.view.ops/compare.pointer.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/compare.pointer.pass.cpp @@ -72,7 +72,7 @@ int main() test(L"abcdefghijklmnopqrst", L"abcdefghijklmnopqrst", 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { test(U"", U"", 0); test(U"", U"abcde", -5); diff --git a/test/std/experimental/string.view/string.view.ops/compare.pointer_size.pass.cpp b/test/std/experimental/string.view/string.view.ops/compare.pointer_size.pass.cpp index 7ccbd528c7fc8..cfe35fcb47193 100644 --- a/test/std/experimental/string.view/string.view.ops/compare.pointer_size.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/compare.pointer_size.pass.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: libcpp-no-exceptions // <string_view> // constexpr int compare(size_type pos1, size_type n1, const charT* s) const; @@ -15,18 +14,27 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" #include "constexpr_char_traits.hpp" int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); } template<typename CharT> -void test1 ( std::experimental::basic_string_view<CharT> sv1, +void test1 ( std::experimental::basic_string_view<CharT> sv1, size_t pos1, size_t n1, const CharT *s, int expected ) { - try { + if (pos1 > sv1.size()) { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + sv1.compare(pos1, n1, s); + assert(false); + } catch (const std::out_of_range&) { + } catch (...) { + assert(false); + } +#endif + } else { assert(sign(sv1.compare(pos1, n1, s)) == sign(expected)); - assert(pos1 <= sv1.size()); } - catch (const std::out_of_range&) { assert(pos1 > sv1.size()); } } template<typename CharT> @@ -391,7 +399,7 @@ int main() test(L"abcdefghijklmnopqrst", 0, -1, L"abcdefghijklmnopqrst", 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { test(U"", 0, 0, U"", 0); test(U"", 0, 0, U"abcde", -5); @@ -410,7 +418,7 @@ int main() test(U"abcdefghijklmnopqrst", 0, 12, U"abcdefghij", 10); test(U"abcdefghijklmnopqrst", 0, -1, U"abcdefghijklmnopqrst", 0); } - + { test(u"", 0, 0, u"", 0); test(u"", 0, 0, u"abcde", -5); @@ -431,7 +439,7 @@ int main() } #endif -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 { typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV; constexpr SV sv1; diff --git a/test/std/experimental/string.view/string.view.ops/compare.size_size_sv.pass.cpp b/test/std/experimental/string.view/string.view.ops/compare.size_size_sv.pass.cpp index 244de9eb5104a..2684d903405e3 100644 --- a/test/std/experimental/string.view/string.view.ops/compare.size_size_sv.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/compare.size_size_sv.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// - -// XFAIL: libcpp-no-exceptions // <string_view> // constexpr int compare(size_type pos1, size_type n1, basic_string_view str) const; @@ -16,6 +14,7 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" #include "constexpr_char_traits.hpp" int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); } @@ -24,19 +23,25 @@ template<typename CharT> void test1 ( std::experimental::basic_string_view<CharT> sv1, size_t pos1, size_t n1, std::experimental::basic_string_view<CharT> sv2, int expected ) { - try - { + if (pos1 > sv1.size()) { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + sv1.compare(pos1, n1, sv2); + assert(false); + } catch (const std::out_of_range&) { + } catch (...) { + assert(false); + } +#endif + } else { assert ( sign( sv1.compare(pos1, n1, sv2)) == sign(expected)); - assert(pos1 <= sv1.size()); } - catch (const std::out_of_range&) { assert(pos1 > sv1.size()); } } template<typename CharT> void test ( const CharT *s1, size_t pos1, size_t n1, const CharT *s2, int expected ) { typedef std::experimental::basic_string_view<CharT> string_view_t; - string_view_t sv1 ( s1 ); string_view_t sv2 ( s2 ); test1(sv1, pos1, n1, sv2, expected); @@ -355,7 +360,7 @@ int main () { test0(); test1(); test2(); - + { test("abcde", 5, 1, "", 0); test("abcde", 2, 4, "", 3); @@ -370,7 +375,7 @@ int main () { test(L"ABCde", 2, 4, L"abcde", -1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { test(u"abcde", 5, 1, u"", 0); test(u"abcde", 2, 4, u"", 3); @@ -386,7 +391,7 @@ int main () { } #endif -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 { typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV; constexpr SV sv1 { "abcde", 5 }; diff --git a/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp b/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp index 1c3bc089a656f..69de6335fb5ca 100644 --- a/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// - -// XFAIL: libcpp-no-exceptions // <string_view> // constexpr int compare(size_type pos1, size_type n1, @@ -17,6 +15,7 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" #include "constexpr_char_traits.hpp" int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); } @@ -25,22 +24,29 @@ template<typename CharT> void test1 ( std::experimental::basic_string_view<CharT> sv1, size_t pos1, size_t n1, const CharT *s2, size_t n2, int expected ) { - - try - { - assert ( sign( sv1.compare(pos1, n1, s2, n2)) == sign(expected)); - assert(pos1 <= sv1.size()); + if (pos1 > sv1.size()) { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + sv1.compare(pos1, n1, s2, n2); + assert(false); + } catch (const std::out_of_range&) { + return; + } catch (...) { + assert(false); + } +#endif + } else { + assert(sign(sv1.compare(pos1, n1, s2, n2)) == sign(expected)); } - catch (const std::out_of_range&) { assert(pos1 > sv1.size()); } + } template<typename CharT> -void test ( const CharT *s1, size_t pos1, size_t n1, - const CharT *s2, size_t n2, +void test ( const CharT *s1, size_t pos1, size_t n1, + const CharT *s2, size_t n2, int expected ) { typedef std::experimental::basic_string_view<CharT> string_view_t; - string_view_t sv1 ( s1 ); test1 (sv1, pos1, n1, s2, n2, expected); } @@ -1302,7 +1308,7 @@ int main () { test9(); test10(); test11(); - + { test("", 0, 0, "abcde", 0, 0); test("", 0, 0, "abcde", 1, -1); @@ -1319,7 +1325,7 @@ int main () { test(L"abcdefghijklmnopqrst", 10, 0, L"abcdefghij", 10, -10); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { test(U"", 0, 0, U"abcde", 0, 0); test(U"", 0, 0, U"abcde", 1, -1); @@ -1337,7 +1343,7 @@ int main () { } #endif -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 { typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV; constexpr SV sv1; diff --git a/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp b/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp index c7a6f1e1eb66d..5d5ccc5b5d59f 100644 --- a/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// - -// XFAIL: libcpp-no-exceptions // <string_view> // constexpr int compare(size_type pos1, size_type n1, basic_string_view str, @@ -17,6 +15,7 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" #include "constexpr_char_traits.hpp" int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); } @@ -26,22 +25,28 @@ void test1 ( std::experimental::basic_string_view<CharT> sv1, size_t pos1, size_ std::experimental::basic_string_view<CharT> sv2, size_t pos2, size_t n2, int expected ) { - try - { - assert ( sign( sv1.compare(pos1, n1, sv2, pos2, n2)) == sign(expected)); - assert(pos1 <= sv1.size()); - assert(pos2 <= sv2.size()); + if (pos1 > sv1.size() || pos2 > sv2.size()) { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + sv1.compare(pos1, n1, sv2, pos2, n2); + assert(false); + } catch (const std::out_of_range&) { + } catch (...) { + assert(false); + } +#endif + } else { + assert (sign( sv1.compare(pos1, n1, sv2, pos2, n2)) == sign(expected)); } - catch (const std::out_of_range&) { assert(pos1 > sv1.size() || pos2 > sv2.size()); } } template<typename CharT> -void test ( const CharT *s1, size_t pos1, size_t n1, - const CharT *s2, size_t pos2, size_t n2, +void test ( const CharT *s1, size_t pos1, size_t n1, + const CharT *s2, size_t pos2, size_t n2, int expected ) { typedef std::experimental::basic_string_view<CharT> string_view_t; - + string_view_t sv1 ( s1 ); string_view_t sv2 ( s2 ); test1(sv1, pos1, n1, sv2, pos2, n2, expected); @@ -5801,7 +5806,7 @@ int main () { test53(); test54(); - + { test("abcde", 5, 1, "", 0, 0, 0); test("abcde", 2, 4, "", 0, 0, 3); @@ -5816,7 +5821,7 @@ int main () { test(L"ABCde", 2, 4, L"abcde", 2, 4, -1); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { test(u"abcde", 5, 1, u"", 0, 0, 0); test(u"abcde", 2, 4, u"", 0, 0, 3); @@ -5832,7 +5837,7 @@ int main () { } #endif -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 { typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV; constexpr SV sv1 { "abcde", 5 }; diff --git a/test/std/experimental/string.view/string.view.ops/compare.sv.pass.cpp b/test/std/experimental/string.view/string.view.ops/compare.sv.pass.cpp index 3f686697ba400..4364ab0635430 100644 --- a/test/std/experimental/string.view/string.view.ops/compare.sv.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/compare.sv.pass.cpp @@ -19,7 +19,7 @@ int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); } template<typename CharT> -void test1 ( std::experimental::basic_string_view<CharT> sv1, +void test1 ( std::experimental::basic_string_view<CharT> sv1, std::experimental::basic_string_view<CharT> sv2, int expected ) { assert ( sign( sv1.compare(sv2)) == sign(expected)); } @@ -28,7 +28,7 @@ void test1 ( std::experimental::basic_string_view<CharT> sv1, template<typename CharT> void test ( const CharT *s1, const CharT *s2, int expected ) { typedef std::experimental::basic_string_view<CharT> string_view_t; - + string_view_t sv1 ( s1 ); string_view_t sv2 ( s2 ); test1(sv1, sv2, expected); @@ -70,7 +70,7 @@ int main () { test(L"abcdefghijklmnopqrst", L"abcdefghij", 10); test(L"abcdefghijklmnopqrst", L"abcdefghijklmnopqrst", 0); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test(u"", u"", 0); test(u"", u"abcde", -5); test(u"", u"abcdefghij", -10); @@ -105,7 +105,7 @@ int main () { test(U"abcdefghijklmnopqrst", U"abcdefghij", 10); test(U"abcdefghijklmnopqrst", U"abcdefghijklmnopqrst", 0); #endif - + #if _LIBCPP_STD_VER > 11 { typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV; @@ -117,5 +117,5 @@ int main () { static_assert ( sv3.compare(sv2) > 0, "" ); static_assert ( sv2.compare(sv3) < 0, "" ); } -#endif +#endif } diff --git a/test/std/experimental/string.view/string.view.ops/copy.pass.cpp b/test/std/experimental/string.view/string.view.ops/copy.pass.cpp index 0e4eb9e50bb0a..0acd5bda40112 100644 --- a/test/std/experimental/string.view/string.view.ops/copy.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/copy.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// - -// XFAIL: libcpp-no-exceptions // <string_view> // size_type copy(charT* s, size_type n, size_type pos = 0) const; @@ -23,30 +21,40 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test1 ( std::experimental::basic_string_view<CharT> sv, size_t n, size_t pos ) { const size_t rlen = std::min ( n, sv.size() - pos ); CharT *dest1 = new CharT [rlen + 1]; dest1[rlen] = 0; CharT *dest2 = new CharT [rlen + 1]; dest2[rlen] = 0; - - try { + + if (pos > sv.size()) { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + sv.copy(dest1, n, pos); + assert(false); + } catch (const std::out_of_range&) { + } catch (...) { + assert(false); + } +#endif + } else { sv.copy(dest1, n, pos); std::copy_n(sv.begin() + pos, rlen, dest2); - for ( size_t i = 0; i <= rlen; ++i ) assert ( dest1[i] == dest2[i] ); - } - catch ( const std::out_of_range & ) { assert ( pos > sv.size()); } + } delete [] dest1; - delete [] dest2; + delete [] dest2; } template<typename CharT> void test ( const CharT *s ) { typedef std::experimental::basic_string_view<CharT> string_view_t; - + string_view_t sv1 ( s ); test1(sv1, 0, 0); @@ -54,7 +62,7 @@ void test ( const CharT *s ) { test1(sv1, 20, 0); test1(sv1, sv1.size(), 0); test1(sv1, 20, string_view_t::npos); - + test1(sv1, 0, 3); test1(sv1, 2, 3); test1(sv1, 100, 3); @@ -79,7 +87,7 @@ int main () { test ( L"a" ); test ( L"" ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( u"ABCDE" ); test ( u"a" ); diff --git a/test/std/experimental/string.view/string.view.ops/substr.pass.cpp b/test/std/experimental/string.view/string.view.ops/substr.pass.cpp index c80e90a04788f..a651010d4b278 100644 --- a/test/std/experimental/string.view/string.view.ops/substr.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/substr.pass.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// - -// XFAIL: libcpp-no-exceptions // <string_view> // constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const; @@ -20,30 +18,42 @@ #include <experimental/string_view> #include <cassert> +#include "test_macros.h" + template<typename CharT> void test1 ( std::experimental::basic_string_view<CharT> sv, size_t n, size_t pos ) { - try { + if (pos > sv.size()) { +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + std::experimental::basic_string_view<CharT> sv1 = sv.substr(pos, n); + assert(false); + } catch (const std::out_of_range&) { + return; + } catch (...) { + assert(false); + } +#endif + } else { std::experimental::basic_string_view<CharT> sv1 = sv.substr(pos, n); const size_t rlen = std::min ( n, sv.size() - pos ); assert ( sv1.size() == rlen ); for ( size_t i = 0; i <= rlen; ++i ) assert ( sv[pos+i] == sv1[i] ); - } - catch ( const std::out_of_range & ) { assert ( pos > sv.size()); } + } } template<typename CharT> void test ( const CharT *s ) { typedef std::experimental::basic_string_view<CharT> string_view_t; - + string_view_t sv1 ( s ); test1(sv1, 0, 0); test1(sv1, 1, 0); test1(sv1, 20, 0); test1(sv1, sv1.size(), 0); - + test1(sv1, 0, 3); test1(sv1, 2, 3); test1(sv1, 100, 3); @@ -68,7 +78,7 @@ int main () { test ( L"a" ); test ( L"" ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( u"ABCDE" ); test ( u"a" ); @@ -79,8 +89,8 @@ int main () { test ( U"a" ); test ( U"" ); #endif - -#if _LIBCPP_STD_VER > 11 + +#if TEST_STD_VER > 11 { constexpr std::experimental::string_view sv1 { "ABCDE", 5 }; @@ -91,7 +101,7 @@ int main () { static_assert ( sv2[1] == 'B', "" ); static_assert ( sv2[2] == 'C', "" ); } - + { constexpr std::experimental::string_view sv2 = sv1.substr ( 3, 0 ); static_assert ( sv2.size() == 0, "" ); diff --git a/test/std/experimental/string.view/string.view.ops/to_string.pass.cpp b/test/std/experimental/string.view/string.view.ops/to_string.pass.cpp index a180ab257bf5f..a32a2684c5485 100644 --- a/test/std/experimental/string.view/string.view.ops/to_string.pass.cpp +++ b/test/std/experimental/string.view/string.view.ops/to_string.pass.cpp @@ -26,11 +26,11 @@ void test ( const CharT *s ) { { const std::experimental::basic_string_view<CharT> sv1 ( s ); String str1 = (String) sv1; - + assert ( sv1.size() == str1.size ()); assert ( std::char_traits<CharT>::compare ( sv1.data(), str1.data(), sv1.size()) == 0 ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 auto str2 = sv1.to_string(min_allocator<CharT>()); assert ( sv1.size() == str2.size ()); assert ( std::char_traits<CharT>::compare ( sv1.data(), str2.data(), sv1.size()) == 0 ); @@ -44,7 +44,7 @@ void test ( const CharT *s ) { assert ( sv1.size() == 0); assert ( sv1.size() == str1.size ()); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 auto str2 = sv1.to_string(min_allocator<CharT>()); assert ( sv1.size() == str2.size ()); #endif @@ -62,7 +62,7 @@ int main () { test ( L"a" ); test ( L"" ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( u"ABCDE" ); test ( u"a" ); diff --git a/test/std/experimental/utilities/meta/meta.type.synop/includes.pass.cpp b/test/std/experimental/utilities/meta/meta.type.synop/includes.pass.cpp index 2c90dd6418136..ddc82cb5482f0 100644 --- a/test/std/experimental/utilities/meta/meta.type.synop/includes.pass.cpp +++ b/test/std/experimental/utilities/meta/meta.type.synop/includes.pass.cpp @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/type_traits> #include <experimental/type_traits> -#if _LIBCPP_STD_VER > 11 -# ifndef _LIBCPP_TYPE_TRAITS -# error "<experimental/type_traits> must include <type_traits>" -# endif +#ifndef _LIBCPP_TYPE_TRAITS +# error "<experimental/type_traits> must include <type_traits>" #endif int main() diff --git a/test/std/experimental/utilities/meta/meta.type.synop/meta.rel.pass.cpp b/test/std/experimental/utilities/meta/meta.type.synop/meta.rel.pass.cpp index 96af4b676181e..8edc917303acf 100644 --- a/test/std/experimental/utilities/meta/meta.type.synop/meta.rel.pass.cpp +++ b/test/std/experimental/utilities/meta/meta.type.synop/meta.rel.pass.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/type_traits> #include <experimental/type_traits> -#if _LIBCPP_STD_VER > 11 - namespace ex = std::experimental; struct base_type {}; @@ -60,6 +59,4 @@ int main() static_assert(ex::is_convertible_v<T, U> == std::is_convertible<T, U>::value, ""); } } -#else /* _LIBCPP_STD_VER <= 11 */ -int main() {} -#endif /* _LIBCPP_STD_VER > 11 */ + diff --git a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.cat.pass.cpp b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.cat.pass.cpp index 2d1e706f67d22..a4a91c1369278 100644 --- a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.cat.pass.cpp +++ b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.cat.pass.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/type_traits> #include <experimental/type_traits> -#if _LIBCPP_STD_VER > 11 - namespace ex = std::experimental; struct class_type {}; @@ -176,6 +175,4 @@ int main() static_assert(ex::is_function_v<T> == std::is_function<T>::value, ""); } } -#else /* _LIBCPP_STD_VER <= 11 */ -int main() {} -#endif /* _LIBCPP_STD_VER > 11 */ + diff --git a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.comp.pass.cpp b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.comp.pass.cpp index 814f450f4e07a..b3927b120951e 100644 --- a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.comp.pass.cpp +++ b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.comp.pass.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/type_traits> #include <experimental/type_traits> -#if _LIBCPP_STD_VER > 11 - namespace ex = std::experimental; struct class_type {}; @@ -97,6 +96,4 @@ int main() static_assert(ex::is_member_pointer_v<T> == std::is_member_pointer<T>::value, ""); } } -#else /* _LIBCPP_STD_VER <= 11 */ -int main() {} -#endif /* _LIBCPP_STD_VER > 11 */ + diff --git a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.pass.cpp b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.pass.cpp index 41cb27fced37b..e267c6833ab99 100644 --- a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.pass.cpp +++ b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.pass.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/type_traits> #include <experimental/type_traits> -#if _LIBCPP_STD_VER > 11 - namespace ex = std::experimental; struct non_literal_type { non_literal_type() {} }; @@ -484,6 +483,4 @@ int main() static_assert(ex::has_virtual_destructor_v<T> == std::has_virtual_destructor<T>::value, ""); } } -#else /* _LIBCPP_STD_VER <= 11 */ -int main() {} -#endif /* _LIBCPP_STD_VER > 11 */ + diff --git a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.query.pass.cpp b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.query.pass.cpp index aedd369e5ac8e..f91667da523c0 100644 --- a/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.query.pass.cpp +++ b/test/std/experimental/utilities/meta/meta.type.synop/meta.unary.prop.query.pass.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <experimental/type_traits> #include <experimental/type_traits> -#if _LIBCPP_STD_VER > 11 - namespace ex = std::experimental; int main() @@ -61,6 +60,3 @@ int main() static_assert(ex::extent_v<T, 0> == std::extent<T, 0>::value, ""); } } -#else /* _LIBCPP_STD_VER <= 11 */ -int main() {} -#endif /* _LIBCPP_STD_VER > 11 */ diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign.pass.cpp new file mode 100644 index 0000000000000..33826383d1277 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// template <class U> propagate_const& propagate_const::operator=(const propagate_const<U>&)=delete; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +int main() { static_assert(!std::is_assignable<P, const P &>::value, ""); } diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_element_type.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_element_type.pass.cpp new file mode 100644 index 0000000000000..6de6c63d6104e --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_element_type.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> propagate_const& propagate_const::operator=(U&&); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<CopyConstructibleFromX> PY; + + X x1(1); + PY p(2); + + assert(*p==2); + + p = x1; + + assert(*p==1); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_propagate_const.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_propagate_const.pass.cpp new file mode 100644 index 0000000000000..ae6ef08d3cf08 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_propagate_const.pass.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 + +// <propagate_const> + +// template <class U> constexpr propagate_const& operator=(U&& u); // won't bind to propagate_const + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> PX; +typedef propagate_const<CopyConstructibleFromX> PY; + +int main() { static_assert(!std::is_assignable<PY, const PX &>::value, ""); } diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_element_type.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_element_type.pass.cpp new file mode 100644 index 0000000000000..e4051325f1c1b --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_element_type.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> propagate_const& propagate_const::operator=(U&&); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> P; + + X x1(1); + P p(2); + + assert(*p==2); + + p = x1; + + assert(*p==1); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign.pass.cpp new file mode 100644 index 0000000000000..b112b078d821b --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> propagate_const& propagate_const::operator=(propagate_const<U>&&); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> P; + + P p1(1); + P p2(2); + + p2=std::move(p1); + + assert(*p2==1); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible.pass.cpp new file mode 100644 index 0000000000000..282f0aee61531 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// template <class U> propagate_const& propagate_const::operator=(propagate_const<U>&&); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> PX; + typedef propagate_const<MoveConstructibleFromX> PY; + + PX px2(2); + PY py1(1); + + py1=std::move(px2); + + assert(*py1==2); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible_propagate_const.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible_propagate_const.pass.cpp new file mode 100644 index 0000000000000..743fc8eacbfa4 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible_propagate_const.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> PX; + typedef propagate_const<MoveConstructibleFromX> PY; + + PX px2(2); + PY py1(1); + + py1=std::move(px2); + + assert(*py1==2); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.explicit.ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.explicit.ctor.pass.cpp new file mode 100644 index 0000000000000..10b0dd896280d --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.explicit.ctor.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<ExplicitCopyConstructibleFromX> P; + +int main() { + static_assert(!std::is_convertible<P, X>::value, ""); + static_assert(std::is_constructible<P, X>::value, ""); +} + diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.non-explicit.ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.non-explicit.ctor.pass.cpp new file mode 100644 index 0000000000000..8ba5261de5e30 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.non-explicit.ctor.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> constexpr propagate_const(propagate_const<_Up>&& pu); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +typedef propagate_const<CopyConstructibleFromX> P; + +void f(const P& p) +{ + assert(*p==2); +} + +int main() { + f(X(2)); +} + diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.copy_ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.copy_ctor.pass.cpp new file mode 100644 index 0000000000000..ca65f3c47fff8 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.copy_ctor.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// template <class U> constexpr propagate_const& operator(propagate_const<_Up>&& pu); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> PX; +typedef propagate_const<CopyConstructibleFromX> PY; + +int main() { static_assert(!std::is_constructible<PX, PY>::value, ""); } + diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.explicit.move_ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.explicit.move_ctor.pass.cpp new file mode 100644 index 0000000000000..b021cbd5e5e1a --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.explicit.move_ctor.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// template <class U> constexpr propagate_const(propagate_const<_Up>&& pu); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> PX; +typedef propagate_const<ExplicitMoveConstructibleFromX> PY; + +int main() { + static_assert(!std::is_convertible<PY, PX &&>::value, ""); + static_assert(std::is_constructible<PY, PX &&>::value, ""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.move_ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.move_ctor.pass.cpp new file mode 100644 index 0000000000000..ee104a5250ea8 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.move_ctor.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class U> constexpr propagate_const(propagate_const<_Up>&& pu); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +typedef propagate_const<MoveConstructibleFromX> PY; +typedef propagate_const<X> PX; + +int main() { + PX px(1); + PY py(std::move(px)); + + assert(*py==1); +} + diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/copy_ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/copy_ctor.pass.cpp new file mode 100644 index 0000000000000..daefdf320e3af --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/copy_ctor.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// propagate_const(const propagate_const&)=delete; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +int main() { static_assert(!std::is_constructible<P, const P &>::value, ""); } diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.explicit.ctor.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.explicit.ctor.pass.cpp new file mode 100644 index 0000000000000..6a7289b2f1a6c --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.explicit.ctor.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// template <class U> propagate_const(U&&); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<ExplicitX> P; + +int main() { + static_assert(!std::is_convertible<P, int>::value, ""); + static_assert(std::is_constructible<P, int>::value, ""); +} + diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.non-explicit.ctor.pass.cpp index 85c32ca6d4955..9c6ed89f6757b 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.non-explicit.ctor.pass.cpp @@ -9,19 +9,20 @@ // UNSUPPORTED: c++98, c++03, c++11 -#include <tuple> -#include <string> -#include <complex> +// <propagate_const> +// template <class U> propagate_const(U&&); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" #include <cassert> -int main() +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +void f(const P&) { -#if _LIBCPP_STD_VER > 11 - typedef std::complex<float> cf; - auto t1 = std::make_tuple<int, std::string> ( 42, "Hi" ); - assert (( std::get<cf>(t1) == cf {1,2} )); // no such type -#else -#error -#endif } + +int main() { f(2); } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/move_ctor.pass.cpp index 0a8d5829d02b1..a5adf2d1f7f0b 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/move_ctor.pass.cpp @@ -9,19 +9,20 @@ // UNSUPPORTED: c++98, c++03, c++11 -#include <tuple> -#include <string> -#include <complex> +// <propagate_const> +// propagate_const(propagate_const&&)=default; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" #include <cassert> -int main() -{ -#if _LIBCPP_STD_VER > 11 - typedef std::complex<float> cf; - auto t1 = std::make_tuple<int, int, std::string, cf> ( 42, 21, "Hi", { 1,2 } ); - assert ( std::get<int>(t1) == 42 ); // two ints here -#else -#error -#endif +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> P; + + P p1(2); + P p2(std::move(p1)); } diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/dereference.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/dereference.pass.cpp new file mode 100644 index 0000000000000..5e9e0434fed7b --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/dereference.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// element_type& propagate_const::operator*(); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +constexpr P f() +{ + P p(1); + *p = 2; + return p; +} + +int main() { + constexpr P p = f(); + static_assert(*p==2,""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/explicit_operator_element_type_ptr.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/explicit_operator_element_type_ptr.pass.cpp new file mode 100644 index 0000000000000..808eda0e3cc3c --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/explicit_operator_element_type_ptr.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// propagate_const::operator element_type*(); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +int main() { static_assert(!std::is_convertible<P, int *>::value, ""); } diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/get.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/get.pass.cpp new file mode 100644 index 0000000000000..298389b7b59dc --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/get.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// element_type* propagate_const::get(); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +constexpr P f() +{ + P p(1); + *p.get() = 2; + return p; +} + +int main() { + constexpr P p = f(); + static_assert(*(p.get())==2,""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/op_arrow.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/op_arrow.pass.cpp new file mode 100644 index 0000000000000..810e86eea172e --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/op_arrow.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// element_type* propagate_const::operator->(); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +constexpr P f() +{ + P p(1); + *(p.operator->()) = 2; + return p; +} + +int main() { + constexpr P p = f(); + static_assert(*(p.operator->())==2,""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/operator_element_type_ptr.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/operator_element_type_ptr.pass.cpp new file mode 100644 index 0000000000000..6bdf76c92e995 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/operator_element_type_ptr.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// propagate_const::operator element_type*(); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<XWithImplicitIntStarConversion> P; + + P p(1); + + int* ptr_1 = p; + + assert(*ptr_1==1); + + *ptr_1 = 2; + + assert(*ptr_1==2); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/dereference.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/dereference.pass.cpp new file mode 100644 index 0000000000000..292335449649c --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/dereference.pass.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// const element_type& propagate_const::operator*() const; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> P; + + constexpr P p(1); + + static_assert(*p==1,""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/explicit_operator_element_type_ptr.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/explicit_operator_element_type_ptr.pass.cpp new file mode 100644 index 0000000000000..b9b6b3f90f230 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/explicit_operator_element_type_ptr.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// propagate_const::operator const element_type*() const; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <type_traits> + +using std::experimental::propagate_const; + +typedef propagate_const<X> P; + +int main() { + static_assert(!std::is_convertible<const P, const int *>::value, ""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/get.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/get.pass.cpp new file mode 100644 index 0000000000000..8029ff47475ef --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/get.pass.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// const element_type* propagate_const::get() const; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> P; + + constexpr P p(1); + + static_assert(*(p.get())==1, ""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/op_arrow.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/op_arrow.pass.cpp new file mode 100644 index 0000000000000..4ceea8a1d7819 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/op_arrow.pass.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// const element_type* propagate_const::operator->() const; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +int main() { + + typedef propagate_const<X> P; + + constexpr P p(1); + + static_assert(*(p.operator->())==1,""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/operator_element_type_ptr.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/operator_element_type_ptr.pass.cpp new file mode 100644 index 0000000000000..1ac6d254a3429 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/operator_element_type_ptr.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// propagate_const::operator const element_type*() const; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +typedef propagate_const<XWithImplicitConstIntStarConversion> P; + +constexpr P p(1); + +constexpr const int *ptr_1 = p; + +int main() { assert(*ptr_1 == 1); } diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.class/swap.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.class/swap.pass.cpp new file mode 100644 index 0000000000000..c5c832bbe0c2c --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.class/swap.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> constexpr void propagate_const::swap(propagate_const<T>& x); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +bool swap_called = false; +void swap(X &, X &) { swap_called = true; } + +int main() { + typedef propagate_const<X> P; + P p1(1); + P p2(2); + p1.swap(p2); + assert(swap_called); +} + diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/hash.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/hash.pass.cpp new file mode 100644 index 0000000000000..8cf670a25402c --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/hash.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// template <class T> struct hash<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +namespace std { +template <> struct hash<X> +{ + typedef X first_argument_type; + + size_t operator()(const first_argument_type& x1) const + { + return 99; + } + +}; +} // namespace std + +int main() { + + typedef propagate_const<X> P; + + P p(1); + + auto h = std::hash<P>(); + + assert(h(p)==99); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/equal_to.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/equal_to.pass.cpp new file mode 100644 index 0000000000000..d54222a97a1c6 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/equal_to.pass.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 + +// <propagate_const> + +// template <class T> struct equal_to<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator==(const X &x1, const X &x2) { return x1.i_ == x2.i_; } + +int main() { + + typedef propagate_const<X> P; + + P p1_1(1); + P p2_1(1); + P p3_2(2); + + auto c = std::equal_to<P>(); + + assert(c(p1_1,p2_1)); + assert(!c(p1_1,p3_2)); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater.pass.cpp new file mode 100644 index 0000000000000..fb8e1282f214e --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater.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 + +// <propagate_const> + +// template <class T> struct greater<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator>(const X &x1, const X &x2) { return x1.i_ > x2.i_; } + +int main() { + + typedef propagate_const<X> P; + + P p1_1(1); + P p2_1(1); + P p3_2(2); + + auto c = std::greater<P>(); + + assert(!c(p1_1,p2_1)); + assert(!c(p2_1,p1_1)); + assert(!c(p1_1,p3_2)); + assert(c(p3_2,p1_1)); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater_equal.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater_equal.pass.cpp new file mode 100644 index 0000000000000..29a1868d64716 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater_equal.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 + +// <propagate_const> + +// template <class T> struct greater_equal<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator>=(const X &x1, const X &x2) { return x1.i_ >= x2.i_; } + +int main() { + + typedef propagate_const<X> P; + + P p1_1(1); + P p2_1(1); + P p3_2(2); + + auto c = std::greater_equal<P>(); + + assert(c(p1_1,p2_1)); + assert(c(p2_1,p1_1)); + assert(!c(p1_1,p3_2)); + assert(c(p3_2,p1_1)); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less.pass.cpp new file mode 100644 index 0000000000000..074a3914a51c0 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less.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 + +// <propagate_const> + +// template <class T> struct less<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator<(const X &x1, const X &x2) { return x1.i_ < x2.i_; } + +int main() { + + typedef propagate_const<X> P; + + P p1_1(1); + P p2_1(1); + P p3_2(2); + + auto c = std::less<P>(); + + assert(!c(p1_1,p2_1)); + assert(!c(p2_1,p1_1)); + assert(c(p1_1,p3_2)); + assert(!c(p3_2,p1_1)); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less_equal.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less_equal.pass.cpp new file mode 100644 index 0000000000000..a2082ec5cb317 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less_equal.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 + +// <propagate_const> + +// template <class T> struct less_equal<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator<=(const X &x1, const X &x2) { return x1.i_ <= x2.i_; } + +int main() { + + typedef propagate_const<X> P; + + P p1_1(1); + P p2_1(1); + P p3_2(2); + + auto c = std::less_equal<P>(); + + assert(c(p1_1,p2_1)); + assert(c(p2_1,p1_1)); + assert(c(p1_1,p3_2)); + assert(!c(p3_2,p1_1)); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/not_equal_to.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/not_equal_to.pass.cpp new file mode 100644 index 0000000000000..20756d984e94d --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/not_equal_to.pass.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 + +// <propagate_const> + +// template <class T> struct not_equal_to<experimental::fundamentals_v2::propagate_const<T>>; + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator!=(const X &x1, const X &x2) { return x1.i_ != x2.i_; } + +int main() { + + typedef propagate_const<X> P; + + P p1_1(1); + P p2_1(1); + P p3_2(2); + + auto c = std::not_equal_to<P>(); + + assert(!c(p1_1,p2_1)); + assert(c(p1_1,p3_2)); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/equal.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/equal.pass.cpp new file mode 100644 index 0000000000000..a4a28b48a545b --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/equal.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 + +// <propagate_const> + +// template <class T> constexpr bool operator==(const propagate_const<T>& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator==(const T& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator==(const propagate_const<T>& x, const T& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; +using std::nullptr_t; + +constexpr bool operator==(const X &lhs, const X &rhs) { + return lhs.i_ == rhs.i_; +} + +constexpr bool operator==(const X &, const nullptr_t &) { + return false; +} + +constexpr bool operator==(const nullptr_t &, const X &) { + return false; +} + +int main() { + constexpr X x1_1(1); + constexpr X x2_1(1); + constexpr X x3_2(2); + + static_assert(x1_1 == x1_1, ""); + static_assert(x1_1 == x2_1, ""); + static_assert(!(x1_1 == x3_2), ""); + + typedef propagate_const<X> P; + + constexpr P p1_1(1); + constexpr P p2_1(1); + constexpr P p3_2(2); + + static_assert(p1_1 == p1_1, ""); + static_assert(p1_1 == p2_1, ""); + static_assert(!(p1_1 == p3_2), ""); + + static_assert(x1_1 == p1_1, ""); + static_assert(!(x1_1 == p3_2), ""); + + static_assert(p1_1 == x1_1, ""); + static_assert(!(p1_1 == x3_2), ""); + + static_assert(!(p1_1==nullptr),""); + static_assert(!(nullptr==p1_1),""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_equal.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_equal.pass.cpp new file mode 100644 index 0000000000000..4b5b42467c092 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_equal.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. +// +//>==---------------------------------------------------------------------->==// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> constexpr bool operator>=(const propagate_const<T>& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator>=(const T& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator>=(const propagate_const<T>& x, const T& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator>=(const X &lhs, const X &rhs) { + return lhs.i_ >= rhs.i_; +} + +int main() { + constexpr X x1_1(1); + constexpr X x2_1(1); + constexpr X x3_2(2); + + static_assert(x1_1 >= x2_1, ""); + static_assert(!(x1_1 >= x3_2), ""); + static_assert(x3_2 >= x1_1, ""); + + typedef propagate_const<X> P; + + constexpr P p1_1(1); + constexpr P p2_1(1); + constexpr P p3_2(2); + + static_assert(p1_1 >= p2_1, ""); + static_assert(!(p1_1 >= p3_2), ""); + static_assert(p3_2 >= p1_1, ""); + + static_assert(p1_1 >= x2_1, ""); + static_assert(!(p1_1 >= x3_2), ""); + static_assert(p3_2 >= x1_1, ""); + + static_assert(x1_1 >= p2_1, ""); + static_assert(!(x1_1 >= p3_2), ""); + static_assert(x3_2 >= p1_1, ""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_than.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_than.pass.cpp new file mode 100644 index 0000000000000..3865b9370727f --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_than.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: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> constexpr bool operator>(const propagate_const<T>& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator>(const T& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator>(const propagate_const<T>& x, const T& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator>(const X &lhs, const X &rhs) { + return lhs.i_ > rhs.i_; +} + +int main() { + constexpr X x1_1(1); + constexpr X x2_1(1); + constexpr X x3_2(2); + + static_assert(!(x1_1 > x2_1), ""); + static_assert(x3_2 > x1_1, ""); + + typedef propagate_const<X> P; + + constexpr P p1_1(1); + constexpr P p2_1(1); + constexpr P p3_2(2); + + static_assert(!(p1_1 > p2_1), ""); + static_assert(p3_2 > p1_1, ""); + + static_assert(!(p1_1 > x2_1), ""); + static_assert(p3_2 > x1_1, ""); + + static_assert(!(x1_1 > p2_1), ""); + static_assert(x3_2 > p1_1, ""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_equal.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_equal.pass.cpp new file mode 100644 index 0000000000000..3ac12c27f8bbc --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_equal.pass.cpp @@ -0,0 +1,55 @@ +//<==----------------------------------------------------------------------<==// +// +// 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 + +// <propagate_const> + +// template <class T> constexpr bool operator<=(const propagate_const<T>& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator<=(const T& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator<=(const propagate_const<T>& x, const T& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator<=(const X &lhs, const X &rhs) { + return lhs.i_ <= rhs.i_; +} + +int main() { + constexpr X x1_1(1); + constexpr X x2_1(1); + constexpr X x3_2(2); + + static_assert(x1_1 <= x2_1, ""); + static_assert(x1_1 <= x3_2, ""); + static_assert(!(x3_2 <= x1_1), ""); + + typedef propagate_const<X> P; + + constexpr P p1_1(1); + constexpr P p2_1(1); + constexpr P p3_2(2); + + static_assert(p1_1 <= p2_1, ""); + static_assert(p1_1 <= p3_2, ""); + static_assert(!(p3_2 <= p1_1), ""); + + static_assert(p1_1 <= x2_1, ""); + static_assert(p1_1 <= x3_2, ""); + static_assert(!(p3_2 <= x1_1), ""); + + static_assert(x1_1 <= p2_1, ""); + static_assert(x1_1 <= p3_2, ""); + static_assert(!(x3_2 <= p1_1), ""); + +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_than.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_than.pass.cpp new file mode 100644 index 0000000000000..42b2730c58cc5 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_than.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: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> constexpr bool operator<(const propagate_const<T>& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator<(const T& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator<(const propagate_const<T>& x, const T& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +constexpr bool operator<(const X &lhs, const X &rhs) { + return lhs.i_ < rhs.i_; +} + +int main() { + constexpr X x1_1(1); + constexpr X x2_1(1); + constexpr X x3_2(2); + + static_assert(!(x1_1 < x2_1), ""); + static_assert(x1_1 < x3_2, ""); + + typedef propagate_const<X> P; + + constexpr P p1_1(1); + constexpr P p2_1(1); + constexpr P p3_2(2); + + static_assert(!(p1_1 < p2_1), ""); + static_assert(p1_1 < p3_2, ""); + + static_assert(!(x1_1 < p1_1), ""); + static_assert(x1_1 < p3_2, ""); + + static_assert(!(p1_1 < x1_1), ""); + static_assert(p1_1 < x3_2, ""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/not_equal.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/not_equal.pass.cpp new file mode 100644 index 0000000000000..1104abdecb6d5 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/not_equal.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <propagate_const> + +// template <class T> constexpr bool operator!=(const propagate_const<T>& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator!=(const T& x, const propagate_const<T>& y); +// template <class T> constexpr bool operator!=(const propagate_const<T>& x, const T& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; +using std::nullptr_t; + +constexpr bool operator!=(const X &lhs, const X &rhs) { + return lhs.i_ != rhs.i_; +} + +constexpr bool operator!=(const X &, const nullptr_t &) { + return true; +} + +constexpr bool operator!=(const nullptr_t &, const X &) { + return true; +} + +int main() { + constexpr X x1_1(1); + constexpr X x2_1(1); + constexpr X x3_2(2); + + static_assert(!(x1_1 != x2_1), ""); + static_assert(x1_1 != x3_2, ""); + + typedef propagate_const<X> P; + + constexpr P p1_1(1); + constexpr P p2_1(1); + constexpr P p3_2(2); + + static_assert(!(p1_1 != p2_1), ""); + static_assert(p1_1 != p3_2, ""); + + static_assert(!(x1_1 != p1_1), ""); + static_assert(x1_1 != p3_2, ""); + + static_assert(!(p1_1 != x1_1), ""); + static_assert(p1_1 != x3_2, ""); + + static_assert(p1_1!=nullptr,""); + static_assert(nullptr!=p1_1,""); +} diff --git a/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/swap.pass.cpp b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/swap.pass.cpp new file mode 100644 index 0000000000000..6c3b609489658 --- /dev/null +++ b/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/swap.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <propagate_const> + +// template <class T> constexpr void swap(propagate_const<T>& x, propagate_const<T>& y); + +#include <experimental/propagate_const> +#include "propagate_const_helpers.h" +#include <cassert> + +using std::experimental::propagate_const; + +bool swap_called = false; +void swap(X &, X &) { swap_called = true; } + +int main() { + typedef propagate_const<X> P; + P p1(1); + P p2(2); + swap(p1, p2); + assert(swap_called); +} 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 index 2d700486f26bd..5b8a8f09d1eee 100644 --- a/test/std/experimental/utilities/tuple/tuple.apply/constexpr_types.pass.cpp +++ b/test/std/experimental/utilities/tuple/tuple.apply/constexpr_types.pass.cpp @@ -9,11 +9,6 @@ // 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 &&) 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 index 1ec38da5c043e..314d2783f7ec3 100644 --- a/test/std/experimental/utilities/tuple/tuple.apply/return_type.pass.cpp +++ b/test/std/experimental/utilities/tuple/tuple.apply/return_type.pass.cpp @@ -25,30 +25,27 @@ 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<2>) { return static_cast<int &>(my_int); } +int const & f(index<3>) { return static_cast<int const &>(my_int); } +int volatile & f(index<4>) { return static_cast<int volatile &>(my_int); } +int const volatile & f(index<5>) { 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<6>) { return static_cast<int &&>(my_int); } +int const && f(index<7>) { return static_cast<int const &&>(my_int); } +int volatile && f(index<8>) { return static_cast<int volatile &&>(my_int); } +int const volatile && f(index<9>) { 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); } +int * f(index<10>) { return static_cast<int *>(&my_int); } +int const * f(index<11>) { return static_cast<int const *>(&my_int); } +int volatile * f(index<12>) { return static_cast<int volatile *>(&my_int); } +int const volatile * f(index<13>) { return static_cast<int const volatile *>(&my_int); } template <int Func, class Expect> void test() { - using F = decltype((f(index<Func>{}))); + using F = decltype(f(index<Func>{})); static_assert(std::is_same<F, Expect>::value, ""); } @@ -58,19 +55,16 @@ 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 *>(); + test<2, int &>(); + test<3, int const &>(); + test<4, int volatile &>(); + test<5, int const volatile &>(); + test<6, int &&>(); + test<7, int const &&>(); + test<8, int volatile &&>(); + test<9, int const volatile &&>(); + test<10, int *>(); + test<11, int const *>(); + test<12, int volatile *>(); + test<13, int const volatile *>(); } diff --git a/test/std/input.output/file.streams/c.files/cinttypes.pass.cpp b/test/std/input.output/file.streams/c.files/cinttypes.pass.cpp index 4cb2c4c2f448e..8937950522c8b 100644 --- a/test/std/input.output/file.streams/c.files/cinttypes.pass.cpp +++ b/test/std/input.output/file.streams/c.files/cinttypes.pass.cpp @@ -917,7 +917,7 @@ int main() std::uintmax_t i4 = 0; } { - std::imaxdiv_t i1 = {0}; + std::imaxdiv_t i1 = {}; } std::intmax_t i = 0; static_assert((std::is_same<decltype(std::imaxabs(i)), std::intmax_t>::value), ""); 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 a06f0443d701f..4c2be7d4aa9e5 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 @@ -78,17 +78,24 @@ #include <cstdarg> +#if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wformat-zero-length" #pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif int main() { std::FILE* fp = 0; - std::fpos_t fpos = {0}; + std::fpos_t fpos = {}; std::size_t s = 0; char* cp = 0; std::va_list va; + ((void)fp); // Prevent unused warning + ((void)fpos); // Prevent unused warning + ((void)s); // Prevent unused warning + ((void)cp); // Prevent unused warning + ((void)va); // Prevent unused warning 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::setbuf(fp,cp)), void>::value), ""); diff --git a/test/std/input.output/file.streams/c.files/gets.fail.cpp b/test/std/input.output/file.streams/c.files/gets.fail.cpp index 4250e23c11c2b..064d72cd9e4a1 100644 --- a/test/std/input.output/file.streams/c.files/gets.fail.cpp +++ b/test/std/input.output/file.streams/c.files/gets.fail.cpp @@ -7,17 +7,14 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // test <cstdio> -// gets +// gets #include <cstdio> int main() { -#if _LIBCPP_STD_VER > 11 (void) std::gets((char *) NULL); -#else -#error -#endif } diff --git a/test/std/input.output/iostream.format/ext.manip/get_time.pass.cpp b/test/std/input.output/iostream.format/ext.manip/get_time.pass.cpp index a8b82a62bb6b6..553c2b2eb3a08 100644 --- a/test/std/input.output/iostream.format/ext.manip/get_time.pass.cpp +++ b/test/std/input.output/iostream.format/ext.manip/get_time.pass.cpp @@ -44,7 +44,7 @@ int main() testbuf<char> sb(" Sat Dec 31 23:55:59 2061"); std::istream is(&sb); is.imbue(std::locale(LOCALE_en_US_UTF_8)); - std::tm t = {0}; + std::tm t = {}; is >> std::get_time(&t, "%a %b %d %H:%M:%S %Y"); assert(t.tm_sec == 59); assert(t.tm_min == 55); @@ -60,7 +60,7 @@ int main() testbuf<wchar_t> sb(L" Sat Dec 31 23:55:59 2061"); std::wistream is(&sb); is.imbue(std::locale(LOCALE_en_US_UTF_8)); - std::tm t = {0}; + std::tm t = {}; is >> std::get_time(&t, L"%a %b %d %H:%M:%S %Y"); assert(t.tm_sec == 59); assert(t.tm_min == 55); diff --git a/test/std/input.output/iostream.format/ext.manip/put_time.pass.cpp b/test/std/input.output/iostream.format/ext.manip/put_time.pass.cpp index f4e3ded1745c5..e907708d0f227 100644 --- a/test/std/input.output/iostream.format/ext.manip/put_time.pass.cpp +++ b/test/std/input.output/iostream.format/ext.manip/put_time.pass.cpp @@ -56,7 +56,7 @@ int main() testbuf<char> sb; std::ostream os(&sb); os.imbue(std::locale(LOCALE_en_US_UTF_8)); - std::tm t = {0}; + std::tm t = {}; t.tm_sec = 59; t.tm_min = 55; t.tm_hour = 23; @@ -72,7 +72,7 @@ int main() testbuf<wchar_t> sb; std::wostream os(&sb); os.imbue(std::locale(LOCALE_en_US_UTF_8)); - std::tm t = {0}; + std::tm t = {}; t.tm_sec = 59; t.tm_min = 55; t.tm_hour = 23; diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore_0xff.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore_0xff.pass.cpp index ccc3545483e71..e498172aa8b1b 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore_0xff.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore_0xff.pass.cpp @@ -21,10 +21,10 @@ int main() { int bad=-1; std::ostringstream os; - os << "aaaabbbb" << static_cast<char>(bad) + os << "aaaabbbb" << static_cast<char>(bad) << "ccccdddd" << std::endl; std::string s=os.str(); - + std::istringstream is(s); const unsigned int ignoreLen=10; size_t a=is.tellg(); diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp index 3cedf91928084..818d42c26212c 100644 --- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp +++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp @@ -40,7 +40,7 @@ public: CharT* egptr() const {return base::egptr();} protected: typename base::pos_type seekoff(typename base::off_type off, - std::ios_base::seekdir way, + std::ios_base::seekdir, std::ios_base::openmode which) { assert(which == std::ios_base::in); diff --git a/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minus1.pass b/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minus1.pass.cpp index 27b8cfd85c960..47e257a18684d 100644 --- a/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minus1.pass +++ b/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minus1.pass.cpp @@ -21,8 +21,10 @@ // Testing to make sure that the max length values are correctly inserted -#include <iostream> #include <sstream> +#include <ios> +#include <cctype> +#include <cstdint> #include <cassert> template <typename T> @@ -30,7 +32,6 @@ void test_octal(const char *expected) { std::stringstream ss; ss << std::oct << static_cast<T>(-1); - assert(ss.str() == expected); } @@ -39,8 +40,6 @@ void test_dec(const char *expected) { std::stringstream ss; ss << std::dec << static_cast<T>(-1); - -// std::cout << ss.str() << " " << expected << std::endl; assert(ss.str() == expected); } @@ -49,22 +48,32 @@ void test_hex(const char *expected) { std::stringstream ss; ss << std::hex << static_cast<T>(-1); - + std::string str = ss.str(); for (size_t i = 0; i < str.size(); ++i ) str[i] = std::toupper(str[i]); - + assert(str == expected); } -int main(int argc, char* argv[]) +int main() { + test_octal<uint16_t>( "177777"); test_octal< int16_t>( "177777"); test_octal<uint32_t>( "37777777777"); test_octal< int32_t>( "37777777777"); test_octal<uint64_t>("1777777777777777777777"); test_octal< int64_t>("1777777777777777777777"); + test_octal<uint64_t>("1777777777777777777777"); + if (sizeof(long) == sizeof(int64_t)) { + test_octal< unsigned long>("1777777777777777777777"); + test_octal< long>("1777777777777777777777"); + } + if (sizeof(long long) == sizeof(int64_t)) { + test_octal< unsigned long long>("1777777777777777777777"); + test_octal< long long>("1777777777777777777777"); + } test_dec<uint16_t>( "65535"); test_dec< int16_t>( "-1"); @@ -72,6 +81,14 @@ int main(int argc, char* argv[]) test_dec< int32_t>( "-1"); test_dec<uint64_t>("18446744073709551615"); test_dec< int64_t>( "-1"); + if (sizeof(long) == sizeof(int64_t)) { + test_dec<unsigned long>("18446744073709551615"); + test_dec< long>( "-1"); + } + if (sizeof(long long) == sizeof(int64_t)) { + test_dec<unsigned long long>("18446744073709551615"); + test_dec< long long>( "-1"); + } test_hex<uint16_t>( "FFFF"); test_hex< int16_t>( "FFFF"); @@ -79,6 +96,12 @@ int main(int argc, char* argv[]) test_hex< int32_t>( "FFFFFFFF"); test_hex<uint64_t>("FFFFFFFFFFFFFFFF"); test_hex< int64_t>("FFFFFFFFFFFFFFFF"); - - return 0; + if (sizeof(long) == sizeof(int64_t)) { + test_hex<unsigned long>("FFFFFFFFFFFFFFFF"); + test_hex< long>("FFFFFFFFFFFFFFFF"); + } + if (sizeof(long long) == sizeof(int64_t)) { + test_hex<unsigned long long>("FFFFFFFFFFFFFFFF"); + test_hex< long long>("FFFFFFFFFFFFFFFF"); + } } diff --git a/test/std/input.output/iostream.format/quoted.manip/quoted.pass.cpp b/test/std/input.output/iostream.format/quoted.manip/quoted.pass.cpp index d09b3cae4f66e..ee9aabcb6ac8e 100644 --- a/test/std/input.output/iostream.format/quoted.manip/quoted.pass.cpp +++ b/test/std/input.output/iostream.format/quoted.manip/quoted.pass.cpp @@ -16,79 +16,95 @@ #include <string> #include <cassert> -#if _LIBCPP_STD_VER > 11 - -bool is_skipws ( const std::istream *is ) { - return ( is->flags() & std::ios_base::skipws ) != 0; - } +#include "test_macros.h" +#if TEST_STD_VER > 11 -bool is_skipws ( const std::wistream *is ) { - return ( is->flags() & std::ios_base::skipws ) != 0; +template <class CharT, class Traits> +bool is_skipws ( const std::basic_istream<CharT, Traits>& is ) { + return ( is.flags() & std::ios_base::skipws ) != 0; } -void both_ways ( const char *p ) { - std::string str(p); +template <class CharT, class Traits = std::char_traits<CharT>> +void both_ways ( const CharT *p ) { + std::basic_string<CharT, Traits> str(p); auto q = std::quoted(str); - std::stringstream ss; - bool skippingws = is_skipws ( &ss ); + std::basic_stringstream<CharT, Traits> ss; + bool skippingws = is_skipws ( ss ); ss << q; ss >> q; } -void round_trip ( const char *p ) { - std::stringstream ss; - bool skippingws = is_skipws ( &ss ); +template <class CharT, class Traits = std::char_traits<CharT>> +void round_trip ( const CharT *p ) { + std::basic_stringstream<CharT, Traits> ss; + bool skippingws = is_skipws ( ss ); + ss << std::quoted(p); - std::string s; + std::basic_string<CharT, Traits> s; ss >> std::quoted(s); assert ( s == p ); - assert ( skippingws == is_skipws ( &ss )); + assert ( skippingws == is_skipws ( ss )); } -void round_trip_ws ( const char *p ) { - std::stringstream ss; + +template <class CharT, class Traits = std::char_traits<CharT>> +void round_trip_ws ( const CharT *p ) { + std::basic_stringstream<CharT, Traits> ss; std::noskipws ( ss ); - bool skippingws = is_skipws ( &ss ); + bool skippingws = is_skipws ( ss ); + ss << std::quoted(p); - std::string s; + std::basic_string<CharT, Traits> s; ss >> std::quoted(s); assert ( s == p ); - assert ( skippingws == is_skipws ( &ss )); + assert ( skippingws == is_skipws ( ss )); } -void round_trip_d ( const char *p, char delim ) { - std::stringstream ss; - ss << std::quoted(p, delim); - std::string s; - ss >> std::quoted(s, delim); +template <class CharT, class Traits = std::char_traits<CharT>> +void round_trip_d ( const CharT *p, char delim ) { + std::basic_stringstream<CharT, Traits> ss; + CharT d(delim); + + ss << std::quoted(p, d); + std::basic_string<CharT, Traits> s; + ss >> std::quoted(s, d); assert ( s == p ); } -void round_trip_e ( const char *p, char escape ) { - std::stringstream ss; - ss << std::quoted(p, '"', escape ); - std::string s; - ss >> std::quoted(s, '"', escape ); +template <class CharT, class Traits = std::char_traits<CharT>> +void round_trip_e ( const CharT *p, char escape ) { + std::basic_stringstream<CharT, Traits> ss; + CharT e(escape); + + ss << std::quoted(p, CharT('"'), e ); + std::basic_string<CharT, Traits> s; + ss >> std::quoted(s, CharT('"'), e ); assert ( s == p ); } - -std::string quote ( const char *p, char delim='"', char escape='\\' ) { - std::stringstream ss; - ss << std::quoted(p, delim, escape); - std::string s; +template <class CharT, class Traits = std::char_traits<CharT>> +std::basic_string<CharT, Traits> quote ( const CharT *p, char delim='"', char escape='\\' ) { + std::basic_stringstream<CharT, Traits> ss; + CharT d(delim); + CharT e(escape); + ss << std::quoted(p, d, e); + std::basic_string<CharT, Traits> s; ss >> s; // no quote return s; } -std::string unquote ( const char *p, char delim='"', char escape='\\' ) { - std::stringstream ss; +template <class CharT, class Traits = std::char_traits<CharT>> +std::basic_string<CharT, Traits> unquote ( const CharT *p, char delim='"', char escape='\\' ) { + std::basic_stringstream<CharT, Traits> ss; ss << p; - std::string s; - ss >> std::quoted(s, delim, escape); + + CharT d(delim); + CharT e(escape); + std::basic_string<CharT, Traits> s; + ss >> std::quoted(s, d, e); return s; } @@ -98,7 +114,7 @@ void test_padding () { ss << std::left << std::setw(10) << std::setfill('!') << std::quoted("abc", '`'); assert ( ss.str() == "`abc`!!!!!" ); } - + { std::stringstream ss; ss << std::right << std::setw(10) << std::setfill('!') << std::quoted("abc", '`'); @@ -107,61 +123,6 @@ void test_padding () { } -void round_trip ( const wchar_t *p ) { - std::wstringstream ss; - bool skippingws = is_skipws ( &ss ); - ss << std::quoted(p); - std::wstring s; - ss >> std::quoted(s); - assert ( s == p ); - assert ( skippingws == is_skipws ( &ss )); - } - - -void round_trip_ws ( const wchar_t *p ) { - std::wstringstream ss; - std::noskipws ( ss ); - bool skippingws = is_skipws ( &ss ); - ss << std::quoted(p); - std::wstring s; - ss >> std::quoted(s); - assert ( s == p ); - assert ( skippingws == is_skipws ( &ss )); - } - -void round_trip_d ( const wchar_t *p, wchar_t delim ) { - std::wstringstream ss; - ss << std::quoted(p, delim); - std::wstring s; - ss >> std::quoted(s, delim); - assert ( s == p ); - } - -void round_trip_e ( const wchar_t *p, wchar_t escape ) { - std::wstringstream ss; - ss << std::quoted(p, wchar_t('"'), escape ); - std::wstring s; - ss >> std::quoted(s, wchar_t('"'), escape ); - assert ( s == p ); - } - - -std::wstring quote ( const wchar_t *p, wchar_t delim='"', wchar_t escape='\\' ) { - std::wstringstream ss; - ss << std::quoted(p, delim, escape); - std::wstring s; - ss >> s; // no quote - return s; -} - -std::wstring unquote ( const wchar_t *p, wchar_t delim='"', wchar_t escape='\\' ) { - std::wstringstream ss; - ss << p; - std::wstring s; - ss >> std::quoted(s, delim, escape); - return s; -} - int main() { both_ways ( "" ); // This is a compilation check @@ -170,31 +131,31 @@ int main() round_trip_ws ( "" ); round_trip_d ( "", 'q' ); round_trip_e ( "", 'q' ); - + round_trip ( L"" ); round_trip_ws ( L"" ); round_trip_d ( L"", 'q' ); round_trip_e ( L"", 'q' ); - + round_trip ( "Hi" ); round_trip_ws ( "Hi" ); round_trip_d ( "Hi", '!' ); round_trip_e ( "Hi", '!' ); assert ( quote ( "Hi", '!' ) == "!Hi!" ); assert ( quote ( "Hi!", '!' ) == R"(!Hi\!!)" ); - + round_trip ( L"Hi" ); round_trip_ws ( L"Hi" ); round_trip_d ( L"Hi", '!' ); round_trip_e ( L"Hi", '!' ); assert ( quote ( L"Hi", '!' ) == L"!Hi!" ); assert ( quote ( L"Hi!", '!' ) == LR"(!Hi\!!)" ); - + round_trip ( "Hi Mom" ); round_trip_ws ( "Hi Mom" ); round_trip ( L"Hi Mom" ); round_trip_ws ( L"Hi Mom" ); - + assert ( quote ( "" ) == "\"\"" ); assert ( quote ( L"" ) == L"\"\"" ); assert ( quote ( "a" ) == "\"a\"" ); @@ -203,7 +164,7 @@ int main() // missing end quote - must not hang assert ( unquote ( "\"abc" ) == "abc" ); assert ( unquote ( L"\"abc" ) == L"abc" ); - + assert ( unquote ( "abc" ) == "abc" ); // no delimiter assert ( unquote ( L"abc" ) == L"abc" ); // no delimiter assert ( unquote ( "abc def" ) == "abc" ); // no delimiter diff --git a/test/std/input.output/iostream.format/quoted.manip/quoted_char.fail.cpp b/test/std/input.output/iostream.format/quoted.manip/quoted_char.fail.cpp index 2f516f8fbc916..c9fccea2c7d0c 100644 --- a/test/std/input.output/iostream.format/quoted.manip/quoted_char.fail.cpp +++ b/test/std/input.output/iostream.format/quoted.manip/quoted_char.fail.cpp @@ -16,7 +16,11 @@ #include <string> #include <cassert> -#if _LIBCPP_STD_VER > 11 +#include "test_macros.h" + +// Test that mismatches between strings and wides streams are diagnosed + +#if TEST_STD_VER > 11 void round_trip ( const char *p ) { std::wstringstream ss; @@ -29,7 +33,7 @@ void round_trip ( const char *p ) { int main() { - round_trip ( "Hi Mom" ); + round_trip ( "Hi Mom" ); } #else #error diff --git a/test/std/input.output/iostream.format/quoted.manip/quoted_traits.fail.cpp b/test/std/input.output/iostream.format/quoted.manip/quoted_traits.fail.cpp index bdd362df19c99..109674d1660d8 100644 --- a/test/std/input.output/iostream.format/quoted.manip/quoted_traits.fail.cpp +++ b/test/std/input.output/iostream.format/quoted.manip/quoted_traits.fail.cpp @@ -16,7 +16,11 @@ #include <string> #include <cassert> -#if _LIBCPP_STD_VER > 11 +#include "test_macros.h" + +#if TEST_STD_VER > 11 + +// Test that mismatches in the traits between the quoted object and the dest string are diagnosed. template <class charT> struct test_traits @@ -35,7 +39,7 @@ void round_trip ( const char *p ) { int main() { - round_trip ( "Hi Mom" ); + round_trip ( "Hi Mom" ); } #else #error diff --git a/test/std/input.output/iostreams.base/ios/basic.ios.members/move.pass.cpp b/test/std/input.output/iostreams.base/ios/basic.ios.members/move.pass.cpp index 509b836686c53..0b068e0d4a9f4 100644 --- a/test/std/input.output/iostreams.base/ios/basic.ios.members/move.pass.cpp +++ b/test/std/input.output/iostreams.base/ios/basic.ios.members/move.pass.cpp @@ -41,17 +41,17 @@ bool g1_called = false; bool g2_called = false; bool g3_called = false; -void f1(std::ios_base::event ev, std::ios_base& stream, int index) +void f1(std::ios_base::event, std::ios_base&, int) { f1_called = true; } -void f2(std::ios_base::event ev, std::ios_base& stream, int index) +void f2(std::ios_base::event, std::ios_base&, int) { f2_called = true; } -void g1(std::ios_base::event ev, std::ios_base& stream, int index) +void g1(std::ios_base::event ev, std::ios_base&, int index) { if (ev == std::ios_base::imbue_event) { @@ -60,7 +60,7 @@ void g1(std::ios_base::event ev, std::ios_base& stream, int index) } } -void g2(std::ios_base::event ev, std::ios_base& stream, int index) +void g2(std::ios_base::event ev, std::ios_base&, int index) { if (ev == std::ios_base::imbue_event) { @@ -69,7 +69,7 @@ void g2(std::ios_base::event ev, std::ios_base& stream, int index) } } -void g3(std::ios_base::event ev, std::ios_base& stream, int index) +void g3(std::ios_base::event ev, std::ios_base&, int index) { if (ev == std::ios_base::imbue_event) { diff --git a/test/std/input.output/iostreams.base/ios/basic.ios.members/narow.pass.cpp b/test/std/input.output/iostreams.base/ios/basic.ios.members/narrow.pass.cpp index bf865e68149d4..bf865e68149d4 100644 --- a/test/std/input.output/iostreams.base/ios/basic.ios.members/narow.pass.cpp +++ b/test/std/input.output/iostreams.base/ios/basic.ios.members/narrow.pass.cpp diff --git a/test/std/input.output/iostreams.base/ios/basic.ios.members/swap.pass.cpp b/test/std/input.output/iostreams.base/ios/basic.ios.members/swap.pass.cpp index e44f4b32512c2..2887ca100c99c 100644 --- a/test/std/input.output/iostreams.base/ios/basic.ios.members/swap.pass.cpp +++ b/test/std/input.output/iostreams.base/ios/basic.ios.members/swap.pass.cpp @@ -41,31 +41,31 @@ bool g1_called = false; bool g2_called = false; bool g3_called = false; -void f1(std::ios_base::event ev, std::ios_base& stream, int index) +void f1(std::ios_base::event, std::ios_base&, int index) { assert(index == 4); f1_called = true; } -void f2(std::ios_base::event ev, std::ios_base& stream, int index) +void f2(std::ios_base::event, std::ios_base&, int index) { assert(index == 5); f2_called = true; } -void g1(std::ios_base::event ev, std::ios_base& stream, int index) +void g1(std::ios_base::event, std::ios_base&, int index) { assert(index == 7); g1_called = true; } -void g2(std::ios_base::event ev, std::ios_base& stream, int index) +void g2(std::ios_base::event, std::ios_base&, int index) { assert(index == 8); g2_called = true; } -void g3(std::ios_base::event ev, std::ios_base& stream, int index) +void g3(std::ios_base::event, std::ios_base&, int index) { assert(index == 9); g3_called = true; diff --git a/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.get/sgetn.pass.cpp b/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.get/sgetn.pass.cpp index 730cedeea76c0..1935308dea0fa 100644 --- a/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.get/sgetn.pass.cpp +++ b/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.get/sgetn.pass.cpp @@ -25,7 +25,7 @@ struct test test() {} protected: - std::streamsize xsgetn(char_type* s, std::streamsize n) + std::streamsize xsgetn(char_type*, std::streamsize) { ++xsgetn_called; return 10; diff --git a/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.pback/sputbackc.pass.cpp b/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.pback/sputbackc.pass.cpp index 34a2a2dda3727..2f4aad0510796 100644 --- a/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.pback/sputbackc.pass.cpp +++ b/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.pback/sputbackc.pass.cpp @@ -32,7 +32,7 @@ struct test } protected: - int_type pbackfail(int_type c = traits_type::eof()) + int_type pbackfail(int_type = traits_type::eof()) { ++pbackfail_called; return 'a'; diff --git a/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.pback/sungetc.pass.cpp b/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.pback/sungetc.pass.cpp index 4c68fada07a8c..36a19da85fe05 100644 --- a/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.pback/sungetc.pass.cpp +++ b/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.pback/sungetc.pass.cpp @@ -32,7 +32,7 @@ struct test } protected: - int_type pbackfail(int_type c = traits_type::eof()) + int_type pbackfail(int_type = traits_type::eof()) { ++pbackfail_called; return 'a'; diff --git a/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.put/sputc.pass.cpp b/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.put/sputc.pass.cpp index b04b8b0acc91a..5ea48c18d793c 100644 --- a/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.put/sputc.pass.cpp +++ b/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.put/sputc.pass.cpp @@ -36,7 +36,7 @@ struct test } protected: - int_type overflow(int_type c = traits_type::eof()) + int_type overflow(int_type = traits_type::eof()) { ++overflow_called; return 'a'; diff --git a/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.put/sputn.pass.cpp b/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.put/sputn.pass.cpp index e03e8e0cbda3c..4ced690a2652e 100644 --- a/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.put/sputn.pass.cpp +++ b/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.pub.put/sputn.pass.cpp @@ -25,7 +25,7 @@ struct test test() {} protected: - std::streamsize xsputn(const char_type* s, std::streamsize n) + std::streamsize xsputn(const char_type*, std::streamsize) { ++xsputn_called; return 5; diff --git a/test/std/iterators/iterator.container/data.pass.cpp b/test/std/iterators/iterator.container/data.pass.cpp index 3d1fa33358dbb..a7a17480235a1 100644 --- a/test/std/iterators/iterator.container/data.pass.cpp +++ b/test/std/iterators/iterator.container/data.pass.cpp @@ -13,7 +13,9 @@ // template <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept; // C++17 // template <class E> constexpr const E* data(initializer_list<E> il) noexcept; // C++17 -#if __cplusplus <= 201402L +#include "test_macros.h" + +#if TEST_STD_VER <= 14 int main () {} #else @@ -40,7 +42,7 @@ void test_container( C& c ) { assert ( std::data(c) == c.data()); } - + template<typename T> void test_container( std::initializer_list<T>& c) { @@ -58,7 +60,7 @@ int main() std::vector<int> v; v.push_back(1); std::array<int, 1> a; a[0] = 3; std::initializer_list<int> il = { 4 }; - + test_container ( v ); test_container ( a ); test_container ( il ); @@ -66,7 +68,7 @@ int main() test_const_container ( v ); test_const_container ( a ); test_const_container ( il ); - + static constexpr int arrA [] { 1, 2, 3 }; test_const_array ( arrA ); } diff --git a/test/std/iterators/iterator.container/empty.pass.cpp b/test/std/iterators/iterator.container/empty.pass.cpp index f26cb98e1aed6..f9b8b94a89f96 100644 --- a/test/std/iterators/iterator.container/empty.pass.cpp +++ b/test/std/iterators/iterator.container/empty.pass.cpp @@ -12,7 +12,9 @@ // template <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept; // C++17 // template <class E> constexpr bool empty(initializer_list<E> il) noexcept; // C++17 -#if __cplusplus <= 201402L +#include "test_macros.h" + +#if TEST_STD_VER <= 14 int main () {} #else @@ -40,7 +42,7 @@ void test_container( C& c ) { assert ( std::empty(c) == c.empty()); } - + template<typename T> void test_container( std::initializer_list<T>& c ) { @@ -59,7 +61,7 @@ int main() std::list<int> l; l.push_back(2); std::array<int, 1> a; a[0] = 3; std::initializer_list<int> il = { 4 }; - + test_container ( v ); test_container ( l ); test_container ( a ); @@ -69,7 +71,7 @@ int main() test_const_container ( l ); test_const_container ( a ); test_const_container ( il ); - + static constexpr int arrA [] { 1, 2, 3 }; test_const_array ( arrA ); } diff --git a/test/std/iterators/iterator.container/size.pass.cpp b/test/std/iterators/iterator.container/size.pass.cpp index 705fb40e1926f..87b0ef8970722 100644 --- a/test/std/iterators/iterator.container/size.pass.cpp +++ b/test/std/iterators/iterator.container/size.pass.cpp @@ -11,7 +11,9 @@ // template <class C> constexpr auto size(const C& c) -> decltype(c.size()); // C++17 // template <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17 -#if __cplusplus <= 201402L +#include "test_macros.h" + +#if TEST_STD_VER <= 14 int main () {} #else @@ -39,7 +41,7 @@ void test_container( C& c) { assert ( std::size(c) == c.size()); } - + template<typename T> void test_container( std::initializer_list<T>& c ) { @@ -58,7 +60,7 @@ int main() std::list<int> l; l.push_back(2); std::array<int, 1> a; a[0] = 3; std::initializer_list<int> il = { 4 }; - + test_container ( v ); test_container ( l ); test_container ( a ); @@ -68,7 +70,7 @@ int main() test_const_container ( l ); test_const_container ( a ); test_const_container ( il ); - + static constexpr int arrA [] { 1, 2, 3 }; test_const_array ( arrA ); } diff --git a/test/std/iterators/iterator.primitives/std.iterator.tags/bidirectional_iterator_tag.pass.cpp b/test/std/iterators/iterator.primitives/std.iterator.tags/bidirectional_iterator_tag.pass.cpp index 0f368c3b765f5..ecda1d1469494 100644 --- a/test/std/iterators/iterator.primitives/std.iterator.tags/bidirectional_iterator_tag.pass.cpp +++ b/test/std/iterators/iterator.primitives/std.iterator.tags/bidirectional_iterator_tag.pass.cpp @@ -17,6 +17,7 @@ int main() { std::bidirectional_iterator_tag tag; + ((void)tag); // Prevent unused warning static_assert((std::is_base_of<std::forward_iterator_tag, std::bidirectional_iterator_tag>::value), ""); static_assert((!std::is_base_of<std::output_iterator_tag, diff --git a/test/std/iterators/iterator.primitives/std.iterator.tags/forward_iterator_tag.pass.cpp b/test/std/iterators/iterator.primitives/std.iterator.tags/forward_iterator_tag.pass.cpp index 0936595c85d6b..e11b8e9ba7ac4 100644 --- a/test/std/iterators/iterator.primitives/std.iterator.tags/forward_iterator_tag.pass.cpp +++ b/test/std/iterators/iterator.primitives/std.iterator.tags/forward_iterator_tag.pass.cpp @@ -17,6 +17,7 @@ int main() { std::forward_iterator_tag tag; + ((void)tag); // Prevent unused warning static_assert((std::is_base_of<std::input_iterator_tag, std::forward_iterator_tag>::value), ""); static_assert((!std::is_base_of<std::output_iterator_tag, diff --git a/test/std/iterators/iterator.primitives/std.iterator.tags/input_iterator_tag.pass.cpp b/test/std/iterators/iterator.primitives/std.iterator.tags/input_iterator_tag.pass.cpp index afeac3e91caeb..19b517c328e72 100644 --- a/test/std/iterators/iterator.primitives/std.iterator.tags/input_iterator_tag.pass.cpp +++ b/test/std/iterators/iterator.primitives/std.iterator.tags/input_iterator_tag.pass.cpp @@ -17,6 +17,7 @@ int main() { std::input_iterator_tag tag; + ((void)tag); // Prevent unused warning static_assert((!std::is_base_of<std::output_iterator_tag, std::input_iterator_tag>::value), ""); } diff --git a/test/std/iterators/iterator.primitives/std.iterator.tags/output_iterator_tag.pass.cpp b/test/std/iterators/iterator.primitives/std.iterator.tags/output_iterator_tag.pass.cpp index 7f7f66a98f4ad..e315b2724f829 100644 --- a/test/std/iterators/iterator.primitives/std.iterator.tags/output_iterator_tag.pass.cpp +++ b/test/std/iterators/iterator.primitives/std.iterator.tags/output_iterator_tag.pass.cpp @@ -17,6 +17,7 @@ int main() { std::output_iterator_tag tag; + ((void)tag); // Prevent unused warning static_assert((!std::is_base_of<std::input_iterator_tag, std::output_iterator_tag>::value), ""); } diff --git a/test/std/iterators/iterator.primitives/std.iterator.tags/random_access_iterator_tag.pass.cpp b/test/std/iterators/iterator.primitives/std.iterator.tags/random_access_iterator_tag.pass.cpp index 04f830bc31090..f16a3b74c53f8 100644 --- a/test/std/iterators/iterator.primitives/std.iterator.tags/random_access_iterator_tag.pass.cpp +++ b/test/std/iterators/iterator.primitives/std.iterator.tags/random_access_iterator_tag.pass.cpp @@ -17,6 +17,7 @@ int main() { std::random_access_iterator_tag tag; + ((void)tag); // Prevent unused warning static_assert((std::is_base_of<std::bidirectional_iterator_tag, std::random_access_iterator_tag>::value), ""); static_assert((!std::is_base_of<std::output_iterator_tag, diff --git a/test/std/iterators/iterator.range/begin-end.pass.cpp b/test/std/iterators/iterator.range/begin-end.pass.cpp index bd7e0aa90fbc1..ec3f61789b27b 100644 --- a/test/std/iterators/iterator.range/begin-end.pass.cpp +++ b/test/std/iterators/iterator.range/begin-end.pass.cpp @@ -15,7 +15,9 @@ // template <class E> reverse_iterator<const E*> rbegin(initializer_list<E> il); // template <class E> reverse_iterator<const E*> rend(initializer_list<E> il); -#if __cplusplus >= 201103L +#include "test_macros.h" + +#if TEST_STD_VER >= 11 #include <iterator> #include <cassert> #include <vector> @@ -81,7 +83,7 @@ void test_container( C & c, typename C::value_type val ) { assert ( std::crend(c) == c.crend()); #endif } - + template<typename T> void test_container( std::initializer_list<T> & c, T val ) { assert ( std::begin(c) == c.begin()); @@ -121,7 +123,7 @@ int main(){ std::list<int> l; l.push_back(2); std::array<int, 1> a; a[0] = 3; std::initializer_list<int> il = { 4 }; - + test_container ( v, 1 ); test_container ( l, 2 ); test_container ( a, 3 ); @@ -131,7 +133,7 @@ int main(){ test_const_container ( l, 2 ); test_const_container ( a, 3 ); test_const_container ( il, 4 ); - + static constexpr int arrA [] { 1, 2, 3 }; test_const_array ( arrA ); #if _LIBCPP_STD_VER > 11 diff --git a/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/types.pass.cpp b/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/types.pass.cpp index 2611c9a4b0cc5..7aa7f3443aa4a 100644 --- a/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/types.pass.cpp +++ b/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/types.pass.cpp @@ -21,7 +21,7 @@ // typedef Cont container_type; // typedef void value_type; // typedef void difference_type; -// typedef back_insert_iterator<Cont>& reference; +// typedef void reference; // typedef void pointer; // }; @@ -48,7 +48,7 @@ test() static_assert((std::is_same<typename R::container_type, C>::value), ""); static_assert((std::is_same<typename R::value_type, void>::value), ""); static_assert((std::is_same<typename R::difference_type, void>::value), ""); - static_assert((std::is_same<typename R::reference, R&>::value), ""); + static_assert((std::is_same<typename R::reference, void>::value), ""); static_assert((std::is_same<typename R::pointer, void>::value), ""); static_assert((std::is_same<typename R::iterator_category, std::output_iterator_tag>::value), ""); } diff --git a/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/types.pass.cpp b/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/types.pass.cpp index 755133a919481..7a7c678edaaf9 100644 --- a/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/types.pass.cpp +++ b/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/types.pass.cpp @@ -21,7 +21,7 @@ // typedef Container container_type; // typedef void value_type; // typedef void difference_type; -// typedef front_insert_iterator<Cont>& reference; +// typedef void reference; // typedef void pointer; // typedef output_iterator_tag iterator_category; // }; @@ -49,7 +49,7 @@ test() static_assert((std::is_same<typename R::container_type, C>::value), ""); static_assert((std::is_same<typename R::value_type, void>::value), ""); static_assert((std::is_same<typename R::difference_type, void>::value), ""); - static_assert((std::is_same<typename R::reference, R&>::value), ""); + static_assert((std::is_same<typename R::reference, void>::value), ""); static_assert((std::is_same<typename R::pointer, void>::value), ""); static_assert((std::is_same<typename R::iterator_category, std::output_iterator_tag>::value), ""); } diff --git a/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/types.pass.cpp b/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/types.pass.cpp index cf63df63e89bc..5b61a38951321 100644 --- a/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/types.pass.cpp +++ b/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/types.pass.cpp @@ -22,7 +22,7 @@ // typedef Cont container_type; // typedef void value_type; // typedef void difference_type; -// typedef insert_iterator<Cont>& reference; +// typedef void reference; // typedef void pointer; // }; @@ -53,7 +53,7 @@ test() static_assert((std::is_same<typename R::container_type, C>::value), ""); static_assert((std::is_same<typename R::value_type, void>::value), ""); static_assert((std::is_same<typename R::difference_type, void>::value), ""); - static_assert((std::is_same<typename R::reference, R&>::value), ""); + static_assert((std::is_same<typename R::reference, void>::value), ""); static_assert((std::is_same<typename R::pointer, void>::value), ""); static_assert((std::is_same<typename R::iterator_category, std::output_iterator_tag>::value), ""); } diff --git a/test/std/iterators/predef.iterators/move.iterators/move.iterator/types.pass.cpp b/test/std/iterators/predef.iterators/move.iterators/move.iterator/types.pass.cpp index 9bdf7215e9ee9..a6d4d61e13ce1 100644 --- a/test/std/iterators/predef.iterators/move.iterators/move.iterator/types.pass.cpp +++ b/test/std/iterators/predef.iterators/move.iterators/move.iterator/types.pass.cpp @@ -18,7 +18,7 @@ // public: // typedef Iter iterator_type; // typedef Iter::difference_type difference_type; -// typedef Iterator pointer; +// typedef Iter pointer; // typedef Iter::value_type value_type; // typedef value_type&& reference; // }; @@ -26,8 +26,18 @@ #include <iterator> #include <type_traits> +#include "test_macros.h" #include "test_iterators.h" +template <class ValueType, class Reference> +struct DummyIt { + typedef std::forward_iterator_tag iterator_category; + typedef ValueType value_type; + typedef std::ptrdiff_t difference_type; + typedef ValueType* pointer; + typedef Reference reference; +}; + template <class It> void test() @@ -36,9 +46,9 @@ test() typedef std::iterator_traits<It> T; static_assert((std::is_same<typename R::iterator_type, It>::value), ""); static_assert((std::is_same<typename R::difference_type, typename T::difference_type>::value), ""); - static_assert((std::is_same<typename R::pointer, typename T::pointer>::value), ""); + static_assert((std::is_same<typename R::pointer, It>::value), ""); static_assert((std::is_same<typename R::value_type, typename T::value_type>::value), ""); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if TEST_STD_VER >= 11 static_assert((std::is_same<typename R::reference, typename R::value_type&&>::value), ""); #else static_assert((std::is_same<typename R::reference, typename T::reference>::value), ""); @@ -53,4 +63,33 @@ int main() test<bidirectional_iterator<char*> >(); test<random_access_iterator<char*> >(); test<char*>(); +#if TEST_STD_VER >= 11 + { + typedef DummyIt<int, int> T; + typedef std::move_iterator<T> It; + static_assert(std::is_same<It::reference, int>::value, ""); + } + { + typedef DummyIt<int, std::reference_wrapper<int> > T; + typedef std::move_iterator<T> It; + static_assert(std::is_same<It::reference, std::reference_wrapper<int> >::value, ""); + } + { + // Check that move_iterator uses whatever reference type it's given + // when it's not a reference. + typedef DummyIt<int, long > T; + typedef std::move_iterator<T> It; + static_assert(std::is_same<It::reference, long>::value, ""); + } + { + typedef DummyIt<int, int&> T; + typedef std::move_iterator<T> It; + static_assert(std::is_same<It::reference, int&&>::value, ""); + } + { + typedef DummyIt<int, int&&> T; + typedef std::move_iterator<T> It; + static_assert(std::is_same<It::reference, int&&>::value, ""); + } +#endif } diff --git a/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.make/make_reverse_iterator.pass.cpp b/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.make/make_reverse_iterator.pass.cpp index 98b7331cd3869..7ec287e5cd370 100644 --- a/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.make/make_reverse_iterator.pass.cpp +++ b/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.make/make_reverse_iterator.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <iterator> // reverse_iterator @@ -19,8 +20,6 @@ #include "test_iterators.h" -#if _LIBCPP_STD_VER > 11 - template <class It> void test(It i) @@ -37,6 +36,4 @@ int main() while ( b != e ) test ( b++ ); } -#else -int main () {} -#endif + diff --git a/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.opref/op_arrow.pass.cpp b/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.opref/op_arrow.pass.cpp index efbdf1406c96f..404e8fbf19bfb 100644 --- a/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.opref/op_arrow.pass.cpp +++ b/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.opref/op_arrow.pass.cpp @@ -63,13 +63,13 @@ int main() { A a; test(&a+1, A()); - + { std::list<B> l; l.push_back(B(0)); l.push_back(B(1)); l.push_back(B(2)); - + { std::list<B>::const_iterator i = l.begin(); assert ( i->get() == 0 ); ++i; @@ -77,7 +77,7 @@ int main() assert ( i->get() == 2 ); ++i; assert ( i == l.end ()); } - + { std::list<B>::const_reverse_iterator ri = l.rbegin(); assert ( ri->get() == 2 ); ++ri; diff --git a/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.fail.cpp b/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.fail.cpp index 5e6cc5455998c..452049677c75a 100644 --- a/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.fail.cpp +++ b/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.fail.cpp @@ -16,11 +16,13 @@ #include <iterator> #include <cassert> -struct S { S(); }; // not constexpr +#include "test_macros.h" + +struct S { S(); }; // not constexpr int main() { -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { constexpr std::istream_iterator<S> it; } 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 bea07ec2272e5..c1924e4b92721 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 @@ -16,15 +16,17 @@ #include <iterator> #include <cassert> +#include "test_macros.h" + int main() { { typedef std::istream_iterator<int> T; T it; assert(it == T()); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 constexpr T it2; #endif } - + } diff --git a/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.ops/arrow.pass.cpp b/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.ops/arrow.pass.cpp index 5c4ddcad32eaf..30057a227c998 100644 --- a/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.ops/arrow.pass.cpp +++ b/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.ops/arrow.pass.cpp @@ -23,6 +23,8 @@ struct A int i_; }; +void operator&(A const&) {} + std::istream& operator>>(std::istream& is, A& a) { return is >> a.d_ >> a.i_; 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 85a70a017976b..1250e364d35ed 100644 --- a/test/std/iterators/stream.iterators/istream.iterator/types.pass.cpp +++ b/test/std/iterators/stream.iterators/istream.iterator/types.pass.cpp @@ -9,6 +9,9 @@ // <iterator> +// Test fails due to use of is_trivially_* trait. +// XFAIL: gcc-4.9 + // template <class T, class charT = char, class traits = char_traits<charT>, // class Distance = ptrdiff_t> // class istream_iterator 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 46ac390d931f1..74aa6f2ab5170 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 @@ -13,20 +13,22 @@ // // istreambuf_iterator() throw(); // -// All specializations of istreambuf_iterator shall have a trivial copy constructor, +// All specializations of istreambuf_iterator shall have a trivial copy constructor, // a constexpr default constructor and a trivial destructor. #include <iterator> #include <sstream> #include <cassert> +#include "test_macros.h" + int main() { { typedef std::istreambuf_iterator<char> T; T it; assert(it == T()); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 constexpr T it2; #endif } @@ -34,7 +36,7 @@ int main() typedef std::istreambuf_iterator<wchar_t> T; T it; assert(it == T()); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 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 2ad927cf952c2..c974e2cd091db 100644 --- a/test/std/iterators/stream.iterators/istreambuf.iterator/types.pass.cpp +++ b/test/std/iterators/stream.iterators/istreambuf.iterator/types.pass.cpp @@ -9,6 +9,9 @@ // <iterator> +// Test fails due to use of is_trivially_* trait. +// XFAIL: gcc-4.9 + // template<class charT, class traits = char_traits<charT> > // class istreambuf_iterator // : public iterator<input_iterator_tag, charT, @@ -23,19 +26,23 @@ // typedef basic_istream<charT,traits> istream_type; // ... // -// All specializations of istreambuf_iterator shall have a trivial copy constructor, +// All specializations of istreambuf_iterator shall have a trivial copy constructor, // a constexpr default constructor and a trivial destructor. #include <iterator> #include <string> #include <type_traits> +#include "test_macros.h" + int main() { typedef std::istreambuf_iterator<char> I1; - static_assert((std::is_convertible<I1, - std::iterator<std::input_iterator_tag, char, std::char_traits<char>::off_type, - char*, char> >::value), ""); + static_assert((std::is_same<I1::iterator_category, std::input_iterator_tag>::value), ""); + static_assert((std::is_same<I1::value_type, char>::value), ""); + static_assert((std::is_same<I1::difference_type, std::char_traits<char>::off_type>::value), ""); + LIBCPP_STATIC_ASSERT((std::is_same<I1::pointer, char*>::value), ""); + static_assert((std::is_same<I1::reference, char>::value), ""); 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::int_type, I1::traits_type::int_type>::value), ""); @@ -46,9 +53,11 @@ int main() static_assert((std::is_trivially_destructible<I1>::value), "" ); typedef std::istreambuf_iterator<wchar_t> I2; - static_assert((std::is_convertible<I2, - std::iterator<std::input_iterator_tag, wchar_t, std::char_traits<wchar_t>::off_type, - wchar_t*, wchar_t> >::value), ""); + static_assert((std::is_same<I2::iterator_category, std::input_iterator_tag>::value), ""); + static_assert((std::is_same<I2::value_type, wchar_t>::value), ""); + static_assert((std::is_same<I2::difference_type, std::char_traits<wchar_t>::off_type>::value), ""); + LIBCPP_STATIC_ASSERT((std::is_same<I2::pointer, wchar_t*>::value), ""); + static_assert((std::is_same<I2::reference, wchar_t>::value), ""); 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::int_type, I2::traits_type::int_type>::value), ""); diff --git a/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.cons.des/ostream.pass.cpp b/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.cons.des/ostream.pass.cpp index 321cfbdb82c8d..6366355cc108c 100644 --- a/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.cons.des/ostream.pass.cpp +++ b/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.cons.des/ostream.pass.cpp @@ -17,9 +17,23 @@ #include <sstream> #include <cassert> +struct MyTraits : std::char_traits<char> {}; + +typedef std::basic_ostringstream<char, MyTraits> StringStream; +typedef std::basic_ostream<char, MyTraits> BasicStream; + +void operator&(BasicStream const&) {} + int main() { - std::ostringstream outf; - std::ostream_iterator<int> i(outf); - assert(outf.good()); + { + std::ostringstream outf; + std::ostream_iterator<int> i(outf); + assert(outf.good()); + } + { + StringStream outf; + std::ostream_iterator<int, char, MyTraits> i(outf); + assert(outf.good()); + } } diff --git a/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.cons.des/ostream_delem.pass.cpp b/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.cons.des/ostream_delim.pass.cpp index 8e5c771a4ab40..69c2dfc9b5f24 100644 --- a/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.cons.des/ostream_delem.pass.cpp +++ b/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.cons.des/ostream_delim.pass.cpp @@ -17,6 +17,14 @@ #include <sstream> #include <cassert> + +struct MyTraits : std::char_traits<char> {}; + +typedef std::basic_ostringstream<char, MyTraits> StringStream; +typedef std::basic_ostream<char, MyTraits> BasicStream; + +void operator&(BasicStream const&) {} + int main() { { @@ -29,4 +37,9 @@ int main() std::ostream_iterator<double, wchar_t> i(outf, L", "); assert(outf.good()); } + { + StringStream outf; + std::ostream_iterator<int, char, MyTraits> i(outf, ", "); + assert(outf.good()); + } } diff --git a/test/std/language.support/cstdint/cstdint.syn/cstdint.pass.cpp b/test/std/language.support/cstdint/cstdint.syn/cstdint.pass.cpp index 23cf8b66bcb1f..20ae6e6207532 100644 --- a/test/std/language.support/cstdint/cstdint.syn/cstdint.pass.cpp +++ b/test/std/language.support/cstdint/cstdint.syn/cstdint.pass.cpp @@ -172,8 +172,8 @@ int main() // INTN_MIN static_assert(INT8_MIN == -128, "INT8_MIN == -128"); static_assert(INT16_MIN == -32768, "INT16_MIN == -32768"); - static_assert(INT32_MIN == -2147483648U, "INT32_MIN == -2147483648"); - static_assert(INT64_MIN == -9223372036854775808ULL, "INT64_MIN == -9223372036854775808LL"); + static_assert(INT32_MIN == -2147483647 - 1, "INT32_MIN == -2147483648"); + static_assert(INT64_MIN == -9223372036854775807LL - 1, "INT64_MIN == -9223372036854775808LL"); // INTN_MAX static_assert(INT8_MAX == 127, "INT8_MAX == 127"); @@ -190,8 +190,8 @@ int main() // INT_FASTN_MIN static_assert(INT_FAST8_MIN <= -128, "INT_FAST8_MIN <= -128"); static_assert(INT_FAST16_MIN <= -32768, "INT_FAST16_MIN <= -32768"); - static_assert(INT_FAST32_MIN <= -2147483648U, "INT_FAST32_MIN <= -2147483648"); - static_assert(INT_FAST64_MIN <= -9223372036854775808ULL, "INT_FAST64_MIN <= -9223372036854775808LL"); + static_assert(INT_FAST32_MIN <= -2147483647 - 1, "INT_FAST32_MIN <= -2147483648"); + static_assert(INT_FAST64_MIN <= -9223372036854775807LL - 1, "INT_FAST64_MIN <= -9223372036854775808LL"); // INT_FASTN_MAX static_assert(INT_FAST8_MAX >= 127, "INT_FAST8_MAX >= 127"); 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 105c7a93f210b..5887bb0bdf30a 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 @@ -11,6 +11,10 @@ // UNSUPPORTED: sanitizer-new-delete +// TODO Investigate why UBSAN prevents new from calling our replacement. +// XFAIL: ubsan + + #include <new> #include <cstddef> #include <cstdlib> @@ -22,7 +26,9 @@ int new_called = 0; void* operator new(std::size_t s) throw(std::bad_alloc) { ++new_called; - return std::malloc(s); + void* ret = std::malloc(s); + if (!ret) std::abort(); // placate MSVC's unchecked malloc warning + return ret; } void operator delete(void* p) throw() 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 92bd7b952dcbc..1e78ea8fe2673 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 @@ -11,6 +11,10 @@ // UNSUPPORTED: sanitizer-new-delete +// TODO Investigate why UBSAN prevents new from calling our replacement. +// XFAIL: ubsan + + #include <new> #include <cstddef> #include <cstdlib> @@ -22,7 +26,9 @@ volatile int new_called = 0; void* operator new(std::size_t s) throw(std::bad_alloc) { ++new_called; - return std::malloc(s); + void* ret = std::malloc(s); + if (!ret) std::abort(); // placate MSVC's unchecked malloc warning + return ret; } void operator delete(void* p) throw() diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_array.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_array.pass.cpp index 1ab52ae4c8dfb..462d1973c5071 100644 --- a/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_array.pass.cpp +++ b/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_array.pass.cpp @@ -22,9 +22,13 @@ struct A int main() { - char buf[3*sizeof(A)]; + const std::size_t Size = 3; + // placement new might require additional space. + const std::size_t ExtraSize = 64; + char buf[Size*sizeof(A) + ExtraSize]; - A* ap = new(buf) A[3]; - assert((char*)ap == buf); - assert(A_constructed == 3); + A* ap = new(buf) A[Size]; + assert((char*)ap >= buf); + assert((char*)ap < (buf + ExtraSize)); + assert(A_constructed == Size); } 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 57ce287522081..892842a1b9f40 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 @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// // XFAIL: libcpp-no-exceptions + // test operator new // asan and msan will not call the new handler. 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 cd70f90948d2d..eb8319bac2f72 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 @@ -11,6 +11,9 @@ // UNSUPPORTED: sanitizer-new-delete +// TODO Investigate why UBSAN prevents nothrow new from calling our replacement. +// XFAIL: ubsan + #include <new> #include <cstddef> #include <cstdlib> @@ -22,7 +25,9 @@ int new_called = 0; void* operator new(std::size_t s) throw(std::bad_alloc) { ++new_called; - return std::malloc(s); + void* ret = std::malloc(s); + if (!ret) std::abort(); // placate MSVC's unchecked malloc warning + return ret; } void operator delete(void* p) throw() 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 0df3a93703d21..6056ed7bb0b39 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 @@ -22,7 +22,9 @@ int new_called = 0; void* operator new(std::size_t s) throw(std::bad_alloc) { ++new_called; - return std::malloc(s); + void* ret = std::malloc(s); + if (!ret) std::abort(); // placate MSVC's unchecked malloc warning + return ret; } void operator delete(void* p) throw() 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 index 5c4eba53d3e4d..f656d1cd712a4 100644 --- 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 @@ -13,6 +13,10 @@ // UNSUPPORTED: sanitizer-new-delete +// TODO Investigate why UBSAN prevents new from calling our replacement. +// XFAIL: ubsan + + #include <new> #include <cstddef> #include <cstdlib> 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 index da43d49691742..24d33e210f573 100644 --- 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 @@ -14,6 +14,9 @@ // UNSUPPORTED: sanitizer-new-delete +// TODO Investigate why UBSAN prevents new from calling our replacement. +// XFAIL: ubsan + // NOTE: Only clang-3.7 and GCC 5.1 and greater support -fsized-deallocation. // REQUIRES: fsized-deallocation diff --git a/test/std/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp b/test/std/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp index a8b6e15feab88..4ee95fdf30016 100644 --- a/test/std/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp +++ b/test/std/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp @@ -76,9 +76,9 @@ int main() std::rethrow_if_nested(a); assert(false); } - catch (const B& b) + catch (const B& b2) { - assert(b == B(5)); + assert(b2 == B(5)); } } } 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 98006bb1e3a0f..c14cb69bdea3d 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 @@ -18,6 +18,8 @@ #include <cstdlib> #include <cassert> +#include "test_macros.h" + class A { int data_; @@ -37,7 +39,7 @@ public: friend bool operator==(const B& x, const B& y) {return x.data_ == y.data_;} }; -#if __cplusplus > 201103L +#if TEST_STD_VER > 11 struct Final final {}; #endif @@ -105,14 +107,14 @@ int main() assert(i == 7); } } -#if __cplusplus > 201103L +#if TEST_STD_VER > 11 { try { std::throw_with_nested(Final()); assert(false); } - catch (const Final &f) + catch (const Final &) { } } diff --git a/test/std/language.support/support.exception/propagation/current_exception.pass.cpp b/test/std/language.support/support.exception/propagation/current_exception.pass.cpp index 09adf580bddf8..7bf1df457dbed 100644 --- a/test/std/language.support/support.exception/propagation/current_exception.pass.cpp +++ b/test/std/language.support/support.exception/propagation/current_exception.pass.cpp @@ -74,7 +74,7 @@ int main() throw A(); assert(false); } - catch (A& a) + catch (A&) { std::exception_ptr p = std::current_exception(); assert(A::constructed == 1); @@ -94,7 +94,7 @@ int main() throw A(); assert(false); } - catch (A a) + catch (A) { std::exception_ptr p = std::current_exception(); assert(A::constructed == 2); diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/const_data_members.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/const_data_members.pass.cpp index bbead15da64f3..50cfc46742514 100644 --- a/test/std/language.support/support.limits/limits/numeric.limits.members/const_data_members.pass.cpp +++ b/test/std/language.support/support.limits/limits/numeric.limits.members/const_data_members.pass.cpp @@ -178,13 +178,13 @@ int main() TEST_NUMERIC_LIMITS(const float) TEST_NUMERIC_LIMITS(volatile float) TEST_NUMERIC_LIMITS(const volatile float) - + // double TEST_NUMERIC_LIMITS(double) TEST_NUMERIC_LIMITS(const double) TEST_NUMERIC_LIMITS(volatile double) TEST_NUMERIC_LIMITS(const volatile double) - + // long double TEST_NUMERIC_LIMITS(long double) TEST_NUMERIC_LIMITS(const long double) diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/denorm_min.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/denorm_min.pass.cpp index a452d4e9949d4..8deb28d3fd9c8 100644 --- a/test/std/language.support/support.limits/limits/numeric.limits.members/denorm_min.pass.cpp +++ b/test/std/language.support/support.limits/limits/numeric.limits.members/denorm_min.pass.cpp @@ -12,6 +12,7 @@ // denorm_min() #include <limits> +#include <cfloat> #include <cassert> template <class T> @@ -47,7 +48,17 @@ int main() test<__int128_t>(0); test<__uint128_t>(0); #endif +#if defined(__FLT_DENORM_MIN__) // guarded because these macros are extensions. test<float>(__FLT_DENORM_MIN__); test<double>(__DBL_DENORM_MIN__); test<long double>(__LDBL_DENORM_MIN__); +#endif +#if defined(FLT_TRUE_MIN) // not currently provided on linux. + test<float>(FLT_TRUE_MIN); + test<double>(DBL_TRUE_MIN); + test<long double>(LDBL_TRUE_MIN); +#endif +#if !defined(__FLT_DENORM_MIN__) && !defined(FLT_TRUE_MIN) +#error Test has no expected values for floating point types +#endif } diff --git a/test/std/language.support/support.runtime/csetjmp.pass.cpp b/test/std/language.support/support.runtime/csetjmp.pass.cpp index dc034ce099e2e..f5060305608d3 100644 --- a/test/std/language.support/support.runtime/csetjmp.pass.cpp +++ b/test/std/language.support/support.runtime/csetjmp.pass.cpp @@ -19,6 +19,7 @@ int main() { std::jmp_buf jb; + ((void)jb); // Prevent unused warning static_assert((std::is_same<decltype(std::longjmp(jb, 0)), void>::value), "std::is_same<decltype(std::longjmp(jb, 0)), void>::value"); } diff --git a/test/std/language.support/support.runtime/cstdarg.pass.cpp b/test/std/language.support/support.runtime/cstdarg.pass.cpp index 9d6f610a943ef..e7282b1c555e8 100644 --- a/test/std/language.support/support.runtime/cstdarg.pass.cpp +++ b/test/std/language.support/support.runtime/cstdarg.pass.cpp @@ -11,11 +11,13 @@ #include <cstdarg> +#include "test_macros.h" + #ifndef va_arg #error va_arg not defined #endif -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 # ifndef va_copy # error va_copy is not defined when c++ >= 11 # endif diff --git a/test/std/language.support/support.runtime/ctime.pass.cpp b/test/std/language.support/support.runtime/ctime.pass.cpp index 03a0aa4d69666..34343b247f215 100644 --- a/test/std/language.support/support.runtime/ctime.pass.cpp +++ b/test/std/language.support/support.runtime/ctime.pass.cpp @@ -23,10 +23,13 @@ int main() { std::clock_t c = 0; - ((void)c); std::size_t s = 0; std::time_t t = 0; - std::tm tm = {0}; + std::tm tm = {}; + ((void)c); // Prevent unused warning + ((void)s); // Prevent unused warning + ((void)t); // Prevent unused warning + ((void)tm); // Prevent unused warning static_assert((std::is_same<decltype(std::clock()), std::clock_t>::value), ""); 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), ""); @@ -39,5 +42,7 @@ int main() #endif char* c1 = 0; const char* c2 = 0; + ((void)c1); // Prevent unused warning + ((void)c2); // Prevent unused warning static_assert((std::is_same<decltype(std::strftime(c1,s,c2,&tm)), std::size_t>::value), ""); } diff --git a/test/std/language.support/support.types/nullptr_t.pass.cpp b/test/std/language.support/support.types/nullptr_t.pass.cpp index 1cc2aa62032eb..ca5170f649ed9 100644 --- a/test/std/language.support/support.types/nullptr_t.pass.cpp +++ b/test/std/language.support/support.types/nullptr_t.pass.cpp @@ -57,10 +57,14 @@ void test_comparisons() #pragma clang diagnostic ignored "-Wnull-conversion" #endif void test_nullptr_conversions() { +// GCC does not accept this due to CWG Defect #1423 +// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1423 +#if defined(__clang__) { bool b = nullptr; assert(!b); } +#endif { bool b(nullptr); assert(!b); diff --git a/test/std/language.support/support.types/offsetof.pass.cpp b/test/std/language.support/support.types/offsetof.pass.cpp index e36ac22974ff7..d479f9ca44fa4 100644 --- a/test/std/language.support/support.types/offsetof.pass.cpp +++ b/test/std/language.support/support.types/offsetof.pass.cpp @@ -7,8 +7,12 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + #include <cstddef> +#include "test_macros.h" + #ifndef offsetof #error offsetof not defined #endif @@ -20,7 +24,5 @@ struct A int main() { -#if (__has_feature(cxx_noexcept)) static_assert(noexcept(offsetof(A, x)), ""); -#endif } diff --git a/test/std/localization/c.locales/clocale.pass.cpp b/test/std/localization/c.locales/clocale.pass.cpp index a90725bfa3672..534213495cd9b 100644 --- a/test/std/localization/c.locales/clocale.pass.cpp +++ b/test/std/localization/c.locales/clocale.pass.cpp @@ -47,6 +47,7 @@ int main() { std::lconv lc; + ((void)lc); // Prevent unused warning #ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS static_assert((std::is_same<decltype(std::setlocale(0, "")), char*>::value), ""); #endif diff --git a/test/std/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp b/test/std/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp index 09009ceaaae26..dfbdeaea954ba 100644 --- a/test/std/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp +++ b/test/std/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp @@ -53,23 +53,6 @@ int main() } } { - std::locale l(""); - { - const std::collate<char>& f = std::use_facet<std::collate<char> >(l); - std::string s2("aaaaaaA"); - std::string s3("BaaaaaA"); - assert(f.compare(s2.data(), s2.data() + s2.size(), - s3.data(), s3.data() + s3.size()) == 1); - } - { - const std::collate<wchar_t>& f = std::use_facet<std::collate<wchar_t> >(l); - std::wstring s2(L"aaaaaaA"); - std::wstring s3(L"BaaaaaA"); - assert(f.compare(s2.data(), s2.data() + s2.size(), - s3.data(), s3.data() + s3.size()) == 1); - } - } - { std::locale l("C"); { const std::collate<char>& f = std::use_facet<std::collate<char> >(l); diff --git a/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp b/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp index d31705e5ad1b4..b39e9ad74dc40 100644 --- a/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp +++ b/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp @@ -25,8 +25,6 @@ int main() { - // Ensure that the default locale is not C. If it is, the second tests will fail. - putenv(const_cast<char*>("LC_ALL=" LOCALE_en_US_UTF_8)); { std::locale l(LOCALE_en_US_UTF_8); { @@ -41,19 +39,6 @@ int main() } } { - std::locale l(""); - { - std::string x("1234"); - const std::collate<char>& f = std::use_facet<std::collate<char> >(l); - assert(f.transform(x.data(), x.data() + x.size()) != x); - } - { - std::wstring x(L"1234"); - const std::collate<wchar_t>& f = std::use_facet<std::collate<wchar_t> >(l); - assert(f.transform(x.data(), x.data() + x.size()) != x); - } - } - { std::locale l("C"); { std::string x("1234"); diff --git a/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.statics/classic_table.pass.cpp b/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.statics/classic_table.pass.cpp index b5690e3c6b26a..f7b0e5b715672 100644 --- a/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.statics/classic_table.pass.cpp +++ b/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.statics/classic_table.pass.cpp @@ -30,7 +30,7 @@ int main() for ( size_t i = 0; i < 128; ++i ) // values above 128 are not consistent { mask set = 0; - + if ( i < 32 || i > 126 ) set |= F::cntrl; if ( i >= 32 && i <= 126 ) set |= F::print; @@ -51,9 +51,9 @@ int main() if ( i >= 58 && i <= 64 ) set |= F::punct; // ':' .. '@' if ( i >= 91 && i <= 96 ) set |= F::punct; // '[' .. '`' if ( i >= 123 && i <= 126 ) set |= F::punct; // '{' .. '~' } - + assert(( p[i] & set) == set); // all the right bits set assert(((p[i] & ~set) & defined) == 0); // no extra ones } - + } diff --git a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/types.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/types.pass.cpp index fdfab57690430..0e9909720c0ba 100644 --- a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/types.pass.cpp +++ b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/types.pass.cpp @@ -45,19 +45,6 @@ int main() } } { - std::locale l(""); - { - assert(std::has_facet<std::ctype_byname<char> >(l)); - assert(&std::use_facet<std::ctype<char> >(l) - == &std::use_facet<std::ctype_byname<char> >(l)); - } - { - assert(std::has_facet<std::ctype_byname<wchar_t> >(l)); - assert(&std::use_facet<std::ctype<wchar_t> >(l) - == &std::use_facet<std::ctype_byname<wchar_t> >(l)); - } - } - { std::locale l("C"); { assert(std::has_facet<std::ctype_byname<char> >(l)); diff --git a/test/std/localization/locale.categories/category.monetary/locale.moneypunct/money_base.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.moneypunct/money_base.pass.cpp index beabe0cae660e..a0c17dcae7d00 100644 --- a/test/std/localization/locale.categories/category.monetary/locale.moneypunct/money_base.pass.cpp +++ b/test/std/localization/locale.categories/category.monetary/locale.moneypunct/money_base.pass.cpp @@ -21,13 +21,13 @@ int main() { - std::money_base mb; - assert(mb.none == 0); - assert(mb.space == 1); - assert(mb.symbol == 2); - assert(mb.sign == 3); - assert(mb.value == 4); - assert(sizeof(std::money_base::pattern) == 4); + std::money_base mb; ((void)mb); + static_assert(std::money_base::none == 0, ""); + static_assert(std::money_base::space == 1, ""); + static_assert(std::money_base::symbol == 2, ""); + static_assert(std::money_base::sign == 3, ""); + static_assert(std::money_base::value == 4, ""); + static_assert(sizeof(std::money_base::pattern) == 4, ""); std::money_base::pattern p; p.field[0] = std::money_base::none; } diff --git a/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_double.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_double.pass.cpp index a54b37314e870..596f8f80f04e0 100644 --- a/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_double.pass.cpp +++ b/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_double.pass.cpp @@ -13,6 +13,9 @@ // iter_type put(iter_type s, ios_base& iob, char_type fill, double v) const; +// TODO(EricWF): This test takes 40+ minutes to build with Clang 3.8 under ASAN or MSAN. +// UNSUPPORTED: asan, msan + #include <locale> #include <ios> #include <cassert> diff --git a/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp index 935961257ef2d..cf9339341abb0 100644 --- a/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp +++ b/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp @@ -13,6 +13,9 @@ // iter_type put(iter_type s, ios_base& iob, char_type fill, long double v) const; +// TODO(EricWF): This test takes 40+ minutes to build with Clang 3.8 under ASAN or MSAN. +// UNSUPPORTED: asan, msan + // TODO GLIBC uses a different string for positive and negative NAN numbers. // XFAIL: linux-gnu @@ -24412,14 +24415,14 @@ void test11() void test12() { - char str[200]; output_iterator<char*> iter; std::locale lc = std::locale::classic(); std::locale lg(lc, new my_numpunct); #ifdef __APPLE__ // This test is failing on FreeBSD, possibly due to different representations -// of the floating point numbers. +// of the floating point numbers. const my_facet f(1); + char str[200]; { long double v = 1234567890.125; std::ios ios(0); @@ -26218,7 +26221,6 @@ int main() test10(); test11(); test12(); - char str[200]; output_iterator<char*> iter; std::locale lc = std::locale::classic(); std::locale lg(lc, new my_numpunct); diff --git a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp index f5c7c1277c31a..6d7f506bb2d45 100644 --- a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp +++ b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp @@ -207,6 +207,30 @@ int main() assert(err == ios.goodbit); assert(v == 2); } + { + v = -1; + const char str[] = "1.79779e+309"; // unrepresentable + std::ios_base::iostate err = ios.goodbit; + input_iterator<const char*> iter = + f.get(input_iterator<const char*>(str), + input_iterator<const char*>(str+sizeof(str)), + ios, err, v); + assert(iter.base() == str+sizeof(str)-1); + assert(err == ios.failbit); + assert(v == HUGE_VAL); + } + { + v = -1; + const char str[] = "-1.79779e+308"; // unrepresentable + std::ios_base::iostate err = ios.goodbit; + input_iterator<const char*> iter = + f.get(input_iterator<const char*>(str), + input_iterator<const char*>(str+sizeof(str)), + ios, err, v); + assert(iter.base() == str+sizeof(str)-1); + assert(err == ios.failbit); + assert(v == -HUGE_VAL); + } ios.imbue(std::locale(std::locale(), new my_numpunct)); { v = -1; diff --git a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp index 9138894784ed6..d01f63d5920de 100644 --- a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp +++ b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp @@ -32,6 +32,7 @@ public: : F(refs) {} }; + int main() { const my_facet f(1); @@ -168,4 +169,29 @@ int main() assert(err == ios.goodbit); assert(std::isnan(v)); } + { + v = -1; + const char str[] = "3.40283e+39"; // unrepresentable + std::ios_base::iostate err = ios.goodbit; + input_iterator<const char*> iter = + f.get(input_iterator<const char*>(str), + input_iterator<const char*>(str+sizeof(str)), + ios, err, v); + assert(iter.base() == str+sizeof(str)-1); + assert(err == ios.failbit); + assert(v == HUGE_VALF); + } + { + v = -1; + const char str[] = "-3.40283e+38"; // unrepresentable + std::ios_base::iostate err = ios.goodbit; + input_iterator<const char*> iter = + f.get(input_iterator<const char*>(str), + input_iterator<const char*>(str+sizeof(str)), + ios, err, v); + assert(iter.base() == str+sizeof(str)-1); + assert(err == ios.failbit); + assert(v == -HUGE_VALF); + + } } diff --git a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp index 8e89ebc470cf3..b79650b0199b6 100644 --- a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp +++ b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp @@ -32,6 +32,7 @@ public: : F(refs) {} }; + int main() { const my_facet f(1); @@ -228,4 +229,28 @@ int main() assert(err != ios.failbit); assert(v == 304888344611713860501504000000.0L); } + { + v = -1; + const char str[] = "1.19973e+4933"; // unrepresentable + std::ios_base::iostate err = ios.goodbit; + input_iterator<const char*> iter = + f.get(input_iterator<const char*>(str), + input_iterator<const char*>(str+sizeof(str)), + ios, err, v); + assert(iter.base() == str+sizeof(str)-1); + assert(err == ios.failbit); + assert(v == HUGE_VALL); + } + { + v = -1; + const char str[] = "-1.18974e+4932"; // unrepresentable + std::ios_base::iostate err = ios.goodbit; + input_iterator<const char*> iter = + f.get(input_iterator<const char*>(str), + input_iterator<const char*>(str+sizeof(str)), + ios, err, v); + assert(iter.base() == str+sizeof(str)-1); + assert(err == ios.failbit); + assert(v == -HUGE_VALL); + } } diff --git a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp index e474eca2f5b23..6ba5a89e61e47 100644 --- a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp +++ b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp @@ -25,14 +25,14 @@ void check_limits() assert(miniss << minv); assert(maxiss << maxv); std::string mins = miniss.str(); - std::string maxs = maxiss.str(); + std::string maxs = maxiss.str(); istringstream maxoss(maxs), minoss(mins); T new_minv, new_maxv; assert(maxoss >> new_maxv); assert(minoss >> new_minv); - + assert(new_minv == minv); assert(new_maxv == maxv); @@ -40,11 +40,11 @@ void check_limits() mins = "-1"; else mins[mins.size() - 1]++; - + maxs[maxs.size() - 1]++; istringstream maxoss2(maxs), minoss2(mins); - + assert(! (maxoss2 >> new_maxv)); assert(! (minoss2 >> new_minv)); } diff --git a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname.pass.cpp index 7ad431652a894..931ab5d409640 100644 --- a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname.pass.cpp +++ b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname.pass.cpp @@ -9,15 +9,8 @@ // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 -// REQUIRES: locale.ru_RU.UTF-8 // REQUIRES: locale.zh_CN.UTF-8 -// NOTE: debian and opensuse use old locale data for ru_RU.UTF-8 abbreviated -// months. This locale data was changed in glibc 2.14. -// Debian uses glibc 2.13 as of 20/11/2014 -// OpenSuse uses glibc 2.19 with old locale data as of 20/11/2014 -// XFAIL: debian, opensuse - // <locale> // class time_get_byname<charT, InputIterator> @@ -70,16 +63,6 @@ int main() assert(err == std::ios_base::eofbit); } { - const my_facet f(LOCALE_ru_RU_UTF_8, 1); - const char in[] = "\xD0\xB8\xD1\x8E\xD0\xBD\xD1\x8F"; - err = std::ios_base::goodbit; - t = std::tm(); - I i = f.get_monthname(I(in), I(in+sizeof(in)/sizeof(in[0])-1), ios, err, &t); - assert(i.base() == in+sizeof(in)/sizeof(in[0])-1); - assert(t.tm_mon == 5); - assert(err == std::ios_base::eofbit); - } - { const my_facet f(LOCALE_zh_CN_UTF_8, 1); const char in[] = "\xE5\x85\xAD\xE6\x9C\x88"; err = std::ios_base::goodbit; diff --git a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname_wide.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname_wide.pass.cpp index 631a6de03d828..551f298b04198 100644 --- a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname_wide.pass.cpp +++ b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname_wide.pass.cpp @@ -9,15 +9,8 @@ // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.fr_FR.UTF-8 -// REQUIRES: locale.ru_RU.UTF-8 // REQUIRES: locale.zh_CN.UTF-8 -// NOTE: debian and opensuse use bad locale data for ru_RU.UTF-8 abbreviated -// months. This locale data was fixed in glibc 2.14. -// Debian uses glibc 2.13 as of 20/11/2014 -// OpenSuse uses glibc 2.19 with old locale data as of 20/11/2014 -// XFAIL: debian, opensuse - // <locale> // class time_get_byname<charT, InputIterator> @@ -79,16 +72,6 @@ int main() assert(err == std::ios_base::eofbit); } { - const my_facet f(LOCALE_ru_RU_UTF_8, 1); - const wchar_t in[] = L"\x438\x44E\x43D\x44F"; - err = std::ios_base::goodbit; - t = std::tm(); - I i = f.get_monthname(I(in), I(in+sizeof(in)/sizeof(in[0])-1), ios, err, &t); - assert(i.base() == in+sizeof(in)/sizeof(in[0])-1); - assert(t.tm_mon == 5); - assert(err == std::ios_base::eofbit); - } - { const my_facet f(LOCALE_zh_CN_UTF_8, 1); const wchar_t in[] = L"\x516D\x6708"; err = std::ios_base::goodbit; diff --git a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp index ae8bce22445af..4a2b3819b507f 100644 --- a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp +++ b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp @@ -75,7 +75,7 @@ int main() } { const my_facet f(LOCALE_fr_FR_UTF_8, 1); - const wchar_t in[] = L"Sam 31 d""\xE9""c 23:55:59 2061"; + const wchar_t in[] = L"Sam 31 d" L"\xE9" L"c 23:55:59 2061"; err = std::ios_base::goodbit; t = std::tm(); I i = f.get(I(in), I(in+sizeof(in)/sizeof(in[0])-1), ios, err, &t, 'c'); @@ -105,11 +105,11 @@ int main() { const my_facet f("ru_RU", 1); const wchar_t in[] = L"\x441\x443\x431\x431\x43E\x442\x430" - ", 31 " - "\x434\x435\x43A\x430\x431\x440\x44F" - " 2061 " - "\x433" - ". 23:55:59"; + L", 31 " + L"\x434\x435\x43A\x430\x431\x440\x44F" + L" 2061 " + L"\x433" + L". 23:55:59"; err = std::ios_base::goodbit; t = std::tm(); I i = f.get(I(in), I(in+sizeof(in)/sizeof(in[0])-1), ios, err, &t, 'c'); @@ -140,7 +140,7 @@ int main() { const my_facet f("zh_CN", 1); const wchar_t in[] = L"\x516D" - " 12/31 23:55:59 2061"; + L" 12/31 23:55:59 2061"; err = std::ios_base::goodbit; t = std::tm(); I i = f.get(I(in), I(in+sizeof(in)/sizeof(in[0])-1), ios, err, &t, 'c'); @@ -157,7 +157,7 @@ int main() #endif { const my_facet f(LOCALE_zh_CN_UTF_8, 1); - const wchar_t in[] = L"23""\x65F6""55""\x5206""59""\x79D2"; + const wchar_t in[] = L"23" L"\x65F6" L"55" L"\x5206" L"59" L"\x79D2"; err = std::ios_base::goodbit; t = std::tm(); I i = f.get(I(in), I(in+sizeof(in)/sizeof(in[0])-1), ios, err, &t, 'X'); diff --git a/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_copy.pass.cpp b/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_copy.pass.cpp new file mode 100644 index 0000000000000..72e79dfb1e7fe --- /dev/null +++ b/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_copy.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. +// +//===----------------------------------------------------------------------===// + +// These constructors are still unavailable in C++03, but this test depends +// on access control SFINAE and fails without it. +// UNSUPPORTED: c++98, c++03 + +// <locale> + +// wstring_convert<Codecvt, Elem, Wide_alloc, Byte_alloc> + +// wstring_convert(wstring_convert const&) = delete; +// wstring_convert& operator=(wstring_convert const&) = delete; + +#include <locale> +#include <codecvt> +#include <cassert> + +int main() +{ + typedef std::codecvt_utf8<wchar_t> Codecvt; + typedef std::wstring_convert<Codecvt> Myconv; + static_assert(!std::is_copy_constructible<Myconv>::value, ""); + static_assert(!std::is_copy_assignable<Myconv>::value, ""); +} 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 80afe1e46aad6..8b31a8f974987 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,6 @@ //===----------------------------------------------------------------------===// // REQUIRES: locale.ru_RU.UTF-8 -// UNSUPPORTED: sanitizer-new-delete // <locale> @@ -18,21 +17,10 @@ #include <cassert> #include <new> -#include "platform_support.h" // locale name macros - -int new_called = 0; +#include "count_new.hpp" -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - ++new_called; - return std::malloc(s); -} +#include "platform_support.h" // locale name macros -void operator delete(void* p) throw() -{ - --new_called; - std::free(p); -} void check(const std::locale& loc) { @@ -79,5 +67,5 @@ int main() check(loc); check(loc2); } - assert(new_called == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); } 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 b808a7650c476..c7021df8f5777 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 @@ -10,7 +10,6 @@ // XFAIL: libcpp-no-exceptions // REQUIRES: locale.ru_RU.UTF-8 // REQUIRES: locale.zh_CN.UTF-8 -// UNSUPPORTED: sanitizer-new-delete // <locale> @@ -20,21 +19,9 @@ #include <new> #include <cassert> +#include "count_new.hpp" #include "platform_support.h" // locale name macros -int new_called = 0; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - ++new_called; - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - --new_called; - std::free(p); -} void check(const std::locale& loc) { @@ -101,5 +88,5 @@ int main() } std::locale ok(""); } - assert(new_called == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); } 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 0760cc46cdd8d..9e446e4408513 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,6 @@ //===----------------------------------------------------------------------===// // REQUIRES: locale.fr_FR.UTF-8 -// UNSUPPORTED: sanitizer-new-delete // <locale> @@ -18,22 +17,9 @@ #include <cassert> #include <new> +#include "count_new.hpp" #include "platform_support.h" // locale name macros -int new_called = 0; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - ++new_called; - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - --new_called; - std::free(p); -} - void check(const std::locale& loc) { assert(std::has_facet<std::collate<char> >(loc)); @@ -78,5 +64,5 @@ int main() check(loc); check(loc2); } - assert(new_called == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); } 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 2a9e20fcf98df..eb381f9a580df 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,6 @@ // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.ru_RU.UTF-8 -// UNSUPPORTED: sanitizer-new-delete // <locale> @@ -19,22 +18,9 @@ #include <new> #include <cassert> +#include "count_new.hpp" #include "platform_support.h" // locale name macros -int new_called = 0; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - ++new_called; - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - --new_called; - std::free(p); -} - void check(const std::locale& loc) { assert(std::has_facet<std::collate<char> >(loc)); @@ -78,5 +64,5 @@ int main() std::locale loc2(loc, LOCALE_en_US_UTF_8, std::locale::monetary); check(loc2); } - assert(new_called == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); } 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 fb6e39e5742f3..1144931e3d2c8 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,6 @@ //===----------------------------------------------------------------------===// // REQUIRES: locale.ru_RU.UTF-8 -// UNSUPPORTED: sanitizer-new-delete // <locale> @@ -18,21 +17,9 @@ #include <new> #include <cassert> +#include "count_new.hpp" #include "platform_support.h" // locale name macros -int new_called = 0; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - ++new_called; - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - --new_called; - std::free(p); -} void check(const std::locale& loc) { @@ -81,7 +68,6 @@ std::locale::id my_facet::id; int main() { -{ { std::locale loc(LOCALE_ru_RU_UTF_8); check(loc); @@ -91,9 +77,7 @@ int main() const my_facet& f = std::use_facet<my_facet>(loc2); assert(f.test() == 5); } - assert(new_called == 0); -} -{ + assert(globalMemCounter.checkOutstandingNewEq(0)); { std::locale loc; check(loc); @@ -101,6 +85,5 @@ int main() check(loc2); assert(loc == loc2); } - assert(new_called == 0); -} + assert(globalMemCounter.checkOutstandingNewEq(0)); } 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 fa87eb20e9af1..f1afff66580e8 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,6 @@ // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.ru_RU.UTF-8 -// UNSUPPORTED: sanitizer-new-delete // <locale> @@ -19,22 +18,9 @@ #include <new> #include <cassert> +#include "count_new.hpp" #include "platform_support.h" // locale name macros -int new_called = 0; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - ++new_called; - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - --new_called; - std::free(p); -} - void check(const std::locale& loc) { assert(std::has_facet<std::collate<char> >(loc)); @@ -78,5 +64,5 @@ int main() std::locale loc2(loc, std::locale(LOCALE_en_US_UTF_8), std::locale::monetary); check(loc2); } - assert(new_called == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); } 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 59fbc59b90da9..eb63cd03b6637 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 @@ -6,10 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// - + // REQUIRES: locale.en_US.UTF-8 // REQUIRES: locale.ru_RU.UTF-8 -// UNSUPPORTED: sanitizer-new-delete // <locale> @@ -19,21 +18,9 @@ #include <new> #include <cassert> +#include "count_new.hpp" #include "platform_support.h" // locale name macros -int new_called = 0; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - ++new_called; - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - --new_called; - std::free(p); -} void check(const std::locale& loc) { @@ -78,5 +65,5 @@ int main() std::locale loc2(loc, std::string(LOCALE_en_US_UTF_8), std::locale::monetary); check(loc2); } - assert(new_called == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); } 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 c9f944196e734..6fc0808b2728b 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,6 @@ // REQUIRES: locale.ru_RU.UTF-8 // REQUIRES: locale.zh_CN.UTF-8 -// UNSUPPORTED: sanitizer-new-delete // <locale> @@ -19,22 +18,9 @@ #include <new> #include <cassert> +#include "count_new.hpp" #include "platform_support.h" // locale name macros -int new_called = 0; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - ++new_called; - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - --new_called; - std::free(p); -} - void check(const std::locale& loc) { assert(std::has_facet<std::collate<char> >(loc)); @@ -83,5 +69,5 @@ int main() assert(!(loc == loc3)); assert(loc != loc3); } - assert(new_called == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); } diff --git a/test/std/localization/locales/locale/locale.types/locale.facet/tested_elsewhere.pass.cpp b/test/std/localization/locales/locale/locale.types/locale.facet/tested_elsewhere.pass.cpp new file mode 100644 index 0000000000000..b58f5c55b643a --- /dev/null +++ b/test/std/localization/locales/locale/locale.types/locale.facet/tested_elsewhere.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/localization/locales/locale/locale.types/locale.id/tested_elsewhere.pass.cpp b/test/std/localization/locales/locale/locale.types/locale.id/tested_elsewhere.pass.cpp new file mode 100644 index 0000000000000..b58f5c55b643a --- /dev/null +++ b/test/std/localization/locales/locale/locale.types/locale.id/tested_elsewhere.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/numerics/c.math/cmath.pass.cpp b/test/std/numerics/c.math/cmath.pass.cpp index 0b0d86288737a..7161bd37e3e2a 100644 --- a/test/std/numerics/c.math/cmath.pass.cpp +++ b/test/std/numerics/c.math/cmath.pass.cpp @@ -9,13 +9,11 @@ // <cmath> -// NOTE: isinf and isnan are tested separately because they are expected to fail -// on linux. We don't want their expected failure to hide other failures in this file. - #include <cmath> #include <type_traits> #include <cassert> +#include "test_macros.h" #include "hexfloat.h" // convertible to int/float/double/etc @@ -79,6 +77,7 @@ Ambiguous fma(Ambiguous, Ambiguous, Ambiguous){ return Ambiguous(); } Ambiguous fmax(Ambiguous, Ambiguous){ return Ambiguous(); } Ambiguous fmin(Ambiguous, Ambiguous){ return Ambiguous(); } Ambiguous hypot(Ambiguous, Ambiguous){ return Ambiguous(); } +Ambiguous hypot(Ambiguous, Ambiguous, Ambiguous){ return Ambiguous(); } Ambiguous ilogb(Ambiguous){ return Ambiguous(); } Ambiguous lgamma(Ambiguous){ return Ambiguous(); } Ambiguous llrint(Ambiguous){ return Ambiguous(); } @@ -631,6 +630,29 @@ void test_isgreaterequal() assert(std::isgreaterequal(-1.0, 0.F) == false); } +void test_isinf() +{ +#ifdef isinf +#error isinf defined +#endif + static_assert((std::is_same<decltype(std::isinf((float)0)), bool>::value), ""); + + typedef decltype(std::isinf((double)0)) DoubleRetType; +#ifndef __linux__ + static_assert((std::is_same<DoubleRetType, bool>::value), ""); +#else + // GLIBC < 2.26 defines 'isinf(double)' with a return type of 'int' in + // all C++ dialects. The test should tolerate this. + // See: https://sourceware.org/bugzilla/show_bug.cgi?id=19439 + static_assert((std::is_same<DoubleRetType, bool>::value + || std::is_same<DoubleRetType, int>::value), ""); +#endif + + static_assert((std::is_same<decltype(std::isinf(0)), bool>::value), ""); + static_assert((std::is_same<decltype(std::isinf((long double)0)), bool>::value), ""); + assert(std::isinf(-1.0) == false); +} + void test_isless() { #ifdef isless @@ -688,6 +710,29 @@ void test_islessgreater() assert(std::islessgreater(-1.0, 0.F) == true); } +void test_isnan() +{ +#ifdef isnan +#error isnan defined +#endif + static_assert((std::is_same<decltype(std::isnan((float)0)), bool>::value), ""); + + typedef decltype(std::isnan((double)0)) DoubleRetType; +#ifndef __linux__ + static_assert((std::is_same<DoubleRetType, bool>::value), ""); +#else + // GLIBC < 2.26 defines 'isnan(double)' with a return type of 'int' in + // all C++ dialects. The test should tolerate this. + // See: https://sourceware.org/bugzilla/show_bug.cgi?id=19439 + static_assert((std::is_same<DoubleRetType, bool>::value + || std::is_same<DoubleRetType, int>::value), ""); +#endif + + static_assert((std::is_same<decltype(std::isnan(0)), bool>::value), ""); + static_assert((std::is_same<decltype(std::isnan((long double)0)), bool>::value), ""); + assert(std::isnan(-1.0) == false); +} + void test_isunordered() { #ifdef isunordered @@ -1010,6 +1055,28 @@ void test_hypot() static_assert((std::is_same<decltype(std::hypot((int)0, (int)0)), double>::value), ""); static_assert((std::is_same<decltype(hypot(Ambiguous(), Ambiguous())), Ambiguous>::value), ""); assert(std::hypot(3,4) == 5); + +#if TEST_STD_VER > 14 + static_assert((std::is_same<decltype(std::hypot((float)0, (float)0, (float)0)), float>::value), ""); + static_assert((std::is_same<decltype(std::hypot((float)0, (bool)0, (float)0)), double>::value), ""); + static_assert((std::is_same<decltype(std::hypot((float)0, (unsigned short)0, (double)0)), double>::value), ""); + static_assert((std::is_same<decltype(std::hypot((float)0, (int)0, (long double)0)), long double>::value), ""); + static_assert((std::is_same<decltype(std::hypot((float)0, (unsigned int)0)), double>::value), ""); + static_assert((std::is_same<decltype(std::hypot((float)0, (double)0, (long)0)), double>::value), ""); + static_assert((std::is_same<decltype(std::hypot((float)0, (long double)0, (unsigned long)0)), long double>::value), ""); + static_assert((std::is_same<decltype(std::hypot((float)0, (int)0, (long long)0)), double>::value), ""); + static_assert((std::is_same<decltype(std::hypot((float)0, (int)0, (unsigned long long)0)), double>::value), ""); + static_assert((std::is_same<decltype(std::hypot((float)0, (double)0, (double)0)), double>::value), ""); + static_assert((std::is_same<decltype(std::hypot((float)0, (long double)0, (long double)0)), long double>::value), ""); + static_assert((std::is_same<decltype(std::hypot((float)0, (float)0, (double)0)), double>::value), ""); + static_assert((std::is_same<decltype(std::hypot((float)0, (float)0, (long double)0)), long double>::value), ""); + static_assert((std::is_same<decltype(std::hypot((float)0, (double)0, (long double)0)), long double>::value), ""); + static_assert((std::is_same<decltype(std::hypot((int)0, (int)0, (int)0)), double>::value), ""); + static_assert((std::is_same<decltype(hypot(Ambiguous(), Ambiguous(), Ambiguous())), Ambiguous>::value), ""); + + assert(std::hypot(2,3,6) == 7); + assert(std::hypot(1,4,8) == 9); +#endif } void test_ilogb() @@ -1443,9 +1510,11 @@ int main() test_isnormal(); test_isgreater(); test_isgreaterequal(); + test_isinf(); test_isless(); test_islessequal(); test_islessgreater(); + test_isnan(); test_isunordered(); test_acosh(); test_asinh(); diff --git a/test/std/numerics/c.math/cmath_isinf.pass.cpp b/test/std/numerics/c.math/cmath_isinf.pass.cpp deleted file mode 100644 index 6cde04d9bc868..0000000000000 --- a/test/std/numerics/c.math/cmath_isinf.pass.cpp +++ /dev/null @@ -1,30 +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. -// -//===----------------------------------------------------------------------===// - -// <cmath> - -// isinf - -// XFAIL: linux - -#include <cmath> -#include <type_traits> -#include <cassert> - -int main() -{ -#ifdef isinf -#error isinf defined -#endif - static_assert((std::is_same<decltype(std::isinf((float)0)), bool>::value), ""); - static_assert((std::is_same<decltype(std::isinf((double)0)), bool>::value), ""); - static_assert((std::is_same<decltype(std::isinf(0)), bool>::value), ""); - static_assert((std::is_same<decltype(std::isinf((long double)0)), bool>::value), ""); - assert(std::isinf(-1.0) == false); -}
\ No newline at end of file diff --git a/test/std/numerics/c.math/cmath_isnan.pass.cpp b/test/std/numerics/c.math/cmath_isnan.pass.cpp deleted file mode 100644 index 7b33b96470528..0000000000000 --- a/test/std/numerics/c.math/cmath_isnan.pass.cpp +++ /dev/null @@ -1,30 +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. -// -//===----------------------------------------------------------------------===// - -// <cmath> - -// isnan - -// XFAIL: linux - -#include <cmath> -#include <type_traits> -#include <cassert> - -int main() -{ -#ifdef isnan -#error isnan defined -#endif - static_assert((std::is_same<decltype(std::isnan((float)0)), bool>::value), ""); - static_assert((std::is_same<decltype(std::isnan((double)0)), bool>::value), ""); - static_assert((std::is_same<decltype(std::isnan(0)), bool>::value), ""); - static_assert((std::is_same<decltype(std::isnan((long double)0)), bool>::value), ""); - assert(std::isnan(-1.0) == false); -} diff --git a/test/std/numerics/cfenv/cfenv.syn/cfenv.pass.cpp b/test/std/numerics/cfenv/cfenv.syn/cfenv.pass.cpp index fcf075a36e1a5..f2bf6433ceb4e 100644 --- a/test/std/numerics/cfenv/cfenv.syn/cfenv.pass.cpp +++ b/test/std/numerics/cfenv/cfenv.syn/cfenv.pass.cpp @@ -62,6 +62,8 @@ int main() { std::fenv_t fenv; std::fexcept_t fex; + ((void)fenv); // Prevent unused warning + ((void)fex); // Prevent unused warning 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/complex.number/cases.h b/test/std/numerics/complex.number/cases.h index cd6bd165a9d16..a2f85d11ca4d1 100644 --- a/test/std/numerics/complex.number/cases.h +++ b/test/std/numerics/complex.number/cases.h @@ -17,7 +17,7 @@ #include <complex> #include <cassert> -std::complex<double> x[] = +const std::complex<double> testcases[] = { std::complex<double>( 1.e-6, 1.e-6), std::complex<double>(-1.e-6, 1.e-6), diff --git a/test/std/numerics/complex.number/cmplx.over/imag.pass.cpp b/test/std/numerics/complex.number/cmplx.over/imag.pass.cpp index 30c95c3c88d96..7decea877fbd0 100644 --- a/test/std/numerics/complex.number/cmplx.over/imag.pass.cpp +++ b/test/std/numerics/complex.number/cmplx.over/imag.pass.cpp @@ -30,7 +30,7 @@ test(typename std::enable_if<std::is_integral<T>::value>::type* = 0) static_assert(std::imag(val) == 0, ""); constexpr std::complex<T> t{val, val}; static_assert(t.imag() == x, "" ); -#endif +#endif } template <class T, int x> @@ -44,7 +44,7 @@ test(typename std::enable_if<!std::is_integral<T>::value>::type* = 0) static_assert(std::imag(val) == 0, ""); constexpr std::complex<T> t{val, val}; static_assert(t.imag() == x, "" ); -#endif +#endif } template <class T> diff --git a/test/std/numerics/complex.number/cmplx.over/real.pass.cpp b/test/std/numerics/complex.number/cmplx.over/real.pass.cpp index a5a4a35b13caa..491b35890c0c3 100644 --- a/test/std/numerics/complex.number/cmplx.over/real.pass.cpp +++ b/test/std/numerics/complex.number/cmplx.over/real.pass.cpp @@ -30,7 +30,7 @@ test(typename std::enable_if<std::is_integral<T>::value>::type* = 0) static_assert(std::real(val) == val, ""); constexpr std::complex<T> t{val, val}; static_assert(t.real() == x, "" ); -#endif +#endif } template <class T, int x> @@ -44,7 +44,7 @@ test(typename std::enable_if<!std::is_integral<T>::value>::type* = 0) static_assert(std::real(val) == val, ""); constexpr std::complex<T> t{val, val}; static_assert(t.real() == x, "" ); -#endif +#endif } template <class T> diff --git a/test/std/numerics/complex.number/complex.literals/literals.pass.cpp b/test/std/numerics/complex.number/complex.literals/literals.pass.cpp index 45b59914e7f84..a2e53629f97dc 100644 --- a/test/std/numerics/complex.number/complex.literals/literals.pass.cpp +++ b/test/std/numerics/complex.number/complex.literals/literals.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <chrono> #include <complex> @@ -15,7 +16,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using namespace std::literals::complex_literals; // Make sure the types are right @@ -25,14 +25,14 @@ int main() static_assert ( std::is_same<decltype( 3i ), std::complex<double>>::value, "" ); static_assert ( std::is_same<decltype( 3.0if ), std::complex<float>>::value, "" ); static_assert ( std::is_same<decltype( 3if ), std::complex<float>>::value, "" ); - + { std::complex<long double> c1 = 3.0il; assert ( c1 == std::complex<long double>(0, 3.0)); auto c2 = 3il; assert ( c1 == c2 ); } - + { std::complex<double> c1 = 3.0i; assert ( c1 == std::complex<double>(0, 3.0)); @@ -46,6 +46,4 @@ int main() auto c2 = 3if; assert ( c1 == c2 ); } - -#endif } diff --git a/test/std/numerics/complex.number/complex.literals/literals1.fail.cpp b/test/std/numerics/complex.number/complex.literals/literals1.fail.cpp index 0f31d595566c6..67e0fa131fd00 100644 --- a/test/std/numerics/complex.number/complex.literals/literals1.fail.cpp +++ b/test/std/numerics/complex.number/complex.literals/literals1.fail.cpp @@ -7,14 +7,12 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 #include <complex> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 std::complex<float> foo = 1.0if; // should fail w/conversion operator not found -#else -#error -#endif } diff --git a/test/std/numerics/complex.number/complex.literals/literals1.pass.cpp b/test/std/numerics/complex.number/complex.literals/literals1.pass.cpp index 46903bbd565d4..09a6f270f7595 100644 --- a/test/std/numerics/complex.number/complex.literals/literals1.pass.cpp +++ b/test/std/numerics/complex.number/complex.literals/literals1.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <chrono> #include <complex> @@ -15,7 +16,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using namespace std::literals; { @@ -24,7 +24,7 @@ int main() auto c2 = 3il; assert ( c1 == c2 ); } - + { std::complex<double> c1 = 3.0i; assert ( c1 == std::complex<double>(0, 3.0)); @@ -38,6 +38,4 @@ int main() auto c2 = 3if; assert ( c1 == c2 ); } - -#endif } diff --git a/test/std/numerics/complex.number/complex.literals/literals2.pass.cpp b/test/std/numerics/complex.number/complex.literals/literals2.pass.cpp index 8bd8acd981bcf..d11530d7803a2 100644 --- a/test/std/numerics/complex.number/complex.literals/literals2.pass.cpp +++ b/test/std/numerics/complex.number/complex.literals/literals2.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <chrono> #include <complex> @@ -15,7 +16,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using namespace std; { @@ -24,7 +24,7 @@ int main() auto c2 = 3il; assert ( c1 == c2 ); } - + { std::complex<double> c1 = 3.0i; assert ( c1 == std::complex<double>(0, 3.0)); @@ -38,6 +38,4 @@ int main() auto c2 = 3if; assert ( c1 == c2 ); } - -#endif } diff --git a/test/std/numerics/complex.number/complex.member.ops/divide_equal_complex.pass.cpp b/test/std/numerics/complex.number/complex.member.ops/divide_equal_complex.pass.cpp index cb285117b15df..b4200fc81d402 100644 --- a/test/std/numerics/complex.number/complex.member.ops/divide_equal_complex.pass.cpp +++ b/test/std/numerics/complex.number/complex.member.ops/divide_equal_complex.pass.cpp @@ -28,7 +28,7 @@ test() c /= c2; assert(c.real() == 1); assert(c.imag() == 0); - + std::complex<T> c3; c3 = c; @@ -36,13 +36,13 @@ test() c3 /= ic; assert(c3.real() == 0.5); assert(c3.imag() == -0.5); - + c3 = c; std::complex<float> fc (1,1); c3 /= fc; assert(c3.real() == 0.5); assert(c3.imag() == -0.5); - + } int main() diff --git a/test/std/numerics/complex.number/complex.member.ops/plus_equal_complex.pass.cpp b/test/std/numerics/complex.number/complex.member.ops/plus_equal_complex.pass.cpp index 8c16f4ced2cdb..9b222b8a1d3c3 100644 --- a/test/std/numerics/complex.number/complex.member.ops/plus_equal_complex.pass.cpp +++ b/test/std/numerics/complex.number/complex.member.ops/plus_equal_complex.pass.cpp @@ -36,7 +36,7 @@ test() c3 += ic; assert(c3.real() == 4); assert(c3.imag() == 6); - + c3 = c; std::complex<float> fc (1,1); c3 += fc; diff --git a/test/std/numerics/complex.number/complex.member.ops/times_equal_complex.pass.cpp b/test/std/numerics/complex.number/complex.member.ops/times_equal_complex.pass.cpp index 84d6e591306eb..98b7197cb2722 100644 --- a/test/std/numerics/complex.number/complex.member.ops/times_equal_complex.pass.cpp +++ b/test/std/numerics/complex.number/complex.member.ops/times_equal_complex.pass.cpp @@ -36,7 +36,7 @@ test() c3 *= ic; assert(c3.real() == -11.5); assert(c3.imag() == 3.5); - + c3 = c; std::complex<float> fc (1,1); c3 *= fc; diff --git a/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp b/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp index 86119678aa70e..8d4712eece78d 100644 --- a/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp +++ b/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp @@ -37,16 +37,16 @@ test() void test_edges() { - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { for (unsigned j = 0; j < N; ++j) { - std::complex<double> r = x[i] / x[j]; - switch (classify(x[i])) + std::complex<double> r = testcases[i] / testcases[j]; + switch (classify(testcases[i])) { case zero: - switch (classify(x[j])) + switch (classify(testcases[j])) { case zero: assert(classify(r) == NaN); @@ -66,7 +66,7 @@ void test_edges() } break; case non_zero: - switch (classify(x[j])) + switch (classify(testcases[j])) { case zero: assert(classify(r) == inf); @@ -86,7 +86,7 @@ void test_edges() } break; case inf: - switch (classify(x[j])) + switch (classify(testcases[j])) { case zero: assert(classify(r) == inf); @@ -106,7 +106,7 @@ void test_edges() } break; case NaN: - switch (classify(x[j])) + switch (classify(testcases[j])) { case zero: assert(classify(r) == NaN); @@ -126,7 +126,7 @@ void test_edges() } break; case non_zero_nan: - switch (classify(x[j])) + switch (classify(testcases[j])) { case zero: assert(classify(r) == inf); diff --git a/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp b/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp index 565eaa5657cd1..8ead5bfb627a6 100644 --- a/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp +++ b/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp @@ -39,16 +39,16 @@ test() void test_edges() { - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { for (unsigned j = 0; j < N; ++j) { - std::complex<double> r = x[i] * x[j]; - switch (classify(x[i])) + std::complex<double> r = testcases[i] * testcases[j]; + switch (classify(testcases[i])) { case zero: - switch (classify(x[j])) + switch (classify(testcases[j])) { case zero: assert(classify(r) == zero); @@ -68,7 +68,7 @@ void test_edges() } break; case non_zero: - switch (classify(x[j])) + switch (classify(testcases[j])) { case zero: assert(classify(r) == zero); @@ -88,7 +88,7 @@ void test_edges() } break; case inf: - switch (classify(x[j])) + switch (classify(testcases[j])) { case zero: assert(classify(r) == NaN); @@ -108,7 +108,7 @@ void test_edges() } break; case NaN: - switch (classify(x[j])) + switch (classify(testcases[j])) { case zero: assert(classify(r) == NaN); @@ -128,7 +128,7 @@ void test_edges() } break; case non_zero_nan: - switch (classify(x[j])) + switch (classify(testcases[j])) { case zero: assert(classify(r) == NaN); diff --git a/test/std/numerics/complex.number/complex.transcendentals/acos.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/acos.pass.cpp index f8ee306d7544e..1b0cca0d5f696 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/acos.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/acos.pass.cpp @@ -36,94 +36,94 @@ void test_edges() { typedef std::complex<double> C; const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = acos(x[i]); - if (x[i].real() == 0 && x[i].imag() == 0) + std::complex<double> r = acos(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { is_about(r.real(), pi/2); assert(r.imag() == 0); - assert(std::signbit(x[i].imag()) != std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); } - else if (x[i].real() == 0 && std::isnan(x[i].imag())) + else if (testcases[i].real() == 0 && std::isnan(testcases[i].imag())) { is_about(r.real(), pi/2); assert(std::isnan(r.imag())); } - else if (std::isfinite(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { is_about(r.real(), pi/2); assert(std::isinf(r.imag())); - assert(std::signbit(x[i].imag()) != std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); } - else if (std::isfinite(x[i].real()) && x[i].real() != 0 && std::isnan(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && testcases[i].real() != 0 && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].real() < 0 && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isfinite(testcases[i].imag())) { is_about(r.real(), pi); assert(std::isinf(r.imag())); - assert(std::signbit(x[i].imag()) != std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].real() > 0 && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isfinite(testcases[i].imag())) { assert(r.real() == 0); assert(!std::signbit(r.real())); assert(std::isinf(r.imag())); - assert(std::signbit(x[i].imag()) != std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].real() < 0 && std::isinf(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isinf(testcases[i].imag())) { is_about(r.real(), 0.75 * pi); assert(std::isinf(r.imag())); - assert(std::signbit(x[i].imag()) != std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].real() > 0 && std::isinf(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isinf(testcases[i].imag())) { is_about(r.real(), 0.25 * pi); assert(std::isinf(r.imag())); - assert(std::signbit(x[i].imag()) != std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); } - else if (std::isinf(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isinf(r.imag())); } - else if (std::isnan(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isinf(r.imag())); - assert(std::signbit(x[i].imag()) != std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); } - else if (std::isnan(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (!std::signbit(x[i].real()) && !std::signbit(x[i].imag())) + else if (!std::signbit(testcases[i].real()) && !std::signbit(testcases[i].imag())) { assert(!std::signbit(r.real())); assert( std::signbit(r.imag())); } - else if (std::signbit(x[i].real()) && !std::signbit(x[i].imag())) + else if (std::signbit(testcases[i].real()) && !std::signbit(testcases[i].imag())) { assert(!std::signbit(r.real())); assert( std::signbit(r.imag())); } - else if (std::signbit(x[i].real()) && std::signbit(x[i].imag())) + else if (std::signbit(testcases[i].real()) && std::signbit(testcases[i].imag())) { assert(!std::signbit(r.real())); assert(!std::signbit(r.imag())); } - else if (!std::signbit(x[i].real()) && std::signbit(x[i].imag())) + else if (!std::signbit(testcases[i].real()) && std::signbit(testcases[i].imag())) { assert(!std::signbit(r.real())); assert(!std::signbit(r.imag())); diff --git a/test/std/numerics/complex.number/complex.transcendentals/acosh.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/acosh.pass.cpp index 88a5c798424d0..f1aece20e6cf6 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/acosh.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/acosh.pass.cpp @@ -36,91 +36,91 @@ void test_edges() { typedef std::complex<double> C; const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = acosh(x[i]); - if (x[i].real() == 0 && x[i].imag() == 0) + std::complex<double> r = acosh(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { assert(!std::signbit(r.real())); - if (std::signbit(x[i].imag())) + if (std::signbit(testcases[i].imag())) is_about(r.imag(), -pi/2); else is_about(r.imag(), pi/2); } - else if (x[i].real() == 1 && x[i].imag() == 0) + else if (testcases[i].real() == 1 && testcases[i].imag() == 0) { assert(r.real() == 0); assert(!std::signbit(r.real())); assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (std::isfinite(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); assert(r.real() > 0); - if (std::signbit(x[i].imag())) + if (std::signbit(testcases[i].imag())) is_about(r.imag(), -pi/2); else is_about(r.imag(), pi/2); } - else if (std::isfinite(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].real() < 0 && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isfinite(testcases[i].imag())) { assert(std::isinf(r.real())); assert(r.real() > 0); - if (std::signbit(x[i].imag())) + if (std::signbit(testcases[i].imag())) is_about(r.imag(), -pi); else is_about(r.imag(), pi); } - else if (std::isinf(x[i].real()) && x[i].real() > 0 && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isfinite(testcases[i].imag())) { assert(std::isinf(r.real())); assert(r.real() > 0); assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (std::isinf(x[i].real()) && x[i].real() < 0 && std::isinf(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); assert(r.real() > 0); - if (std::signbit(x[i].imag())) + if (std::signbit(testcases[i].imag())) is_about(r.imag(), -0.75 * pi); else is_about(r.imag(), 0.75 * pi); } - else if (std::isinf(x[i].real()) && x[i].real() > 0 && std::isinf(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); assert(r.real() > 0); - if (std::signbit(x[i].imag())) + if (std::signbit(testcases[i].imag())) is_about(r.imag(), -0.25 * pi); else is_about(r.imag(), 0.25 * pi); } - else if (std::isinf(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isinf(r.real())); assert(r.real() > 0); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); assert(r.real() > 0); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); @@ -128,7 +128,7 @@ void test_edges() else { assert(!std::signbit(r.real())); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } } } diff --git a/test/std/numerics/complex.number/complex.transcendentals/asin.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/asin.pass.cpp index c743be6488c6a..cf6f7869bd1a2 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/asin.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/asin.pass.cpp @@ -36,77 +36,77 @@ void test_edges() { typedef std::complex<double> C; const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = asin(x[i]); - if (x[i].real() == 0 && x[i].imag() == 0) + std::complex<double> r = asin(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { - assert(std::signbit(r.real()) == std::signbit(x[i].real())); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (std::isfinite(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(r.real() == 0); - assert(std::signbit(x[i].real()) == std::signbit(r.real())); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); assert(std::isinf(r.imag())); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } - else if ( x[i].real() == 0 && std::isnan(x[i].imag())) + else if ( testcases[i].real() == 0 && std::isnan(testcases[i].imag())) { assert(r.real() == 0); - assert(std::signbit(x[i].real()) == std::signbit(r.real())); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); assert(std::isnan(r.imag())); } - else if (std::isfinite(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) { - if (x[i].real() > 0) + if (testcases[i].real() > 0) is_about(r.real(), pi/2); else is_about(r.real(), - pi/2); assert(std::isinf(r.imag())); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } - else if (std::isinf(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { - if (std::signbit(x[i].real())) + if (std::signbit(testcases[i].real())) is_about(r.real(), -pi/4); else is_about(r.real(), pi/4); assert(std::isinf(r.imag())); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } - else if (std::isinf(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isinf(r.imag())); - assert(std::signbit(x[i].real()) != std::signbit(r.imag())); + assert(std::signbit(testcases[i].real()) != std::signbit(r.imag())); } - else if (std::isnan(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } - else if (std::isnan(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isinf(r.imag())); } - else if (std::isnan(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } else { - assert(std::signbit(r.real()) == std::signbit(x[i].real())); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } } } diff --git a/test/std/numerics/complex.number/complex.transcendentals/asinh.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/asinh.pass.cpp index 027bc6a98a99f..011f9d6b4f2e9 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/asinh.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/asinh.pass.cpp @@ -36,76 +36,76 @@ void test_edges() { typedef std::complex<double> C; const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = asinh(x[i]); - if (x[i].real() == 0 && x[i].imag() == 0) + std::complex<double> r = asinh(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { - assert(std::signbit(r.real()) == std::signbit(x[i].real())); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (std::isfinite(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); - assert(std::signbit(x[i].real()) == std::signbit(r.real())); - if (std::signbit(x[i].imag())) + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + if (std::signbit(testcases[i].imag())) is_about(r.imag(), -pi/2); else is_about(r.imag(), pi/2); } - else if (std::isfinite(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) { assert(std::isinf(r.real())); - assert(std::signbit(x[i].real()) == std::signbit(r.real())); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); assert(r.imag() == 0); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } - else if (std::isinf(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); - assert(std::signbit(x[i].real()) == std::signbit(r.real())); - if (std::signbit(x[i].imag())) + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + if (std::signbit(testcases[i].imag())) is_about(r.imag(), -pi/4); else is_about(r.imag(), pi/4); } - else if (std::isinf(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isinf(r.real())); - assert(std::signbit(x[i].real()) == std::signbit(r.real())); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && x[i].imag() == 0) + else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) { assert(std::isnan(r.real())); assert(r.imag() == 0); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } - else if (std::isnan(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } else { - assert(std::signbit(r.real()) == std::signbit(x[i].real())); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } } } diff --git a/test/std/numerics/complex.number/complex.transcendentals/atan.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/atan.pass.cpp index 69bc95240141d..8cc71f7bff275 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/atan.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/atan.pass.cpp @@ -35,11 +35,11 @@ test() void test_edges() { typedef std::complex<double> C; - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = atan(x[i]); - std::complex<double> t1(-imag(x[i]), real(x[i])); + std::complex<double> r = atan(testcases[i]); + std::complex<double> t1(-imag(testcases[i]), real(testcases[i])); std::complex<double> t2 = atanh(t1); std::complex<double> z(imag(t2), -real(t2)); if (std::isnan(real(r))) diff --git a/test/std/numerics/complex.number/complex.transcendentals/atanh.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/atanh.pass.cpp index b821109b751bf..6dc6034ca3c62 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/atanh.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/atanh.pass.cpp @@ -36,89 +36,89 @@ void test_edges() { typedef std::complex<double> C; const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = atanh(x[i]); - if (x[i].real() == 0 && x[i].imag() == 0) + std::complex<double> r = atanh(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { - assert(std::signbit(r.real()) == std::signbit(x[i].real())); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if ( x[i].real() == 0 && std::isnan(x[i].imag())) + else if ( testcases[i].real() == 0 && std::isnan(testcases[i].imag())) { assert(r.real() == 0); - assert(std::signbit(x[i].real()) == std::signbit(r.real())); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); assert(std::isnan(r.imag())); } - else if (std::abs(x[i].real()) == 1 && x[i].imag() == 0) + else if (std::abs(testcases[i].real()) == 1 && testcases[i].imag() == 0) { assert(std::isinf(r.real())); - assert(std::signbit(x[i].real()) == std::signbit(r.real())); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); assert(r.imag() == 0); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } - else if (std::isfinite(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(r.real() == 0); - assert(std::signbit(x[i].real()) == std::signbit(r.real())); - if (x[i].imag() > 0) + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + if (testcases[i].imag() > 0) is_about(r.imag(), pi/2); else is_about(r.imag(), -pi/2); } - else if (std::isfinite(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) { assert(r.real() == 0); - assert(std::signbit(x[i].real()) == std::signbit(r.real())); - if (std::signbit(x[i].imag())) + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + if (std::signbit(testcases[i].imag())) is_about(r.imag(), -pi/2); else is_about(r.imag(), pi/2); } - else if (std::isinf(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(r.real() == 0); - assert(std::signbit(x[i].real()) == std::signbit(r.real())); - if (std::signbit(x[i].imag())) + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + if (std::signbit(testcases[i].imag())) is_about(r.imag(), -pi/2); else is_about(r.imag(), pi/2); } - else if (std::isinf(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(r.real() == 0); - assert(std::signbit(x[i].real()) == std::signbit(r.real())); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(r.real() == 0); - assert(std::signbit(x[i].real()) == std::signbit(r.real())); - if (std::signbit(x[i].imag())) + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + if (std::signbit(testcases[i].imag())) is_about(r.imag(), -pi/2); else is_about(r.imag(), pi/2); } - else if (std::isnan(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } else { - assert(std::signbit(r.real()) == std::signbit(x[i].real())); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } } } diff --git a/test/std/numerics/complex.number/complex.transcendentals/cos.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/cos.pass.cpp index f25c967cb1a75..e09163a7057d2 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/cos.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/cos.pass.cpp @@ -36,11 +36,11 @@ void test_edges() { typedef std::complex<double> C; const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = cos(x[i]); - std::complex<double> t1(-imag(x[i]), real(x[i])); + std::complex<double> r = cos(testcases[i]); + std::complex<double> t1(-imag(testcases[i]), real(testcases[i])); std::complex<double> z = cosh(t1); if (std::isnan(real(r))) assert(std::isnan(real(z))); diff --git a/test/std/numerics/complex.number/complex.transcendentals/cosh.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/cosh.pass.cpp index acf4746389c8c..0fd9cf79bcbfd 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/cosh.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/cosh.pass.cpp @@ -36,72 +36,72 @@ void test_edges() { typedef std::complex<double> C; const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = cosh(x[i]); - if (x[i].real() == 0 && x[i].imag() == 0) + std::complex<double> r = cosh(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { assert(r.real() == 1); assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (x[i].real() == 0 && std::isinf(x[i].imag())) + else if (testcases[i].real() == 0 && std::isinf(testcases[i].imag())) { assert(std::isnan(r.real())); assert(r.imag() == 0); } - else if (x[i].real() == 0 && std::isnan(x[i].imag())) + else if (testcases[i].real() == 0 && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(r.imag() == 0); } - else if (std::isfinite(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isfinite(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].imag() == 0) + else if (std::isinf(testcases[i].real()) && testcases[i].imag() == 0) { assert(std::isinf(r.real())); assert(!std::signbit(r.real())); assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (std::isinf(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) { assert(std::isinf(r.real())); - assert(std::signbit(r.real()) == std::signbit(cos(x[i].imag()))); + assert(std::signbit(r.real()) == std::signbit(cos(testcases[i].imag()))); assert(std::isinf(r.imag())); - assert(std::signbit(r.imag()) == std::signbit(x[i].real() * sin(x[i].imag()))); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].real() * sin(testcases[i].imag()))); } - else if (std::isinf(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isinf(r.real())); assert(r.real() > 0); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && x[i].imag() == 0) + else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) { assert(std::isnan(r.real())); assert(r.imag() == 0); } - else if (std::isnan(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); diff --git a/test/std/numerics/complex.number/complex.transcendentals/exp.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/exp.pass.cpp index e8b507572f1ba..31317816fae07 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/exp.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/exp.pass.cpp @@ -34,73 +34,73 @@ test() void test_edges() { - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = exp(x[i]); - if (x[i].real() == 0 && x[i].imag() == 0) + std::complex<double> r = exp(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { assert(r.real() == 1.0); assert(r.imag() == 0); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } - else if (std::isfinite(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isfinite(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].real() > 0 && x[i].imag() == 0) + else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && testcases[i].imag() == 0) { assert(std::isinf(r.real())); assert(r.real() > 0); assert(r.imag() == 0); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].real() < 0 && std::isinf(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isinf(testcases[i].imag())) { assert(r.real() == 0); assert(r.imag() == 0); } - else if (std::isinf(x[i].real()) && x[i].real() > 0 && std::isinf(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].real() < 0 && std::isnan(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isnan(testcases[i].imag())) { assert(r.real() == 0); assert(r.imag() == 0); } - else if (std::isinf(x[i].real()) && x[i].real() > 0 && std::isnan(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isnan(testcases[i].imag())) { assert(std::isinf(r.real())); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && x[i].imag() == 0) + else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) { assert(std::isnan(r.real())); assert(r.imag() == 0); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } - else if (std::isnan(x[i].real()) && x[i].imag() != 0) + else if (std::isnan(testcases[i].real()) && testcases[i].imag() != 0) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isfinite(x[i].imag()) && std::abs(x[i].imag()) <= 1) + else if (std::isfinite(testcases[i].imag()) && std::abs(testcases[i].imag()) <= 1) { assert(!std::signbit(r.real())); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } } } diff --git a/test/std/numerics/complex.number/complex.transcendentals/log.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/log.pass.cpp index 800b92474bf08..589b5969950df 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/log.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/log.pass.cpp @@ -35,17 +35,17 @@ test() void test_edges() { const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = log(x[i]); - if (x[i].real() == 0 && x[i].imag() == 0) + std::complex<double> r = log(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { - if (std::signbit(x[i].real())) + if (std::signbit(testcases[i].real())) { assert(std::isinf(r.real())); assert(r.real() < 0); - if (std::signbit(x[i].imag())) + if (std::signbit(testcases[i].imag())) is_about(r.imag(), -pi); else is_about(r.imag(), pi); @@ -55,24 +55,24 @@ void test_edges() assert(std::isinf(r.real())); assert(r.real() < 0); assert(r.imag() == 0); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } } - else if (std::isfinite(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); assert(r.real() > 0); - if (x[i].imag() > 0) + if (testcases[i].imag() > 0) is_about(r.imag(), pi/2); else is_about(r.imag(), -pi/2); } - else if (std::isfinite(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].real() < 0 && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isfinite(testcases[i].imag())) { assert(std::isinf(r.real()) && r.real() > 0); if (r.imag() > 0) @@ -80,44 +80,44 @@ void test_edges() else is_about(r.imag(), -pi); } - else if (std::isinf(x[i].real()) && x[i].real() > 0 && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isfinite(testcases[i].imag())) { assert(std::isinf(r.real()) && r.real() > 0); assert(r.imag() == 0); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } - else if (x[i].real() == 1 && x[i].imag() == 0) + else if (testcases[i].real() == 1 && testcases[i].imag() == 0) { assert(r.real() == 0); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (x[i].real() == 0 && x[i].imag() == 1) + else if (testcases[i].real() == 0 && testcases[i].imag() == 1) { assert(r.real() == 0); is_about(r.imag(), pi/2); } - else if (x[i].real() == -1 && x[i].imag() == 0) + else if (testcases[i].real() == -1 && testcases[i].imag() == 0) { assert(r.real() == 0); - if (std::signbit(x[i].imag())) + if (std::signbit(testcases[i].imag())) is_about(r.imag(), -pi); else is_about(r.imag(), pi); } - else if (x[i].real() == 0 && x[i].imag() == -1) + else if (testcases[i].real() == 0 && testcases[i].imag() == -1) { assert(r.real() == 0); is_about(r.imag(), -pi/2); } - else if (std::isfinite(x[i].real()) && std::isfinite(x[i].imag()) && abs(x[i]) < 1) + else if (std::isfinite(testcases[i].real()) && std::isfinite(testcases[i].imag()) && abs(testcases[i]) < 1) { assert( std::signbit(r.real())); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (std::isfinite(x[i].real()) && std::isfinite(x[i].imag()) && abs(x[i]) > 1) + else if (std::isfinite(testcases[i].real()) && std::isfinite(testcases[i].imag()) && abs(testcases[i]) > 1) { assert(!std::signbit(r.real())); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } } } diff --git a/test/std/numerics/complex.number/complex.transcendentals/log10.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/log10.pass.cpp index ba03ebf8ad288..58286904ae255 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/log10.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/log10.pass.cpp @@ -35,11 +35,11 @@ test() void test_edges() { const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = log10(x[i]); - std::complex<double> z = log(x[i])/std::log(10); + std::complex<double> r = log10(testcases[i]); + std::complex<double> z = log(testcases[i])/std::log(10); if (std::isnan(real(r))) assert(std::isnan(real(z))); else diff --git a/test/std/numerics/complex.number/complex.transcendentals/pow_complex_complex.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/pow_complex_complex.pass.cpp index 258193d257a84..157246947cfef 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/pow_complex_complex.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/pow_complex_complex.pass.cpp @@ -37,13 +37,13 @@ test() void test_edges() { const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { for (unsigned j = 0; j < N; ++j) { - std::complex<double> r = pow(x[i], x[j]); - std::complex<double> z = exp(x[j] * log(x[i])); + std::complex<double> r = pow(testcases[i], testcases[j]); + std::complex<double> z = exp(testcases[j] * log(testcases[i])); if (std::isnan(real(r))) assert(std::isnan(real(z))); else diff --git a/test/std/numerics/complex.number/complex.transcendentals/pow_complex_scalar.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/pow_complex_scalar.pass.cpp index 03bd10d465d10..0752ea59f5543 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/pow_complex_scalar.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/pow_complex_scalar.pass.cpp @@ -37,13 +37,13 @@ test() void test_edges() { const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { for (unsigned j = 0; j < N; ++j) { - std::complex<double> r = pow(x[i], real(x[j])); - std::complex<double> z = exp(std::complex<double>(real(x[j])) * log(x[i])); + std::complex<double> r = pow(testcases[i], real(testcases[j])); + std::complex<double> z = exp(std::complex<double>(real(testcases[j])) * log(testcases[i])); if (std::isnan(real(r))) assert(std::isnan(real(z))); else diff --git a/test/std/numerics/complex.number/complex.transcendentals/pow_scalar_complex.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/pow_scalar_complex.pass.cpp index a48498cea92c5..aedeec8caacc0 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/pow_scalar_complex.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/pow_scalar_complex.pass.cpp @@ -37,13 +37,13 @@ test() void test_edges() { const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { for (unsigned j = 0; j < N; ++j) { - std::complex<double> r = pow(real(x[i]), x[j]); - std::complex<double> z = exp(x[j] * log(std::complex<double>(real(x[i])))); + std::complex<double> r = pow(real(testcases[i]), testcases[j]); + std::complex<double> z = exp(testcases[j] * log(std::complex<double>(real(testcases[i])))); if (std::isnan(real(r))) assert(std::isnan(real(z))); else diff --git a/test/std/numerics/complex.number/complex.transcendentals/sin.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/sin.pass.cpp index 068222a273735..e1b98ecd06777 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/sin.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/sin.pass.cpp @@ -36,11 +36,11 @@ void test_edges() { typedef std::complex<double> C; const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = sin(x[i]); - std::complex<double> t1(-imag(x[i]), real(x[i])); + std::complex<double> r = sin(testcases[i]); + std::complex<double> t1(-imag(testcases[i]), real(testcases[i])); std::complex<double> t2 = sinh(t1); std::complex<double> z(imag(t2), -real(t2)); if (std::isnan(real(r))) diff --git a/test/std/numerics/complex.number/complex.transcendentals/sinh.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/sinh.pass.cpp index dcd30e48dff59..20f2e71b140ad 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/sinh.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/sinh.pass.cpp @@ -36,73 +36,73 @@ void test_edges() { typedef std::complex<double> C; const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = sinh(x[i]); - if (x[i].real() == 0 && x[i].imag() == 0) + std::complex<double> r = sinh(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { assert(r.real() == 0); - assert(std::signbit(r.real()) == std::signbit(x[i].real())); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (x[i].real() == 0 && std::isinf(x[i].imag())) + else if (testcases[i].real() == 0 && std::isinf(testcases[i].imag())) { assert(r.real() == 0); assert(std::isnan(r.imag())); } - else if (std::isfinite(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (x[i].real() == 0 && std::isnan(x[i].imag())) + else if (testcases[i].real() == 0 && std::isnan(testcases[i].imag())) { assert(r.real() == 0); assert(std::isnan(r.imag())); } - else if (std::isfinite(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].imag() == 0) + else if (std::isinf(testcases[i].real()) && testcases[i].imag() == 0) { assert(std::isinf(r.real())); - assert(std::signbit(r.real()) == std::signbit(x[i].real())); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (std::isinf(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) { assert(std::isinf(r.real())); - assert(std::signbit(r.real()) == std::signbit(x[i].real() * cos(x[i].imag()))); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real() * cos(testcases[i].imag()))); assert(std::isinf(r.imag())); - assert(std::signbit(r.imag()) == std::signbit(sin(x[i].imag()))); + assert(std::signbit(r.imag()) == std::signbit(sin(testcases[i].imag()))); } - else if (std::isinf(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isinf(r.real())); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && x[i].imag() == 0) + else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) { assert(std::isnan(r.real())); assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (std::isnan(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); diff --git a/test/std/numerics/complex.number/complex.transcendentals/sqrt.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/sqrt.pass.cpp index 69309d2b9ab16..d3273179a6dac 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/sqrt.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/sqrt.pass.cpp @@ -36,58 +36,58 @@ test() void test_edges() { - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = sqrt(x[i]); - if (x[i].real() == 0 && x[i].imag() == 0) + std::complex<double> r = sqrt(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { assert(!std::signbit(r.real())); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (std::isinf(x[i].imag())) + else if (std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); assert(r.real() > 0); assert(std::isinf(r.imag())); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (std::isfinite(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].real() < 0 && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isfinite(testcases[i].imag())) { assert(r.real() == 0); assert(!std::signbit(r.real())); assert(std::isinf(r.imag())); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].real() > 0 && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isfinite(testcases[i].imag())) { assert(std::isinf(r.real())); assert(r.real() > 0); assert(r.imag() == 0); - assert(std::signbit(x[i].imag()) == std::signbit(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].real() < 0 && std::isnan(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isinf(r.imag())); } - else if (std::isinf(x[i].real()) && x[i].real() > 0 && std::isnan(x[i].imag())) + else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isnan(testcases[i].imag())) { assert(std::isinf(r.real())); assert(r.real() > 0); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && (std::isfinite(x[i].imag()) || std::isnan(x[i].imag()))) + else if (std::isnan(testcases[i].real()) && (std::isfinite(testcases[i].imag()) || std::isnan(testcases[i].imag()))) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::signbit(x[i].imag())) + else if (std::signbit(testcases[i].imag())) { assert(!std::signbit(r.real())); assert(std::signbit(r.imag())); diff --git a/test/std/numerics/complex.number/complex.transcendentals/tan.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/tan.pass.cpp index 8814276006860..041a7814d0335 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/tan.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/tan.pass.cpp @@ -37,11 +37,11 @@ void test_edges() { typedef std::complex<double> C; const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = tan(x[i]); - std::complex<double> t1(-imag(x[i]), real(x[i])); + std::complex<double> r = tan(testcases[i]); + std::complex<double> t1(-imag(testcases[i]), real(testcases[i])); std::complex<double> t2 = tanh(t1); std::complex<double> z(imag(t2), -real(t2)); if (std::isnan(real(r))) diff --git a/test/std/numerics/complex.number/complex.transcendentals/tanh.pass.cpp b/test/std/numerics/complex.number/complex.transcendentals/tanh.pass.cpp index 907c0e64dba90..9a2276a8b753c 100644 --- a/test/std/numerics/complex.number/complex.transcendentals/tanh.pass.cpp +++ b/test/std/numerics/complex.number/complex.transcendentals/tanh.pass.cpp @@ -36,55 +36,55 @@ void test_edges() { typedef std::complex<double> C; const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = tanh(x[i]); - if (x[i].real() == 0 && x[i].imag() == 0) + std::complex<double> r = tanh(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { assert(r.real() == 0); - assert(std::signbit(r.real()) == std::signbit(x[i].real())); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (std::isfinite(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isfinite(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isinf(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) { assert(r.real() == 1); assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(sin(2*x[i].imag()))); + assert(std::signbit(r.imag()) == std::signbit(sin(2*testcases[i].imag()))); } - else if (std::isinf(x[i].real()) && std::isinf(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(r.real() == 1); assert(r.imag() == 0); } - else if (std::isinf(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(r.real() == 1); assert(r.imag() == 0); } - else if (std::isnan(x[i].real()) && x[i].imag() == 0) + else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) { assert(std::isnan(r.real())); assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(x[i].imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } - else if (std::isnan(x[i].real()) && std::isfinite(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); } - else if (std::isnan(x[i].real()) && std::isnan(x[i].imag())) + else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { assert(std::isnan(r.real())); assert(std::isnan(r.imag())); diff --git a/test/std/numerics/complex.number/complex.value.ops/abs.pass.cpp b/test/std/numerics/complex.number/complex.value.ops/abs.pass.cpp index 5d841d6ee9f10..7a0e3bd700722 100644 --- a/test/std/numerics/complex.number/complex.value.ops/abs.pass.cpp +++ b/test/std/numerics/complex.number/complex.value.ops/abs.pass.cpp @@ -28,11 +28,11 @@ test() void test_edges() { - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - double r = abs(x[i]); - switch (classify(x[i])) + double r = abs(testcases[i]); + switch (classify(testcases[i])) { case zero: assert(r == 0); diff --git a/test/std/numerics/complex.number/complex.value.ops/arg.pass.cpp b/test/std/numerics/complex.number/complex.value.ops/arg.pass.cpp index a7da456b979c1..78f2781b76e24 100644 --- a/test/std/numerics/complex.number/complex.value.ops/arg.pass.cpp +++ b/test/std/numerics/complex.number/complex.value.ops/arg.pass.cpp @@ -29,42 +29,42 @@ test() void test_edges() { const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - double r = arg(x[i]); - if (std::isnan(x[i].real()) || std::isnan(x[i].imag())) + double r = arg(testcases[i]); + if (std::isnan(testcases[i].real()) || std::isnan(testcases[i].imag())) assert(std::isnan(r)); else { - switch (classify(x[i])) + switch (classify(testcases[i])) { case zero: - if (std::signbit(x[i].real())) + if (std::signbit(testcases[i].real())) { - if (std::signbit(x[i].imag())) + if (std::signbit(testcases[i].imag())) is_about(r, -pi); else is_about(r, pi); } else { - assert(std::signbit(x[i].imag()) == std::signbit(r)); + assert(std::signbit(testcases[i].imag()) == std::signbit(r)); } break; case non_zero: - if (x[i].real() == 0) + if (testcases[i].real() == 0) { - if (x[i].imag() < 0) + if (testcases[i].imag() < 0) is_about(r, -pi/2); else is_about(r, pi/2); } - else if (x[i].imag() == 0) + else if (testcases[i].imag() == 0) { - if (x[i].real() < 0) + if (testcases[i].real() < 0) { - if (std::signbit(x[i].imag())) + if (std::signbit(testcases[i].imag())) is_about(r, -pi); else is_about(r, pi); @@ -72,37 +72,37 @@ void test_edges() else { assert(r == 0); - assert(std::signbit(x[i].imag()) == std::signbit(r)); + assert(std::signbit(testcases[i].imag()) == std::signbit(r)); } } - else if (x[i].imag() > 0) + else if (testcases[i].imag() > 0) assert(r > 0); else assert(r < 0); break; case inf: - if (std::isinf(x[i].real()) && std::isinf(x[i].imag())) + if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { - if (x[i].real() < 0) + if (testcases[i].real() < 0) { - if (x[i].imag() > 0) + if (testcases[i].imag() > 0) is_about(r, 0.75 * pi); else is_about(r, -0.75 * pi); } else { - if (x[i].imag() > 0) + if (testcases[i].imag() > 0) is_about(r, 0.25 * pi); else is_about(r, -0.25 * pi); } } - else if (std::isinf(x[i].real())) + else if (std::isinf(testcases[i].real())) { - if (x[i].real() < 0) + if (testcases[i].real() < 0) { - if (std::signbit(x[i].imag())) + if (std::signbit(testcases[i].imag())) is_about(r, -pi); else is_about(r, pi); @@ -110,12 +110,12 @@ void test_edges() else { assert(r == 0); - assert(std::signbit(r) == std::signbit(x[i].imag())); + assert(std::signbit(r) == std::signbit(testcases[i].imag())); } } else { - if (x[i].imag() < 0) + if (testcases[i].imag() < 0) is_about(r, -pi/2); else is_about(r, pi/2); diff --git a/test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp b/test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp index 48f774e8e1c92..da7ad14bedce5 100644 --- a/test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp +++ b/test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp @@ -28,11 +28,11 @@ test() void test_edges() { - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - double r = norm(x[i]); - switch (classify(x[i])) + double r = norm(testcases[i]); + switch (classify(testcases[i])) { case zero: assert(r == 0); diff --git a/test/std/numerics/complex.number/complex.value.ops/polar.pass.cpp b/test/std/numerics/complex.number/complex.value.ops/polar.pass.cpp index a8747bd7c83b4..5e6cb0d523c25 100644 --- a/test/std/numerics/complex.number/complex.value.ops/polar.pass.cpp +++ b/test/std/numerics/complex.number/complex.value.ops/polar.pass.cpp @@ -46,11 +46,11 @@ test() void test_edges() { - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - double r = real(x[i]); - double theta = imag(x[i]); + double r = real(testcases[i]); + double theta = imag(testcases[i]); std::complex<double> z = std::polar(r, theta); switch (classify(r)) { diff --git a/test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp b/test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp index 10bf7f8576f6b..1a7e0c53f3d32 100644 --- a/test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp +++ b/test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp @@ -37,26 +37,26 @@ test() void test_edges() { - const unsigned N = sizeof(x) / sizeof(x[0]); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) { - std::complex<double> r = proj(x[i]); - switch (classify(x[i])) + std::complex<double> r = proj(testcases[i]); + switch (classify(testcases[i])) { case zero: case non_zero: - assert(r == x[i]); - assert(std::signbit(real(r)) == std::signbit(real(x[i]))); - assert(std::signbit(imag(r)) == std::signbit(imag(x[i]))); + assert(r == testcases[i]); + assert(std::signbit(real(r)) == std::signbit(real(testcases[i]))); + assert(std::signbit(imag(r)) == std::signbit(imag(testcases[i]))); break; case inf: assert(std::isinf(real(r)) && real(r) > 0); assert(imag(r) == 0); - assert(std::signbit(imag(r)) == std::signbit(imag(x[i]))); + assert(std::signbit(imag(r)) == std::signbit(imag(testcases[i]))); break; case NaN: case non_zero_nan: - assert(classify(r) == classify(x[i])); + assert(classify(r) == classify(testcases[i])); break; } } diff --git a/test/std/numerics/numarray/template.valarray/valarray.unary/not.pass.cpp b/test/std/numerics/numarray/template.valarray/valarray.unary/not.pass.cpp index 0b792c68fb940..306ea0c18470c 100644 --- a/test/std/numerics/numarray/template.valarray/valarray.unary/not.pass.cpp +++ b/test/std/numerics/numarray/template.valarray/valarray.unary/not.pass.cpp @@ -36,6 +36,6 @@ int main() std::valarray<bool> v2 = !(v + v); assert(v2.size() == v.size()); for (int i = 0; i < v2.size(); ++i) - assert(v2[i] == !2*v[i]); + assert(v2[i] == !(2 * v[i])); } } diff --git a/test/std/numerics/rand/rand.device/ctor.pass.cpp b/test/std/numerics/rand/rand.device/ctor.pass.cpp index dfeccc81e30ee..8c45bb19a0a6b 100644 --- a/test/std/numerics/rand/rand.device/ctor.pass.cpp +++ b/test/std/numerics/rand/rand.device/ctor.pass.cpp @@ -22,7 +22,13 @@ #include <random> #include <system_error> #include <cassert> + +#if !defined(_WIN32) #include <unistd.h> +#endif + +#include "test_macros.h" + bool is_valid_random_device(const std::string &token) { #if defined(_LIBCPP_USING_DEV_RANDOM) @@ -40,33 +46,20 @@ void check_random_device_valid(const std::string &token) { void check_random_device_invalid(const std::string &token) { try { std::random_device r(token); - assert(false); - } catch (const std::system_error &e) { + LIBCPP_ASSERT(false); + } catch (const std::system_error&) { } } -int main() { - { std::random_device r; } +int main() { { - int ec; - ec = close(STDIN_FILENO); - assert(!ec); - ec = close(STDOUT_FILENO); - assert(!ec); - ec = close(STDERR_FILENO); - assert(!ec); std::random_device r; } - { std::string token = "wrong file"; - if (is_valid_random_device(token)) - check_random_device_valid(token); - else - check_random_device_invalid(token); + check_random_device_invalid(token); } - { std::string token = "/dev/urandom"; if (is_valid_random_device(token)) @@ -74,7 +67,6 @@ int main() { else check_random_device_invalid(token); } - { std::string token = "/dev/random"; if (is_valid_random_device(token)) @@ -82,4 +74,19 @@ int main() { else check_random_device_invalid(token); } +#if !defined(_WIN32) +// Test that random_device(const string&) properly handles getting +// a file descriptor with the value '0'. Do this by closing the standard +// streams so that the descriptor '0' is available. + { + int ec; + ec = close(STDIN_FILENO); + assert(!ec); + ec = close(STDOUT_FILENO); + assert(!ec); + ec = close(STDERR_FILENO); + assert(!ec); + std::random_device r; + } +#endif // !defined(_WIN32) } diff --git a/test/std/numerics/rand/rand.device/eval.pass.cpp b/test/std/numerics/rand/rand.device/eval.pass.cpp index ed5361fbde754..eabcc201e0688 100644 --- a/test/std/numerics/rand/rand.device/eval.pass.cpp +++ b/test/std/numerics/rand/rand.device/eval.pass.cpp @@ -17,6 +17,8 @@ #include <random> #include <cassert> +#include "test_macros.h" + int main() { { @@ -28,9 +30,9 @@ int main() { std::random_device r("/dev/null"); r(); - assert(false); + LIBCPP_ASSERT(false); } - catch (const std::system_error& e) + catch (const std::system_error&) { } } diff --git a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/eval.pass.cpp index f071e85074788..b267c2477e919 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/eval.pass.cpp @@ -44,10 +44,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -80,10 +80,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/eval_param.pass.cpp index e03fb57f380ca..f96df82304f09 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/eval_param.pass.cpp @@ -46,10 +46,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -84,10 +84,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp index 43c6b546bdb27..88004ba4a741f 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp @@ -29,447 +29,491 @@ sqr(T x) return x * x; } -int main() +void +test1() { + typedef std::binomial_distribution<> D; + typedef std::mt19937_64 G; + G g; + D d(5, .75); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::binomial_distribution<> D; - typedef std::mt19937_64 G; - G g; - D d(5, .75); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.t() * d.p(); - double x_var = x_mean*(1-d.p()); - double x_skew = (1-2*d.p()) / std::sqrt(x_var); - double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.04); + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(30, .03125); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.t() * d.p(); - double x_var = x_mean*(1-d.p()); - double x_skew = (1-2*d.p()) / std::sqrt(x_var); - double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.t() * d.p(); + double x_var = x_mean*(1-d.p()); + double x_skew = (1-2*d.p()) / std::sqrt(x_var); + double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.04); +} + +void +test2() +{ + typedef std::binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(30, .03125); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(40, .25); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.t() * d.p(); - double x_var = x_mean*(1-d.p()); - double x_skew = (1-2*d.p()) / std::sqrt(x_var); - double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.03); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.3); + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(40, 0); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - // In this case: - // skew computes to 0./0. == nan - // kurtosis computes to 0./0. == nan - // x_skew == inf - // x_kurtosis == inf - // These tests are commented out because UBSan warns about division by 0 -// skew /= u.size() * dev * var; -// kurtosis /= u.size() * var * var; -// kurtosis -= 3; - double x_mean = d.t() * d.p(); - double x_var = x_mean*(1-d.p()); -// double x_skew = (1-2*d.p()) / std::sqrt(x_var); -// double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; - assert(mean == x_mean); - assert(var == x_var); -// assert(skew == x_skew); -// assert(kurtosis == x_kurtosis); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.t() * d.p(); + double x_var = x_mean*(1-d.p()); + double x_skew = (1-2*d.p()) / std::sqrt(x_var); + double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); +} + +void +test3() +{ + typedef std::binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(40, .25); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(40, 1); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - // In this case: - // skew computes to 0./0. == nan - // kurtosis computes to 0./0. == nan - // x_skew == -inf - // x_kurtosis == inf - // These tests are commented out because UBSan warns about division by 0 -// skew /= u.size() * dev * var; -// kurtosis /= u.size() * var * var; -// kurtosis -= 3; - double x_mean = d.t() * d.p(); - double x_var = x_mean*(1-d.p()); -// double x_skew = (1-2*d.p()) / std::sqrt(x_var); -// double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; - assert(mean == x_mean); - assert(var == x_var); -// assert(skew == x_skew); -// assert(kurtosis == x_kurtosis); + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(400, 0.5); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.t() * d.p(); - double x_var = x_mean*(1-d.p()); - double x_skew = (1-2*d.p()) / std::sqrt(x_var); - double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs(skew - x_skew) < 0.01); - assert(std::abs(kurtosis - x_kurtosis) < 0.01); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.t() * d.p(); + double x_var = x_mean*(1-d.p()); + double x_skew = (1-2*d.p()) / std::sqrt(x_var); + double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.03); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.3); +} + +void +test4() +{ + typedef std::binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(40, 0); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(1, 0.5); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.t() * d.p(); - double x_var = x_mean*(1-d.p()); - double x_skew = (1-2*d.p()) / std::sqrt(x_var); - double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs(skew - x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - const int N = 100000; - std::mt19937 gen1; - std::mt19937 gen2; + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + // In this case: + // skew computes to 0./0. == nan + // kurtosis computes to 0./0. == nan + // x_skew == inf + // x_kurtosis == inf + // These tests are commented out because UBSan warns about division by 0 +// skew /= u.size() * dev * var; +// kurtosis /= u.size() * var * var; +// kurtosis -= 3; + double x_mean = d.t() * d.p(); + double x_var = x_mean*(1-d.p()); +// double x_skew = (1-2*d.p()) / std::sqrt(x_var); +// double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; + assert(mean == x_mean); + assert(var == x_var); +// assert(skew == x_skew); +// assert(kurtosis == x_kurtosis); +} - std::binomial_distribution<> dist1(5, 0.1); - std::binomial_distribution<unsigned> dist2(5, 0.1); +void +test5() +{ + typedef std::binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(40, 1); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + // In this case: + // skew computes to 0./0. == nan + // kurtosis computes to 0./0. == nan + // x_skew == -inf + // x_kurtosis == inf + // These tests are commented out because UBSan warns about division by 0 +// skew /= u.size() * dev * var; +// kurtosis /= u.size() * var * var; +// kurtosis -= 3; + double x_mean = d.t() * d.p(); + double x_var = x_mean*(1-d.p()); +// double x_skew = (1-2*d.p()) / std::sqrt(x_var); +// double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; + assert(mean == x_mean); + assert(var == x_var); +// assert(skew == x_skew); +// assert(kurtosis == x_kurtosis); +} - for(int i = 0; i < N; ++i) - assert(dist1(gen1) == dist2(gen2)); +void +test6() +{ + typedef std::binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(400, 0.5); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(0, 0.005); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - // In this case: - // skew computes to 0./0. == nan - // kurtosis computes to 0./0. == nan - // x_skew == inf - // x_kurtosis == inf - // These tests are commented out because UBSan warns about division by 0 -// skew /= u.size() * dev * var; -// kurtosis /= u.size() * var * var; -// kurtosis -= 3; - double x_mean = d.t() * d.p(); - double x_var = x_mean*(1-d.p()); -// double x_skew = (1-2*d.p()) / std::sqrt(x_var); -// double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; - assert(mean == x_mean); - assert(var == x_var); -// assert(skew == x_skew); -// assert(kurtosis == x_kurtosis); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.t() * d.p(); + double x_var = x_mean*(1-d.p()); + double x_skew = (1-2*d.p()) / std::sqrt(x_var); + double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs(skew - x_skew) < 0.01); + assert(std::abs(kurtosis - x_kurtosis) < 0.01); +} + +void +test7() +{ + typedef std::binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(1, 0.5); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(0, 0); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - // In this case: - // skew computes to 0./0. == nan - // kurtosis computes to 0./0. == nan - // x_skew == inf - // x_kurtosis == inf - // These tests are commented out because UBSan warns about division by 0 -// skew /= u.size() * dev * var; -// kurtosis /= u.size() * var * var; -// kurtosis -= 3; - double x_mean = d.t() * d.p(); - double x_var = x_mean*(1-d.p()); -// double x_skew = (1-2*d.p()) / std::sqrt(x_var); -// double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; - assert(mean == x_mean); - assert(var == x_var); -// assert(skew == x_skew); -// assert(kurtosis == x_kurtosis); + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(0, 1); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - // In this case: - // skew computes to 0./0. == nan - // kurtosis computes to 0./0. == nan - // x_skew == -inf - // x_kurtosis == inf - // These tests are commented out because UBSan warns about division by 0 -// skew /= u.size() * dev * var; -// kurtosis /= u.size() * var * var; -// kurtosis -= 3; - double x_mean = d.t() * d.p(); - double x_var = x_mean*(1-d.p()); -// double x_skew = (1-2*d.p()) / std::sqrt(x_var); -// double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; - assert(mean == x_mean); - assert(var == x_var); -// assert(skew == x_skew); -// assert(kurtosis == x_kurtosis); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.t() * d.p(); + double x_var = x_mean*(1-d.p()); + double x_skew = (1-2*d.p()) / std::sqrt(x_var); + double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs(skew - x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); +} + +void +test8() +{ + const int N = 100000; + std::mt19937 gen1; + std::mt19937 gen2; + + std::binomial_distribution<> dist1(5, 0.1); + std::binomial_distribution<unsigned> dist2(5, 0.1); + + for(int i = 0; i < N; ++i) + assert(dist1(gen1) == dist2(gen2)); +} + +void +test9() +{ + typedef std::binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(0, 0.005); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + // In this case: + // skew computes to 0./0. == nan + // kurtosis computes to 0./0. == nan + // x_skew == inf + // x_kurtosis == inf + // These tests are commented out because UBSan warns about division by 0 +// skew /= u.size() * dev * var; +// kurtosis /= u.size() * var * var; +// kurtosis -= 3; + double x_mean = d.t() * d.p(); + double x_var = x_mean*(1-d.p()); +// double x_skew = (1-2*d.p()) / std::sqrt(x_var); +// double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; + assert(mean == x_mean); + assert(var == x_var); +// assert(skew == x_skew); +// assert(kurtosis == x_kurtosis); +} + +void +test10() +{ + typedef std::binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(0, 0); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + // In this case: + // skew computes to 0./0. == nan + // kurtosis computes to 0./0. == nan + // x_skew == inf + // x_kurtosis == inf + // These tests are commented out because UBSan warns about division by 0 +// skew /= u.size() * dev * var; +// kurtosis /= u.size() * var * var; +// kurtosis -= 3; + double x_mean = d.t() * d.p(); + double x_var = x_mean*(1-d.p()); +// double x_skew = (1-2*d.p()) / std::sqrt(x_var); +// double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; + assert(mean == x_mean); + assert(var == x_var); +// assert(skew == x_skew); +// assert(kurtosis == x_kurtosis); +} + +void +test11() +{ + typedef std::binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(0, 1); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + // In this case: + // skew computes to 0./0. == nan + // kurtosis computes to 0./0. == nan + // x_skew == -inf + // x_kurtosis == inf + // These tests are commented out because UBSan warns about division by 0 +// skew /= u.size() * dev * var; +// kurtosis /= u.size() * var * var; +// kurtosis -= 3; + double x_mean = d.t() * d.p(); + double x_var = x_mean*(1-d.p()); +// double x_skew = (1-2*d.p()) / std::sqrt(x_var); +// double x_kurtosis = (1-6*d.p()*(1-d.p())) / x_var; + assert(mean == x_mean); + assert(var == x_var); +// assert(skew == x_skew); +// assert(kurtosis == x_kurtosis); +} + +int main() +{ + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); } diff --git a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval_param.pass.cpp index 1aa66ed57ad16..092a697785139 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval_param.pass.cpp @@ -53,10 +53,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -95,10 +95,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -137,10 +137,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/eval.pass.cpp index a8ef221e3b673..4e9f9d3c044dc 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/eval.pass.cpp @@ -29,246 +29,270 @@ sqr(T x) return x * x; } -int main() +void +test1() +{ + typedef std::geometric_distribution<> D; + typedef std::mt19937 G; + G g; + D d(.03125); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = (1 - d.p()) / d.p(); + double x_var = x_mean / d.p(); + double x_skew = (2 - d.p()) / std::sqrt((1 - d.p())); + double x_kurtosis = 6 + sqr(d.p()) / (1 - d.p()); + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); +} + +void +test2() +{ + typedef std::geometric_distribution<> D; + typedef std::mt19937 G; + G g; + D d(0.05); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = (1 - d.p()) / d.p(); + double x_var = x_mean / d.p(); + double x_skew = (2 - d.p()) / std::sqrt((1 - d.p())); + double x_kurtosis = 6 + sqr(d.p()) / (1 - d.p()); + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.03); +} + +void +test3() +{ + typedef std::geometric_distribution<> D; + typedef std::minstd_rand G; + G g; + D d(.25); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = (1 - d.p()) / d.p(); + double x_var = x_mean / d.p(); + double x_skew = (2 - d.p()) / std::sqrt((1 - d.p())); + double x_kurtosis = 6 + sqr(d.p()) / (1 - d.p()); + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.02); +} + +void +test4() { + typedef std::geometric_distribution<> D; + typedef std::mt19937 G; + G g; + D d(0.5); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::geometric_distribution<> D; - typedef std::mt19937 G; - G g; - D d(.03125); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = (1 - d.p()) / d.p(); - double x_var = x_mean / d.p(); - double x_skew = (2 - d.p()) / std::sqrt((1 - d.p())); - double x_kurtosis = 6 + sqr(d.p()) / (1 - d.p()); - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::geometric_distribution<> D; - typedef std::mt19937 G; - G g; - D d(0.05); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = (1 - d.p()) / d.p(); - double x_var = x_mean / d.p(); - double x_skew = (2 - d.p()) / std::sqrt((1 - d.p())); - double x_kurtosis = 6 + sqr(d.p()) / (1 - d.p()); - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.03); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = (1 - d.p()) / d.p(); + double x_var = x_mean / d.p(); + double x_skew = (2 - d.p()) / std::sqrt((1 - d.p())); + double x_kurtosis = 6 + sqr(d.p()) / (1 - d.p()); + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.02); +} + +void +test5() +{ + typedef std::geometric_distribution<> D; + typedef std::mt19937 G; + G g; + D d(0.75); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::geometric_distribution<> D; - typedef std::minstd_rand G; - G g; - D d(.25); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = (1 - d.p()) / d.p(); - double x_var = x_mean / d.p(); - double x_skew = (2 - d.p()) / std::sqrt((1 - d.p())); - double x_kurtosis = 6 + sqr(d.p()) / (1 - d.p()); - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.02); + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::geometric_distribution<> D; - typedef std::mt19937 G; - G g; - D d(0.5); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = (1 - d.p()) / d.p(); - double x_var = x_mean / d.p(); - double x_skew = (2 - d.p()) / std::sqrt((1 - d.p())); - double x_kurtosis = 6 + sqr(d.p()) / (1 - d.p()); - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.02); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = (1 - d.p()) / d.p(); + double x_var = x_mean / d.p(); + double x_skew = (2 - d.p()) / std::sqrt((1 - d.p())); + double x_kurtosis = 6 + sqr(d.p()) / (1 - d.p()); + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.02); +} + +void +test6() +{ + typedef std::geometric_distribution<> D; + typedef std::mt19937 G; + G g; + D d(0.96875); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::geometric_distribution<> D; - typedef std::mt19937 G; - G g; - D d(0.75); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = (1 - d.p()) / d.p(); - double x_var = x_mean / d.p(); - double x_skew = (2 - d.p()) / std::sqrt((1 - d.p())); - double x_kurtosis = 6 + sqr(d.p()) / (1 - d.p()); - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.02); + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::geometric_distribution<> D; - typedef std::mt19937 G; - G g; - D d(0.96875); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = (1 - d.p()) / d.p(); - double x_var = x_mean / d.p(); - double x_skew = (2 - d.p()) / std::sqrt((1 - d.p())); - double x_kurtosis = 6 + sqr(d.p()) / (1 - d.p()); - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.02); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = (1 - d.p()) / d.p(); + double x_var = x_mean / d.p(); + double x_skew = (2 - d.p()) / std::sqrt((1 - d.p())); + double x_kurtosis = 6 + sqr(d.p()) / (1 - d.p()); + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.02); +} + +int main() +{ + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); } diff --git a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/eval_param.pass.cpp index 91dea8aa13375..c451f0130904a 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/eval_param.pass.cpp @@ -53,10 +53,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -95,10 +95,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -137,10 +137,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval.pass.cpp index 853161e9f9b74..929e6e7e6c3b1 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval.pass.cpp @@ -29,244 +29,268 @@ sqr(T x) return x * x; } -int main() +void +test1() +{ + typedef std::negative_binomial_distribution<> D; + typedef std::minstd_rand G; + G g; + D d(5, .25); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.k() * (1 - d.p()) / d.p(); + double x_var = x_mean / d.p(); + double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p())); + double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p())); + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.02); +} + +void +test2() +{ + typedef std::negative_binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(30, .03125); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.k() * (1 - d.p()) / d.p(); + double x_var = x_mean / d.p(); + double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p())); + double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p())); + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); +} + +void +test3() +{ + typedef std::negative_binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(40, .25); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.k() * (1 - d.p()) / d.p(); + double x_var = x_mean / d.p(); + double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p())); + double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p())); + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.03); +} + +void +test4() { + typedef std::negative_binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(40, 1); + const int N = 1000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::negative_binomial_distribution<> D; - typedef std::minstd_rand G; - G g; - D d(5, .25); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.k() * (1 - d.p()) / d.p(); - double x_var = x_mean / d.p(); - double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p())); - double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p())); - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.02); + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::negative_binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(30, .03125); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.k() * (1 - d.p()) / d.p(); - double x_var = x_mean / d.p(); - double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p())); - double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p())); - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.k() * (1 - d.p()) / d.p(); + double x_var = x_mean / d.p(); + double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p())); + double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p())); + assert(mean == x_mean); + assert(var == x_var); +} + +void +test5() +{ + typedef std::negative_binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(400, 0.5); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::negative_binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(40, .25); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.k() * (1 - d.p()) / d.p(); - double x_var = x_mean / d.p(); - double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p())); - double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p())); - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.03); + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::negative_binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(40, 1); - const int N = 1000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.k() * (1 - d.p()) / d.p(); - double x_var = x_mean / d.p(); - double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p())); - double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p())); - assert(mean == x_mean); - assert(var == x_var); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.k() * (1 - d.p()) / d.p(); + double x_var = x_mean / d.p(); + double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p())); + double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p())); + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.04); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.05); +} + +void +test6() +{ + typedef std::negative_binomial_distribution<> D; + typedef std::mt19937 G; + G g; + D d(1, 0.05); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::negative_binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(400, 0.5); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.k() * (1 - d.p()) / d.p(); - double x_var = x_mean / d.p(); - double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p())); - double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p())); - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.04); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.05); + D::result_type v = d(g); + assert(d.min() <= v && v <= d.max()); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), + double(0)) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::negative_binomial_distribution<> D; - typedef std::mt19937 G; - G g; - D d(1, 0.05); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v <= d.max()); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), - double(0)) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.k() * (1 - d.p()) / d.p(); - double x_var = x_mean / d.p(); - double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p())); - double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p())); - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.03); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.k() * (1 - d.p()) / d.p(); + double x_var = x_mean / d.p(); + double x_skew = (2 - d.p()) / std::sqrt(d.k() * (1 - d.p())); + double x_kurtosis = 6. / d.k() + sqr(d.p()) / (d.k() * (1 - d.p())); + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.03); +} + +int main() +{ + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); } diff --git a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval_param.pass.cpp index f2f2a07879e20..2710061a1a05d 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/eval_param.pass.cpp @@ -53,10 +53,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -95,10 +95,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -137,10 +137,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/eval.pass.cpp index 6fbdd93f8ffd0..f6bc3c73993c1 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/eval.pass.cpp @@ -51,10 +51,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -91,10 +91,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -131,10 +131,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/eval_param.pass.cpp index 548848d19f3e3..fd52a04889792 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/eval_param.pass.cpp @@ -52,10 +52,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -93,10 +93,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -134,10 +134,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval.pass.cpp index 9b111cced8a8c..2ad6784cd8783 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval.pass.cpp @@ -29,216 +29,236 @@ sqr(T x) return x * x; } -int main() +void +test1() +{ + typedef std::lognormal_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(-1./8192, 0.015625); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(v > 0); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = std::exp(d.m() + sqr(d.s())/2); + double x_var = (std::exp(sqr(d.s())) - 1) * std::exp(2*d.m() + sqr(d.s())); + double x_skew = (std::exp(sqr(d.s())) + 2) * + std::sqrt((std::exp(sqr(d.s())) - 1)); + double x_kurtosis = std::exp(4*sqr(d.s())) + 2*std::exp(3*sqr(d.s())) + + 3*std::exp(2*sqr(d.s())) - 6; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.05); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.25); +} + +void +test2() { + typedef std::lognormal_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(-1./32, 0.25); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::lognormal_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d(-1./8192, 0.015625); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(v > 0); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = std::exp(d.m() + sqr(d.s())/2); - double x_var = (std::exp(sqr(d.s())) - 1) * std::exp(2*d.m() + sqr(d.s())); - double x_skew = (std::exp(sqr(d.s())) + 2) * - std::sqrt((std::exp(sqr(d.s())) - 1)); - double x_kurtosis = std::exp(4*sqr(d.s())) + 2*std::exp(3*sqr(d.s())) + - 3*std::exp(2*sqr(d.s())) - 6; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.05); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.25); + D::result_type v = d(g); + assert(v > 0); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::lognormal_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d(-1./32, 0.25); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(v > 0); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = std::exp(d.m() + sqr(d.s())/2); - double x_var = (std::exp(sqr(d.s())) - 1) * std::exp(2*d.m() + sqr(d.s())); - double x_skew = (std::exp(sqr(d.s())) + 2) * - std::sqrt((std::exp(sqr(d.s())) - 1)); - double x_kurtosis = std::exp(4*sqr(d.s())) + 2*std::exp(3*sqr(d.s())) + - 3*std::exp(2*sqr(d.s())) - 6; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.03); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = std::exp(d.m() + sqr(d.s())/2); + double x_var = (std::exp(sqr(d.s())) - 1) * std::exp(2*d.m() + sqr(d.s())); + double x_skew = (std::exp(sqr(d.s())) + 2) * + std::sqrt((std::exp(sqr(d.s())) - 1)); + double x_kurtosis = std::exp(4*sqr(d.s())) + 2*std::exp(3*sqr(d.s())) + + 3*std::exp(2*sqr(d.s())) - 6; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.03); +} + +void +test3() +{ + typedef std::lognormal_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(-1./8, 0.5); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::lognormal_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d(-1./8, 0.5); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(v > 0); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = std::exp(d.m() + sqr(d.s())/2); - double x_var = (std::exp(sqr(d.s())) - 1) * std::exp(2*d.m() + sqr(d.s())); - double x_skew = (std::exp(sqr(d.s())) + 2) * - std::sqrt((std::exp(sqr(d.s())) - 1)); - double x_kurtosis = std::exp(4*sqr(d.s())) + 2*std::exp(3*sqr(d.s())) + - 3*std::exp(2*sqr(d.s())) - 6; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.02); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.05); + D::result_type v = d(g); + assert(v > 0); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::lognormal_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d; - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(v > 0); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = std::exp(d.m() + sqr(d.s())/2); - double x_var = (std::exp(sqr(d.s())) - 1) * std::exp(2*d.m() + sqr(d.s())); - double x_skew = (std::exp(sqr(d.s())) + 2) * - std::sqrt((std::exp(sqr(d.s())) - 1)); - double x_kurtosis = std::exp(4*sqr(d.s())) + 2*std::exp(3*sqr(d.s())) + - 3*std::exp(2*sqr(d.s())) - 6; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.02); - assert(std::abs((skew - x_skew) / x_skew) < 0.08); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.4); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = std::exp(d.m() + sqr(d.s())/2); + double x_var = (std::exp(sqr(d.s())) - 1) * std::exp(2*d.m() + sqr(d.s())); + double x_skew = (std::exp(sqr(d.s())) + 2) * + std::sqrt((std::exp(sqr(d.s())) - 1)); + double x_kurtosis = std::exp(4*sqr(d.s())) + 2*std::exp(3*sqr(d.s())) + + 3*std::exp(2*sqr(d.s())) - 6; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.02); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.05); +} + +void +test4() +{ + typedef std::lognormal_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d; + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::lognormal_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d(-0.78125, 1.25); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(v > 0); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = std::exp(d.m() + sqr(d.s())/2); - double x_var = (std::exp(sqr(d.s())) - 1) * std::exp(2*d.m() + sqr(d.s())); - double x_skew = (std::exp(sqr(d.s())) + 2) * - std::sqrt((std::exp(sqr(d.s())) - 1)); - double x_kurtosis = std::exp(4*sqr(d.s())) + 2*std::exp(3*sqr(d.s())) + - 3*std::exp(2*sqr(d.s())) - 6; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.04); - assert(std::abs((skew - x_skew) / x_skew) < 0.2); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.7); + D::result_type v = d(g); + assert(v > 0); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = std::exp(d.m() + sqr(d.s())/2); + double x_var = (std::exp(sqr(d.s())) - 1) * std::exp(2*d.m() + sqr(d.s())); + double x_skew = (std::exp(sqr(d.s())) + 2) * + std::sqrt((std::exp(sqr(d.s())) - 1)); + double x_kurtosis = std::exp(4*sqr(d.s())) + 2*std::exp(3*sqr(d.s())) + + 3*std::exp(2*sqr(d.s())) - 6; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.02); + assert(std::abs((skew - x_skew) / x_skew) < 0.08); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.4); +} + +void +test5() +{ + typedef std::lognormal_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(-0.78125, 1.25); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(v > 0); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = std::exp(d.m() + sqr(d.s())/2); + double x_var = (std::exp(sqr(d.s())) - 1) * std::exp(2*d.m() + sqr(d.s())); + double x_skew = (std::exp(sqr(d.s())) + 2) * + std::sqrt((std::exp(sqr(d.s())) - 1)); + double x_kurtosis = std::exp(4*sqr(d.s())) + 2*std::exp(3*sqr(d.s())) + + 3*std::exp(2*sqr(d.s())) - 6; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.04); + assert(std::abs((skew - x_skew) / x_skew) < 0.2); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.7); +} + +int main() +{ + test1(); + test2(); + test3(); + test4(); + test5(); } diff --git a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval_param.pass.cpp index 283403ea1a0d9..8f397fcab096f 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval_param.pass.cpp @@ -29,222 +29,241 @@ sqr(T x) return x * x; } -int main() +void +test1() { + typedef std::lognormal_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d; + P p(-1./8192, 0.015625); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g, p); + assert(v > 0); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = std::exp(p.m() + sqr(p.s())/2); + double x_var = (std::exp(sqr(p.s())) - 1) * std::exp(2*p.m() + sqr(p.s())); + double x_skew = (std::exp(sqr(p.s())) + 2) * + std::sqrt((std::exp(sqr(p.s())) - 1)); + double x_kurtosis = std::exp(4*sqr(p.s())) + 2*std::exp(3*sqr(p.s())) + + 3*std::exp(2*sqr(p.s())) - 6; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.05); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.25); +} + +void +test2() +{ + typedef std::lognormal_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d; + P p(-1./32, 0.25); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g, p); + assert(v > 0); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = std::exp(p.m() + sqr(p.s())/2); + double x_var = (std::exp(sqr(p.s())) - 1) * std::exp(2*p.m() + sqr(p.s())); + double x_skew = (std::exp(sqr(p.s())) + 2) * + std::sqrt((std::exp(sqr(p.s())) - 1)); + double x_kurtosis = std::exp(4*sqr(p.s())) + 2*std::exp(3*sqr(p.s())) + + 3*std::exp(2*sqr(p.s())) - 6; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.03); +} +void +test3() +{ + typedef std::lognormal_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d; + P p(-1./8, 0.5); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::lognormal_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d; - P p(-1./8192, 0.015625); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g, p); - assert(v > 0); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = std::exp(p.m() + sqr(p.s())/2); - double x_var = (std::exp(sqr(p.s())) - 1) * std::exp(2*p.m() + sqr(p.s())); - double x_skew = (std::exp(sqr(p.s())) + 2) * - std::sqrt((std::exp(sqr(p.s())) - 1)); - double x_kurtosis = std::exp(4*sqr(p.s())) + 2*std::exp(3*sqr(p.s())) + - 3*std::exp(2*sqr(p.s())) - 6; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.05); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.25); + D::result_type v = d(g, p); + assert(v > 0); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::lognormal_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d; - P p(-1./32, 0.25); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g, p); - assert(v > 0); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = std::exp(p.m() + sqr(p.s())/2); - double x_var = (std::exp(sqr(p.s())) - 1) * std::exp(2*p.m() + sqr(p.s())); - double x_skew = (std::exp(sqr(p.s())) + 2) * - std::sqrt((std::exp(sqr(p.s())) - 1)); - double x_kurtosis = std::exp(4*sqr(p.s())) + 2*std::exp(3*sqr(p.s())) + - 3*std::exp(2*sqr(p.s())) - 6; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.03); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = std::exp(p.m() + sqr(p.s())/2); + double x_var = (std::exp(sqr(p.s())) - 1) * std::exp(2*p.m() + sqr(p.s())); + double x_skew = (std::exp(sqr(p.s())) + 2) * + std::sqrt((std::exp(sqr(p.s())) - 1)); + double x_kurtosis = std::exp(4*sqr(p.s())) + 2*std::exp(3*sqr(p.s())) + + 3*std::exp(2*sqr(p.s())) - 6; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.02); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.05); +} + +void +test4() +{ + typedef std::lognormal_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(3, 4); + P p; + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::lognormal_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d; - P p(-1./8, 0.5); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g, p); - assert(v > 0); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = std::exp(p.m() + sqr(p.s())/2); - double x_var = (std::exp(sqr(p.s())) - 1) * std::exp(2*p.m() + sqr(p.s())); - double x_skew = (std::exp(sqr(p.s())) + 2) * - std::sqrt((std::exp(sqr(p.s())) - 1)); - double x_kurtosis = std::exp(4*sqr(p.s())) + 2*std::exp(3*sqr(p.s())) + - 3*std::exp(2*sqr(p.s())) - 6; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.02); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.05); + D::result_type v = d(g, p); + assert(v > 0); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::lognormal_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d(3, 4); - P p; - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g, p); - assert(v > 0); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = std::exp(p.m() + sqr(p.s())/2); - double x_var = (std::exp(sqr(p.s())) - 1) * std::exp(2*p.m() + sqr(p.s())); - double x_skew = (std::exp(sqr(p.s())) + 2) * - std::sqrt((std::exp(sqr(p.s())) - 1)); - double x_kurtosis = std::exp(4*sqr(p.s())) + 2*std::exp(3*sqr(p.s())) + - 3*std::exp(2*sqr(p.s())) - 6; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.02); - assert(std::abs((skew - x_skew) / x_skew) < 0.08); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.4); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = std::exp(p.m() + sqr(p.s())/2); + double x_var = (std::exp(sqr(p.s())) - 1) * std::exp(2*p.m() + sqr(p.s())); + double x_skew = (std::exp(sqr(p.s())) + 2) * + std::sqrt((std::exp(sqr(p.s())) - 1)); + double x_kurtosis = std::exp(4*sqr(p.s())) + 2*std::exp(3*sqr(p.s())) + + 3*std::exp(2*sqr(p.s())) - 6; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.02); + assert(std::abs((skew - x_skew) / x_skew) < 0.08); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.4); +} + +void +test5() +{ + typedef std::lognormal_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d; + P p(-0.78125, 1.25); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::lognormal_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d; - P p(-0.78125, 1.25); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g, p); - assert(v > 0); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = std::exp(p.m() + sqr(p.s())/2); - double x_var = (std::exp(sqr(p.s())) - 1) * std::exp(2*p.m() + sqr(p.s())); - double x_skew = (std::exp(sqr(p.s())) + 2) * - std::sqrt((std::exp(sqr(p.s())) - 1)); - double x_kurtosis = std::exp(4*sqr(p.s())) + 2*std::exp(3*sqr(p.s())) + - 3*std::exp(2*sqr(p.s())) - 6; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.04); - assert(std::abs((skew - x_skew) / x_skew) < 0.2); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.7); + D::result_type v = d(g, p); + assert(v > 0); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = std::exp(p.m() + sqr(p.s())/2); + double x_var = (std::exp(sqr(p.s())) - 1) * std::exp(2*p.m() + sqr(p.s())); + double x_skew = (std::exp(sqr(p.s())) + 2) * + std::sqrt((std::exp(sqr(p.s())) - 1)); + double x_kurtosis = std::exp(4*sqr(p.s())) + 2*std::exp(3*sqr(p.s())) + + 3*std::exp(2*sqr(p.s())) - 6; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.04); + assert(std::abs((skew - x_skew) / x_skew) < 0.2); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.7); +} + +int main() +{ + test1(); + test2(); + test3(); + test4(); + test5(); } diff --git a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/eval.pass.cpp index 95d0272dbc32c..69f7863977114 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/eval.pass.cpp @@ -47,10 +47,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/eval_param.pass.cpp index 20c3a44f13e1f..af9c547cb7f98 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/eval_param.pass.cpp @@ -48,10 +48,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/eval.pass.cpp index ef6b37e9f9cc7..9210e8a8d3500 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/eval.pass.cpp @@ -47,10 +47,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -83,10 +83,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -119,10 +119,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/eval_param.pass.cpp index 70bc29e3ad133..93053f0a36b71 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/eval_param.pass.cpp @@ -48,10 +48,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -85,10 +85,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -122,10 +122,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/eval.pass.cpp index b2fe52676e7e0..42965b0e6ab2b 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/eval.pass.cpp @@ -51,10 +51,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -91,10 +91,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -131,10 +131,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/eval_param.pass.cpp index 9879e63a33e96..e7de18fdb4340 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/eval_param.pass.cpp @@ -52,10 +52,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/eval.pass.cpp index 6390acef89414..3f1b331889e54 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/eval.pass.cpp @@ -29,162 +29,178 @@ sqr(T x) return x * x; } -int main() +void +test1() +{ + typedef std::extreme_value_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(0.5, 2); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.a() + d.b() * 0.577215665; + double x_var = sqr(d.b()) * 1.644934067; + double x_skew = 1.139547; + double x_kurtosis = 12./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); +} + +void +test2() +{ + typedef std::extreme_value_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(1, 2); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.a() + d.b() * 0.577215665; + double x_var = sqr(d.b()) * 1.644934067; + double x_skew = 1.139547; + double x_kurtosis = 12./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); +} + +void +test3() { + typedef std::extreme_value_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(1.5, 3); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::extreme_value_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d(0.5, 2); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.a() + d.b() * 0.577215665; - double x_var = sqr(d.b()) * 1.644934067; - double x_skew = 1.139547; - double x_kurtosis = 12./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + D::result_type v = d(g); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::extreme_value_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d(1, 2); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.a() + d.b() * 0.577215665; - double x_var = sqr(d.b()) * 1.644934067; - double x_skew = 1.139547; - double x_kurtosis = 12./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.a() + d.b() * 0.577215665; + double x_var = sqr(d.b()) * 1.644934067; + double x_skew = 1.139547; + double x_kurtosis = 12./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); +} + +void +test4() +{ + typedef std::extreme_value_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(3, 4); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::extreme_value_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d(1.5, 3); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.a() + d.b() * 0.577215665; - double x_var = sqr(d.b()) * 1.644934067; - double x_skew = 1.139547; - double x_kurtosis = 12./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + D::result_type v = d(g); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::extreme_value_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d(3, 4); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = d.a() + d.b() * 0.577215665; - double x_var = sqr(d.b()) * 1.644934067; - double x_skew = 1.139547; - double x_kurtosis = 12./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = d.a() + d.b() * 0.577215665; + double x_var = sqr(d.b()) * 1.644934067; + double x_skew = 1.139547; + double x_kurtosis = 12./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); +} + +int main() +{ + test1(); + test2(); + test3(); + test4(); } diff --git a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/eval_param.pass.cpp index 6152cce8f4f82..21bf774228f88 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/eval_param.pass.cpp @@ -29,166 +29,182 @@ sqr(T x) return x * x; } -int main() +void +test1() +{ + typedef std::extreme_value_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(-0.5, 1); + P p(0.5, 2); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g, p); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = p.a() + p.b() * 0.577215665; + double x_var = sqr(p.b()) * 1.644934067; + double x_skew = 1.139547; + double x_kurtosis = 12./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); +} + +void +test2() +{ + typedef std::extreme_value_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(-0.5, 1); + P p(1, 2); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g, p); + u.push_back(v); + } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) + { + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; + } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = p.a() + p.b() * 0.577215665; + double x_var = sqr(p.b()) * 1.644934067; + double x_skew = 1.139547; + double x_kurtosis = 12./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); +} + +void +test3() { + typedef std::extreme_value_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(-0.5, 1); + P p(1.5, 3); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::extreme_value_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d(-0.5, 1); - P p(0.5, 2); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g, p); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = p.a() + p.b() * 0.577215665; - double x_var = sqr(p.b()) * 1.644934067; - double x_skew = 1.139547; - double x_kurtosis = 12./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + D::result_type v = d(g, p); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::extreme_value_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d(-0.5, 1); - P p(1, 2); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g, p); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = p.a() + p.b() * 0.577215665; - double x_var = sqr(p.b()) * 1.644934067; - double x_skew = 1.139547; - double x_kurtosis = 12./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = p.a() + p.b() * 0.577215665; + double x_var = sqr(p.b()) * 1.644934067; + double x_skew = 1.139547; + double x_kurtosis = 12./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); +} + +void +test4() +{ + typedef std::extreme_value_distribution<> D; + typedef D::param_type P; + typedef std::mt19937 G; + G g; + D d(-0.5, 1); + P p(3, 4); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::extreme_value_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d(-0.5, 1); - P p(1.5, 3); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g, p); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = p.a() + p.b() * 0.577215665; - double x_var = sqr(p.b()) * 1.644934067; - double x_skew = 1.139547; - double x_kurtosis = 12./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + D::result_type v = d(g, p); + u.push_back(v); } + double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); + double var = 0; + double skew = 0; + double kurtosis = 0; + for (int i = 0; i < u.size(); ++i) { - typedef std::extreme_value_distribution<> D; - typedef D::param_type P; - typedef std::mt19937 G; - G g; - D d(-0.5, 1); - P p(3, 4); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g, p); - u.push_back(v); - } - double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size(); - double var = 0; - double skew = 0; - double kurtosis = 0; - for (int i = 0; i < u.size(); ++i) - { - double d = (u[i] - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= u.size(); - double dev = std::sqrt(var); - skew /= u.size() * dev * var; - kurtosis /= u.size() * var * var; - kurtosis -= 3; - double x_mean = p.a() + p.b() * 0.577215665; - double x_var = sqr(p.b()) * 1.644934067; - double x_skew = 1.139547; - double x_kurtosis = 12./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs((skew - x_skew) / x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= u.size(); + double dev = std::sqrt(var); + skew /= u.size() * dev * var; + kurtosis /= u.size() * var * var; + kurtosis -= 3; + double x_mean = p.a() + p.b() * 0.577215665; + double x_var = sqr(p.b()) * 1.644934067; + double x_skew = 1.139547; + double x_kurtosis = 12./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs((skew - x_skew) / x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); +} + +int main() +{ + test1(); + test2(); + test3(); + test4(); } diff --git a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/eval.pass.cpp index 7c26cc8a1c472..7c23630ed1e1c 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/eval.pass.cpp @@ -51,10 +51,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -91,10 +91,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -131,10 +131,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/eval_param.pass.cpp index 8ed39df819d74..54a89b6b3f408 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/eval_param.pass.cpp @@ -52,10 +52,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -93,10 +93,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -134,10 +134,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/eval.pass.cpp index f5598978bf0ad..a475624a58a8a 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/eval.pass.cpp @@ -50,10 +50,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -89,10 +89,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -128,10 +128,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/eval_param.pass.cpp index c3bbdeb0ed6c7..d24fbd9f9cf5e 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/eval_param.pass.cpp @@ -52,10 +52,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -93,10 +93,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -134,10 +134,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/eval.pass.cpp index e414932dc8700..cfec8c0d81e11 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/eval.pass.cpp @@ -51,10 +51,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -95,10 +95,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -139,10 +139,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/eval_param.pass.cpp index 6da705eb26c74..a19654dbd575c 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/eval_param.pass.cpp @@ -52,10 +52,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -97,10 +97,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -142,10 +142,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.pconst/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.pconst/eval.pass.cpp index 5d14b3612b2e0..3111912ec29ce 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.pconst/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.pconst/eval.pass.cpp @@ -20,6 +20,7 @@ #include <vector> #include <iterator> #include <numeric> +#include <algorithm> // for sort #include <cassert> template <class T> @@ -30,666 +31,710 @@ sqr(T x) return x*x; } -int main() +void +test1() { + typedef std::piecewise_constant_distribution<> D; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16, 17}; + double p[] = {25, 62.5, 12.5}; + const size_t Np = sizeof(p) / sizeof(p[0]); + D d(b, b+Np+1, p); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::piecewise_constant_distribution<> D; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16, 17}; - double p[] = {25, 62.5, 12.5}; - const size_t Np = sizeof(p) / sizeof(p[0]); - D d(b, b+Np+1, p); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::vector<double> prob(std::begin(p), std::end(p)); - double s = std::accumulate(prob.begin(), prob.end(), 0.0); - for (int i = 0; i < prob.size(); ++i) - prob[i] /= s; - std::sort(u.begin(), u.end()); - for (int i = 0; i < Np; ++i) + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::vector<double> prob(std::begin(p), std::end(p)); + double s = std::accumulate(prob.begin(), prob.end(), 0.0); + for (int i = 0; i < prob.size(); ++i) + prob[i] /= s; + std::sort(u.begin(), u.end()); + for (int i = 0; i < Np; ++i) + { + typedef std::vector<D::result_type>::iterator I; + I lb = std::lower_bound(u.begin(), u.end(), b[i]); + I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); + const size_t Ni = ub - lb; + if (prob[i] == 0) + assert(Ni == 0); + else { - typedef std::vector<D::result_type>::iterator I; - I lb = std::lower_bound(u.begin(), u.end(), b[i]); - I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); - const size_t Ni = ub - lb; - if (prob[i] == 0) - assert(Ni == 0); - else + assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); + double mean = std::accumulate(lb, ub, 0.0) / Ni; + double var = 0; + double skew = 0; + double kurtosis = 0; + for (I j = lb; j != ub; ++j) { - assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); - double mean = std::accumulate(lb, ub, 0.0) / Ni; - double var = 0; - double skew = 0; - double kurtosis = 0; - for (I j = lb; j != ub; ++j) - { - double d = (*j - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= Ni; - double dev = std::sqrt(var); - skew /= Ni * dev * var; - kurtosis /= Ni * var * var; - kurtosis -= 3; - double x_mean = (b[i+1] + b[i]) / 2; - double x_var = sqr(b[i+1] - b[i]) / 12; - double x_skew = 0; - double x_kurtosis = -6./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs(skew - x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (*j - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= Ni; + double dev = std::sqrt(var); + skew /= Ni * dev * var; + kurtosis /= Ni * var * var; + kurtosis -= 3; + double x_mean = (b[i+1] + b[i]) / 2; + double x_var = sqr(b[i+1] - b[i]) / 12; + double x_skew = 0; + double x_kurtosis = -6./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs(skew - x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); } } +} + +void +test2() +{ + typedef std::piecewise_constant_distribution<> D; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16, 17}; + double p[] = {0, 62.5, 12.5}; + const size_t Np = sizeof(p) / sizeof(p[0]); + D d(b, b+Np+1, p); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::piecewise_constant_distribution<> D; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16, 17}; - double p[] = {0, 62.5, 12.5}; - const size_t Np = sizeof(p) / sizeof(p[0]); - D d(b, b+Np+1, p); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::vector<double> prob(std::begin(p), std::end(p)); - double s = std::accumulate(prob.begin(), prob.end(), 0.0); - for (int i = 0; i < prob.size(); ++i) - prob[i] /= s; - std::sort(u.begin(), u.end()); - for (int i = 0; i < Np; ++i) + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::vector<double> prob(std::begin(p), std::end(p)); + double s = std::accumulate(prob.begin(), prob.end(), 0.0); + for (int i = 0; i < prob.size(); ++i) + prob[i] /= s; + std::sort(u.begin(), u.end()); + for (int i = 0; i < Np; ++i) + { + typedef std::vector<D::result_type>::iterator I; + I lb = std::lower_bound(u.begin(), u.end(), b[i]); + I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); + const size_t Ni = ub - lb; + if (prob[i] == 0) + assert(Ni == 0); + else { - typedef std::vector<D::result_type>::iterator I; - I lb = std::lower_bound(u.begin(), u.end(), b[i]); - I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); - const size_t Ni = ub - lb; - if (prob[i] == 0) - assert(Ni == 0); - else + assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); + double mean = std::accumulate(lb, ub, 0.0) / Ni; + double var = 0; + double skew = 0; + double kurtosis = 0; + for (I j = lb; j != ub; ++j) { - assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); - double mean = std::accumulate(lb, ub, 0.0) / Ni; - double var = 0; - double skew = 0; - double kurtosis = 0; - for (I j = lb; j != ub; ++j) - { - double d = (*j - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= Ni; - double dev = std::sqrt(var); - skew /= Ni * dev * var; - kurtosis /= Ni * var * var; - kurtosis -= 3; - double x_mean = (b[i+1] + b[i]) / 2; - double x_var = sqr(b[i+1] - b[i]) / 12; - double x_skew = 0; - double x_kurtosis = -6./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs(skew - x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (*j - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= Ni; + double dev = std::sqrt(var); + skew /= Ni * dev * var; + kurtosis /= Ni * var * var; + kurtosis -= 3; + double x_mean = (b[i+1] + b[i]) / 2; + double x_var = sqr(b[i+1] - b[i]) / 12; + double x_skew = 0; + double x_kurtosis = -6./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs(skew - x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); } } +} + +void +test3() +{ + typedef std::piecewise_constant_distribution<> D; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16, 17}; + double p[] = {25, 0, 12.5}; + const size_t Np = sizeof(p) / sizeof(p[0]); + D d(b, b+Np+1, p); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::vector<double> prob(std::begin(p), std::end(p)); + double s = std::accumulate(prob.begin(), prob.end(), 0.0); + for (int i = 0; i < prob.size(); ++i) + prob[i] /= s; + std::sort(u.begin(), u.end()); + for (int i = 0; i < Np; ++i) { - typedef std::piecewise_constant_distribution<> D; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16, 17}; - double p[] = {25, 0, 12.5}; - const size_t Np = sizeof(p) / sizeof(p[0]); - D d(b, b+Np+1, p); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) + typedef std::vector<D::result_type>::iterator I; + I lb = std::lower_bound(u.begin(), u.end(), b[i]); + I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); + const size_t Ni = ub - lb; + if (prob[i] == 0) + assert(Ni == 0); + else { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::vector<double> prob(std::begin(p), std::end(p)); - double s = std::accumulate(prob.begin(), prob.end(), 0.0); - for (int i = 0; i < prob.size(); ++i) - prob[i] /= s; - std::sort(u.begin(), u.end()); - for (int i = 0; i < Np; ++i) - { - typedef std::vector<D::result_type>::iterator I; - I lb = std::lower_bound(u.begin(), u.end(), b[i]); - I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); - const size_t Ni = ub - lb; - if (prob[i] == 0) - assert(Ni == 0); - else + assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); + double mean = std::accumulate(lb, ub, 0.0) / Ni; + double var = 0; + double skew = 0; + double kurtosis = 0; + for (I j = lb; j != ub; ++j) { - assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); - double mean = std::accumulate(lb, ub, 0.0) / Ni; - double var = 0; - double skew = 0; - double kurtosis = 0; - for (I j = lb; j != ub; ++j) - { - double d = (*j - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= Ni; - double dev = std::sqrt(var); - skew /= Ni * dev * var; - kurtosis /= Ni * var * var; - kurtosis -= 3; - double x_mean = (b[i+1] + b[i]) / 2; - double x_var = sqr(b[i+1] - b[i]) / 12; - double x_skew = 0; - double x_kurtosis = -6./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs(skew - x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (*j - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= Ni; + double dev = std::sqrt(var); + skew /= Ni * dev * var; + kurtosis /= Ni * var * var; + kurtosis -= 3; + double x_mean = (b[i+1] + b[i]) / 2; + double x_var = sqr(b[i+1] - b[i]) / 12; + double x_skew = 0; + double x_kurtosis = -6./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs(skew - x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); } } +} + +void +test4() +{ + typedef std::piecewise_constant_distribution<> D; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16, 17}; + double p[] = {25, 62.5, 0}; + const size_t Np = sizeof(p) / sizeof(p[0]); + D d(b, b+Np+1, p); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::vector<double> prob(std::begin(p), std::end(p)); + double s = std::accumulate(prob.begin(), prob.end(), 0.0); + for (int i = 0; i < prob.size(); ++i) + prob[i] /= s; + std::sort(u.begin(), u.end()); + for (int i = 0; i < Np; ++i) { - typedef std::piecewise_constant_distribution<> D; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16, 17}; - double p[] = {25, 62.5, 0}; - const size_t Np = sizeof(p) / sizeof(p[0]); - D d(b, b+Np+1, p); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::vector<double> prob(std::begin(p), std::end(p)); - double s = std::accumulate(prob.begin(), prob.end(), 0.0); - for (int i = 0; i < prob.size(); ++i) - prob[i] /= s; - std::sort(u.begin(), u.end()); - for (int i = 0; i < Np; ++i) + typedef std::vector<D::result_type>::iterator I; + I lb = std::lower_bound(u.begin(), u.end(), b[i]); + I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); + const size_t Ni = ub - lb; + if (prob[i] == 0) + assert(Ni == 0); + else { - typedef std::vector<D::result_type>::iterator I; - I lb = std::lower_bound(u.begin(), u.end(), b[i]); - I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); - const size_t Ni = ub - lb; - if (prob[i] == 0) - assert(Ni == 0); - else + assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); + double mean = std::accumulate(lb, ub, 0.0) / Ni; + double var = 0; + double skew = 0; + double kurtosis = 0; + for (I j = lb; j != ub; ++j) { - assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); - double mean = std::accumulate(lb, ub, 0.0) / Ni; - double var = 0; - double skew = 0; - double kurtosis = 0; - for (I j = lb; j != ub; ++j) - { - double d = (*j - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= Ni; - double dev = std::sqrt(var); - skew /= Ni * dev * var; - kurtosis /= Ni * var * var; - kurtosis -= 3; - double x_mean = (b[i+1] + b[i]) / 2; - double x_var = sqr(b[i+1] - b[i]) / 12; - double x_skew = 0; - double x_kurtosis = -6./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs(skew - x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (*j - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= Ni; + double dev = std::sqrt(var); + skew /= Ni * dev * var; + kurtosis /= Ni * var * var; + kurtosis -= 3; + double x_mean = (b[i+1] + b[i]) / 2; + double x_var = sqr(b[i+1] - b[i]) / 12; + double x_skew = 0; + double x_kurtosis = -6./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs(skew - x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); } } +} + +void +test5() +{ + typedef std::piecewise_constant_distribution<> D; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16, 17}; + double p[] = {25, 0, 0}; + const size_t Np = sizeof(p) / sizeof(p[0]); + D d(b, b+Np+1, p); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::piecewise_constant_distribution<> D; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16, 17}; - double p[] = {25, 0, 0}; - const size_t Np = sizeof(p) / sizeof(p[0]); - D d(b, b+Np+1, p); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::vector<double> prob(std::begin(p), std::end(p)); - double s = std::accumulate(prob.begin(), prob.end(), 0.0); - for (int i = 0; i < prob.size(); ++i) - prob[i] /= s; - std::sort(u.begin(), u.end()); - for (int i = 0; i < Np; ++i) + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::vector<double> prob(std::begin(p), std::end(p)); + double s = std::accumulate(prob.begin(), prob.end(), 0.0); + for (int i = 0; i < prob.size(); ++i) + prob[i] /= s; + std::sort(u.begin(), u.end()); + for (int i = 0; i < Np; ++i) + { + typedef std::vector<D::result_type>::iterator I; + I lb = std::lower_bound(u.begin(), u.end(), b[i]); + I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); + const size_t Ni = ub - lb; + if (prob[i] == 0) + assert(Ni == 0); + else { - typedef std::vector<D::result_type>::iterator I; - I lb = std::lower_bound(u.begin(), u.end(), b[i]); - I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); - const size_t Ni = ub - lb; - if (prob[i] == 0) - assert(Ni == 0); - else + assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); + double mean = std::accumulate(lb, ub, 0.0) / Ni; + double var = 0; + double skew = 0; + double kurtosis = 0; + for (I j = lb; j != ub; ++j) { - assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); - double mean = std::accumulate(lb, ub, 0.0) / Ni; - double var = 0; - double skew = 0; - double kurtosis = 0; - for (I j = lb; j != ub; ++j) - { - double d = (*j - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= Ni; - double dev = std::sqrt(var); - skew /= Ni * dev * var; - kurtosis /= Ni * var * var; - kurtosis -= 3; - double x_mean = (b[i+1] + b[i]) / 2; - double x_var = sqr(b[i+1] - b[i]) / 12; - double x_skew = 0; - double x_kurtosis = -6./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs(skew - x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (*j - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= Ni; + double dev = std::sqrt(var); + skew /= Ni * dev * var; + kurtosis /= Ni * var * var; + kurtosis -= 3; + double x_mean = (b[i+1] + b[i]) / 2; + double x_var = sqr(b[i+1] - b[i]) / 12; + double x_skew = 0; + double x_kurtosis = -6./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs(skew - x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); } } +} + +void +test6() +{ + typedef std::piecewise_constant_distribution<> D; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16, 17}; + double p[] = {0, 25, 0}; + const size_t Np = sizeof(p) / sizeof(p[0]); + D d(b, b+Np+1, p); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::vector<double> prob(std::begin(p), std::end(p)); + double s = std::accumulate(prob.begin(), prob.end(), 0.0); + for (int i = 0; i < prob.size(); ++i) + prob[i] /= s; + std::sort(u.begin(), u.end()); + for (int i = 0; i < Np; ++i) { - typedef std::piecewise_constant_distribution<> D; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16, 17}; - double p[] = {0, 25, 0}; - const size_t Np = sizeof(p) / sizeof(p[0]); - D d(b, b+Np+1, p); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::vector<double> prob(std::begin(p), std::end(p)); - double s = std::accumulate(prob.begin(), prob.end(), 0.0); - for (int i = 0; i < prob.size(); ++i) - prob[i] /= s; - std::sort(u.begin(), u.end()); - for (int i = 0; i < Np; ++i) + typedef std::vector<D::result_type>::iterator I; + I lb = std::lower_bound(u.begin(), u.end(), b[i]); + I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); + const size_t Ni = ub - lb; + if (prob[i] == 0) + assert(Ni == 0); + else { - typedef std::vector<D::result_type>::iterator I; - I lb = std::lower_bound(u.begin(), u.end(), b[i]); - I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); - const size_t Ni = ub - lb; - if (prob[i] == 0) - assert(Ni == 0); - else + assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); + double mean = std::accumulate(lb, ub, 0.0) / Ni; + double var = 0; + double skew = 0; + double kurtosis = 0; + for (I j = lb; j != ub; ++j) { - assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); - double mean = std::accumulate(lb, ub, 0.0) / Ni; - double var = 0; - double skew = 0; - double kurtosis = 0; - for (I j = lb; j != ub; ++j) - { - double d = (*j - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= Ni; - double dev = std::sqrt(var); - skew /= Ni * dev * var; - kurtosis /= Ni * var * var; - kurtosis -= 3; - double x_mean = (b[i+1] + b[i]) / 2; - double x_var = sqr(b[i+1] - b[i]) / 12; - double x_skew = 0; - double x_kurtosis = -6./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs(skew - x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (*j - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= Ni; + double dev = std::sqrt(var); + skew /= Ni * dev * var; + kurtosis /= Ni * var * var; + kurtosis -= 3; + double x_mean = (b[i+1] + b[i]) / 2; + double x_var = sqr(b[i+1] - b[i]) / 12; + double x_skew = 0; + double x_kurtosis = -6./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs(skew - x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); } } +} + +void +test7() +{ + typedef std::piecewise_constant_distribution<> D; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16, 17}; + double p[] = {0, 0, 1}; + const size_t Np = sizeof(p) / sizeof(p[0]); + D d(b, b+Np+1, p); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::piecewise_constant_distribution<> D; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16, 17}; - double p[] = {0, 0, 1}; - const size_t Np = sizeof(p) / sizeof(p[0]); - D d(b, b+Np+1, p); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::vector<double> prob(std::begin(p), std::end(p)); - double s = std::accumulate(prob.begin(), prob.end(), 0.0); - for (int i = 0; i < prob.size(); ++i) - prob[i] /= s; - std::sort(u.begin(), u.end()); - for (int i = 0; i < Np; ++i) + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::vector<double> prob(std::begin(p), std::end(p)); + double s = std::accumulate(prob.begin(), prob.end(), 0.0); + for (int i = 0; i < prob.size(); ++i) + prob[i] /= s; + std::sort(u.begin(), u.end()); + for (int i = 0; i < Np; ++i) + { + typedef std::vector<D::result_type>::iterator I; + I lb = std::lower_bound(u.begin(), u.end(), b[i]); + I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); + const size_t Ni = ub - lb; + if (prob[i] == 0) + assert(Ni == 0); + else { - typedef std::vector<D::result_type>::iterator I; - I lb = std::lower_bound(u.begin(), u.end(), b[i]); - I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); - const size_t Ni = ub - lb; - if (prob[i] == 0) - assert(Ni == 0); - else + assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); + double mean = std::accumulate(lb, ub, 0.0) / Ni; + double var = 0; + double skew = 0; + double kurtosis = 0; + for (I j = lb; j != ub; ++j) { - assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); - double mean = std::accumulate(lb, ub, 0.0) / Ni; - double var = 0; - double skew = 0; - double kurtosis = 0; - for (I j = lb; j != ub; ++j) - { - double d = (*j - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= Ni; - double dev = std::sqrt(var); - skew /= Ni * dev * var; - kurtosis /= Ni * var * var; - kurtosis -= 3; - double x_mean = (b[i+1] + b[i]) / 2; - double x_var = sqr(b[i+1] - b[i]) / 12; - double x_skew = 0; - double x_kurtosis = -6./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs(skew - x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (*j - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= Ni; + double dev = std::sqrt(var); + skew /= Ni * dev * var; + kurtosis /= Ni * var * var; + kurtosis -= 3; + double x_mean = (b[i+1] + b[i]) / 2; + double x_var = sqr(b[i+1] - b[i]) / 12; + double x_skew = 0; + double x_kurtosis = -6./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs(skew - x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); } } +} + +void +test8() +{ + typedef std::piecewise_constant_distribution<> D; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16}; + double p[] = {75, 25}; + const size_t Np = sizeof(p) / sizeof(p[0]); + D d(b, b+Np+1, p); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::vector<double> prob(std::begin(p), std::end(p)); + double s = std::accumulate(prob.begin(), prob.end(), 0.0); + for (int i = 0; i < prob.size(); ++i) + prob[i] /= s; + std::sort(u.begin(), u.end()); + for (int i = 0; i < Np; ++i) { - typedef std::piecewise_constant_distribution<> D; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16}; - double p[] = {75, 25}; - const size_t Np = sizeof(p) / sizeof(p[0]); - D d(b, b+Np+1, p); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) + typedef std::vector<D::result_type>::iterator I; + I lb = std::lower_bound(u.begin(), u.end(), b[i]); + I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); + const size_t Ni = ub - lb; + if (prob[i] == 0) + assert(Ni == 0); + else { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::vector<double> prob(std::begin(p), std::end(p)); - double s = std::accumulate(prob.begin(), prob.end(), 0.0); - for (int i = 0; i < prob.size(); ++i) - prob[i] /= s; - std::sort(u.begin(), u.end()); - for (int i = 0; i < Np; ++i) - { - typedef std::vector<D::result_type>::iterator I; - I lb = std::lower_bound(u.begin(), u.end(), b[i]); - I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); - const size_t Ni = ub - lb; - if (prob[i] == 0) - assert(Ni == 0); - else + assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); + double mean = std::accumulate(lb, ub, 0.0) / Ni; + double var = 0; + double skew = 0; + double kurtosis = 0; + for (I j = lb; j != ub; ++j) { - assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); - double mean = std::accumulate(lb, ub, 0.0) / Ni; - double var = 0; - double skew = 0; - double kurtosis = 0; - for (I j = lb; j != ub; ++j) - { - double d = (*j - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= Ni; - double dev = std::sqrt(var); - skew /= Ni * dev * var; - kurtosis /= Ni * var * var; - kurtosis -= 3; - double x_mean = (b[i+1] + b[i]) / 2; - double x_var = sqr(b[i+1] - b[i]) / 12; - double x_skew = 0; - double x_kurtosis = -6./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs(skew - x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (*j - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= Ni; + double dev = std::sqrt(var); + skew /= Ni * dev * var; + kurtosis /= Ni * var * var; + kurtosis -= 3; + double x_mean = (b[i+1] + b[i]) / 2; + double x_var = sqr(b[i+1] - b[i]) / 12; + double x_skew = 0; + double x_kurtosis = -6./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs(skew - x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); } } +} + +void +test9() +{ + typedef std::piecewise_constant_distribution<> D; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16}; + double p[] = {0, 25}; + const size_t Np = sizeof(p) / sizeof(p[0]); + D d(b, b+Np+1, p); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::piecewise_constant_distribution<> D; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16}; - double p[] = {0, 25}; - const size_t Np = sizeof(p) / sizeof(p[0]); - D d(b, b+Np+1, p); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::vector<double> prob(std::begin(p), std::end(p)); - double s = std::accumulate(prob.begin(), prob.end(), 0.0); - for (int i = 0; i < prob.size(); ++i) - prob[i] /= s; - std::sort(u.begin(), u.end()); - for (int i = 0; i < Np; ++i) + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::vector<double> prob(std::begin(p), std::end(p)); + double s = std::accumulate(prob.begin(), prob.end(), 0.0); + for (int i = 0; i < prob.size(); ++i) + prob[i] /= s; + std::sort(u.begin(), u.end()); + for (int i = 0; i < Np; ++i) + { + typedef std::vector<D::result_type>::iterator I; + I lb = std::lower_bound(u.begin(), u.end(), b[i]); + I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); + const size_t Ni = ub - lb; + if (prob[i] == 0) + assert(Ni == 0); + else { - typedef std::vector<D::result_type>::iterator I; - I lb = std::lower_bound(u.begin(), u.end(), b[i]); - I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); - const size_t Ni = ub - lb; - if (prob[i] == 0) - assert(Ni == 0); - else + assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); + double mean = std::accumulate(lb, ub, 0.0) / Ni; + double var = 0; + double skew = 0; + double kurtosis = 0; + for (I j = lb; j != ub; ++j) { - assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); - double mean = std::accumulate(lb, ub, 0.0) / Ni; - double var = 0; - double skew = 0; - double kurtosis = 0; - for (I j = lb; j != ub; ++j) - { - double d = (*j - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= Ni; - double dev = std::sqrt(var); - skew /= Ni * dev * var; - kurtosis /= Ni * var * var; - kurtosis -= 3; - double x_mean = (b[i+1] + b[i]) / 2; - double x_var = sqr(b[i+1] - b[i]) / 12; - double x_skew = 0; - double x_kurtosis = -6./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs(skew - x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (*j - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= Ni; + double dev = std::sqrt(var); + skew /= Ni * dev * var; + kurtosis /= Ni * var * var; + kurtosis -= 3; + double x_mean = (b[i+1] + b[i]) / 2; + double x_var = sqr(b[i+1] - b[i]) / 12; + double x_skew = 0; + double x_kurtosis = -6./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs(skew - x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); } } +} + +void +test10() +{ + typedef std::piecewise_constant_distribution<> D; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16}; + double p[] = {1, 0}; + const size_t Np = sizeof(p) / sizeof(p[0]); + D d(b, b+Np+1, p); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::piecewise_constant_distribution<> D; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16}; - double p[] = {1, 0}; - const size_t Np = sizeof(p) / sizeof(p[0]); - D d(b, b+Np+1, p); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::vector<double> prob(std::begin(p), std::end(p)); - double s = std::accumulate(prob.begin(), prob.end(), 0.0); - for (int i = 0; i < prob.size(); ++i) - prob[i] /= s; - std::sort(u.begin(), u.end()); - for (int i = 0; i < Np; ++i) + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::vector<double> prob(std::begin(p), std::end(p)); + double s = std::accumulate(prob.begin(), prob.end(), 0.0); + for (int i = 0; i < prob.size(); ++i) + prob[i] /= s; + std::sort(u.begin(), u.end()); + for (int i = 0; i < Np; ++i) + { + typedef std::vector<D::result_type>::iterator I; + I lb = std::lower_bound(u.begin(), u.end(), b[i]); + I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); + const size_t Ni = ub - lb; + if (prob[i] == 0) + assert(Ni == 0); + else { - typedef std::vector<D::result_type>::iterator I; - I lb = std::lower_bound(u.begin(), u.end(), b[i]); - I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); - const size_t Ni = ub - lb; - if (prob[i] == 0) - assert(Ni == 0); - else + assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); + double mean = std::accumulate(lb, ub, 0.0) / Ni; + double var = 0; + double skew = 0; + double kurtosis = 0; + for (I j = lb; j != ub; ++j) { - assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); - double mean = std::accumulate(lb, ub, 0.0) / Ni; - double var = 0; - double skew = 0; - double kurtosis = 0; - for (I j = lb; j != ub; ++j) - { - double d = (*j - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= Ni; - double dev = std::sqrt(var); - skew /= Ni * dev * var; - kurtosis /= Ni * var * var; - kurtosis -= 3; - double x_mean = (b[i+1] + b[i]) / 2; - double x_var = sqr(b[i+1] - b[i]) / 12; - double x_skew = 0; - double x_kurtosis = -6./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs(skew - x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (*j - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= Ni; + double dev = std::sqrt(var); + skew /= Ni * dev * var; + kurtosis /= Ni * var * var; + kurtosis -= 3; + double x_mean = (b[i+1] + b[i]) / 2; + double x_var = sqr(b[i+1] - b[i]) / 12; + double x_skew = 0; + double x_kurtosis = -6./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs(skew - x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); } } +} + +void +test11() +{ + typedef std::piecewise_constant_distribution<> D; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14}; + double p[] = {1}; + const size_t Np = sizeof(p) / sizeof(p[0]); + D d(b, b+Np+1, p); + const int N = 100000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::piecewise_constant_distribution<> D; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14}; - double p[] = {1}; - const size_t Np = sizeof(p) / sizeof(p[0]); - D d(b, b+Np+1, p); - const int N = 100000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::vector<double> prob(std::begin(p), std::end(p)); - double s = std::accumulate(prob.begin(), prob.end(), 0.0); - for (int i = 0; i < prob.size(); ++i) - prob[i] /= s; - std::sort(u.begin(), u.end()); - for (int i = 0; i < Np; ++i) + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::vector<double> prob(std::begin(p), std::end(p)); + double s = std::accumulate(prob.begin(), prob.end(), 0.0); + for (int i = 0; i < prob.size(); ++i) + prob[i] /= s; + std::sort(u.begin(), u.end()); + for (int i = 0; i < Np; ++i) + { + typedef std::vector<D::result_type>::iterator I; + I lb = std::lower_bound(u.begin(), u.end(), b[i]); + I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); + const size_t Ni = ub - lb; + if (prob[i] == 0) + assert(Ni == 0); + else { - typedef std::vector<D::result_type>::iterator I; - I lb = std::lower_bound(u.begin(), u.end(), b[i]); - I ub = std::lower_bound(u.begin(), u.end(), b[i+1]); - const size_t Ni = ub - lb; - if (prob[i] == 0) - assert(Ni == 0); - else + assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); + double mean = std::accumulate(lb, ub, 0.0) / Ni; + double var = 0; + double skew = 0; + double kurtosis = 0; + for (I j = lb; j != ub; ++j) { - assert(std::abs((double)Ni/N - prob[i]) / prob[i] < .01); - double mean = std::accumulate(lb, ub, 0.0) / Ni; - double var = 0; - double skew = 0; - double kurtosis = 0; - for (I j = lb; j != ub; ++j) - { - double d = (*j - mean); - double d2 = sqr(d); - var += d2; - skew += d * d2; - kurtosis += d2 * d2; - } - var /= Ni; - double dev = std::sqrt(var); - skew /= Ni * dev * var; - kurtosis /= Ni * var * var; - kurtosis -= 3; - double x_mean = (b[i+1] + b[i]) / 2; - double x_var = sqr(b[i+1] - b[i]) / 12; - double x_skew = 0; - double x_kurtosis = -6./5; - assert(std::abs((mean - x_mean) / x_mean) < 0.01); - assert(std::abs((var - x_var) / x_var) < 0.01); - assert(std::abs(skew - x_skew) < 0.01); - assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); + double dbl = (*j - mean); + double d2 = sqr(dbl); + var += d2; + skew += dbl * d2; + kurtosis += d2 * d2; } + var /= Ni; + double dev = std::sqrt(var); + skew /= Ni * dev * var; + kurtosis /= Ni * var * var; + kurtosis -= 3; + double x_mean = (b[i+1] + b[i]) / 2; + double x_var = sqr(b[i+1] - b[i]) / 12; + double x_skew = 0; + double x_kurtosis = -6./5; + assert(std::abs((mean - x_mean) / x_mean) < 0.01); + assert(std::abs((var - x_var) / x_var) < 0.01); + assert(std::abs(skew - x_skew) < 0.01); + assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); } } } + +int main() +{ + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + test11(); +} diff --git a/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.pconst/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.pconst/eval_param.pass.cpp index 6850115875bba..ffd53c05d37ef 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.pconst/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.pconst/eval_param.pass.cpp @@ -17,6 +17,7 @@ // template<class _URNG> result_type operator()(_URNG& g, const param_type& parm); #include <random> +#include <algorithm> #include <vector> #include <iterator> #include <numeric> @@ -72,10 +73,10 @@ int main() double kurtosis = 0; for (I j = lb; j != ub; ++j) { - double d = (*j - mean); - double d2 = sqr(d); + double dbl = (*j - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= Ni; diff --git a/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.plinear/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.plinear/eval.pass.cpp index af75fce512e48..03da9b8960e48 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.plinear/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.plinear/eval.pass.cpp @@ -19,10 +19,12 @@ #include <iostream> #include <random> +#include <algorithm> #include <vector> #include <iterator> #include <numeric> #include <cassert> +#include <limits> template <class T> inline @@ -38,306 +40,333 @@ f(double x, double a, double m, double b, double c) return a + m*(sqr(x) - sqr(b))/2 + c*(x-b); } -int main() +void +test1() { + typedef std::piecewise_linear_distribution<> D; + typedef D::param_type P; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16, 17}; + double p[] = {0, 1, 1, 0}; + const size_t Np = sizeof(p) / sizeof(p[0]) - 1; + D d(b, b+Np+1, p); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::piecewise_linear_distribution<> D; - typedef D::param_type P; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16, 17}; - double p[] = {0, 1, 1, 0}; - const size_t Np = sizeof(p) / sizeof(p[0]) - 1; - D d(b, b+Np+1, p); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::sort(u.begin(), u.end()); - int kp = -1; - double a; - double m; - double bk; - double c; - std::vector<double> areas(Np); - double S = 0; - for (int i = 0; i < areas.size(); ++i) - { - areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; - S += areas[i]; - } - for (int i = 0; i < areas.size(); ++i) - areas[i] /= S; - for (int i = 0; i < Np+1; ++i) - p[i] /= S; - for (int i = 0; i < N; ++i) - { - int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; - if (k != kp) - { - a = 0; - for (int j = 0; j < k; ++j) - a += areas[j]; - m = (p[k+1] - p[k]) / (b[k+1] - b[k]); - bk = b[k]; - c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); - kp = k; - } - assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); - } + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); } + std::sort(u.begin(), u.end()); + int kp = -1; + double a = std::numeric_limits<double>::quiet_NaN(); + double m = std::numeric_limits<double>::quiet_NaN(); + double bk = std::numeric_limits<double>::quiet_NaN(); + double c = std::numeric_limits<double>::quiet_NaN(); + std::vector<double> areas(Np); + double S = 0; + for (int i = 0; i < areas.size(); ++i) { - typedef std::piecewise_linear_distribution<> D; - typedef D::param_type P; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16, 17}; - double p[] = {0, 0, 1, 0}; - const size_t Np = sizeof(p) / sizeof(p[0]) - 1; - D d(b, b+Np+1, p); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::sort(u.begin(), u.end()); - int kp = -1; - double a; - double m; - double bk; - double c; - std::vector<double> areas(Np); - double S = 0; - for (int i = 0; i < areas.size(); ++i) - { - areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; - S += areas[i]; - } - for (int i = 0; i < areas.size(); ++i) - areas[i] /= S; - for (int i = 0; i < Np+1; ++i) - p[i] /= S; - for (int i = 0; i < N; ++i) - { - int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; - if (k != kp) - { - a = 0; - for (int j = 0; j < k; ++j) - a += areas[j]; - m = (p[k+1] - p[k]) / (b[k+1] - b[k]); - bk = b[k]; - c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); - kp = k; - } - assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); - } + areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; + S += areas[i]; } + for (int i = 0; i < areas.size(); ++i) + areas[i] /= S; + for (int i = 0; i < Np+1; ++i) + p[i] /= S; + for (int i = 0; i < N; ++i) { - typedef std::piecewise_linear_distribution<> D; - typedef D::param_type P; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16, 17}; - double p[] = {1, 0, 0, 0}; - const size_t Np = sizeof(p) / sizeof(p[0]) - 1; - D d(b, b+Np+1, p); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::sort(u.begin(), u.end()); - int kp = -1; - double a; - double m; - double bk; - double c; - std::vector<double> areas(Np); - double S = 0; - for (int i = 0; i < areas.size(); ++i) - { - areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; - S += areas[i]; - } - for (int i = 0; i < areas.size(); ++i) - areas[i] /= S; - for (int i = 0; i < Np+1; ++i) - p[i] /= S; - for (int i = 0; i < N; ++i) + int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; + if (k != kp) { - int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; - if (k != kp) - { - a = 0; - for (int j = 0; j < k; ++j) - a += areas[j]; - m = (p[k+1] - p[k]) / (b[k+1] - b[k]); - bk = b[k]; - c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); - kp = k; - } - assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); + a = 0; + for (int j = 0; j < k; ++j) + a += areas[j]; + m = (p[k+1] - p[k]) / (b[k+1] - b[k]); + bk = b[k]; + c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); + kp = k; } + assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); } +} + +void +test2() +{ + typedef std::piecewise_linear_distribution<> D; + typedef D::param_type P; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16, 17}; + double p[] = {0, 0, 1, 0}; + const size_t Np = sizeof(p) / sizeof(p[0]) - 1; + D d(b, b+Np+1, p); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::piecewise_linear_distribution<> D; - typedef D::param_type P; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16}; - double p[] = {0, 1, 0}; - const size_t Np = sizeof(p) / sizeof(p[0]) - 1; - D d(b, b+Np+1, p); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::sort(u.begin(), u.end()); - int kp = -1; - double a; - double m; - double bk; - double c; - std::vector<double> areas(Np); - double S = 0; - for (int i = 0; i < areas.size(); ++i) - { - areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; - S += areas[i]; - } - for (int i = 0; i < areas.size(); ++i) - areas[i] /= S; - for (int i = 0; i < Np+1; ++i) - p[i] /= S; - for (int i = 0; i < N; ++i) - { - int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; - if (k != kp) - { - a = 0; - for (int j = 0; j < k; ++j) - a += areas[j]; - m = (p[k+1] - p[k]) / (b[k+1] - b[k]); - bk = b[k]; - c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); - kp = k; - } - assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); - } + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); } + std::sort(u.begin(), u.end()); + int kp = -1; + double a = std::numeric_limits<double>::quiet_NaN(); + double m = std::numeric_limits<double>::quiet_NaN(); + double bk = std::numeric_limits<double>::quiet_NaN(); + double c = std::numeric_limits<double>::quiet_NaN(); + std::vector<double> areas(Np); + double S = 0; + for (int i = 0; i < areas.size(); ++i) { - typedef std::piecewise_linear_distribution<> D; - typedef D::param_type P; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14}; - double p[] = {1, 1}; - const size_t Np = sizeof(p) / sizeof(p[0]) - 1; - D d(b, b+Np+1, p); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) - { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); - } - std::sort(u.begin(), u.end()); - int kp = -1; - double a; - double m; - double bk; - double c; - std::vector<double> areas(Np); - double S = 0; - for (int i = 0; i < areas.size(); ++i) + areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; + S += areas[i]; + } + for (int i = 0; i < areas.size(); ++i) + areas[i] /= S; + for (int i = 0; i < Np+1; ++i) + p[i] /= S; + for (int i = 0; i < N; ++i) + { + int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; + if (k != kp) { - areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; - S += areas[i]; + a = 0; + for (int j = 0; j < k; ++j) + a += areas[j]; + m = (p[k+1] - p[k]) / (b[k+1] - b[k]); + bk = b[k]; + c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); + kp = k; } - for (int i = 0; i < areas.size(); ++i) - areas[i] /= S; - for (int i = 0; i < Np+1; ++i) - p[i] /= S; - for (int i = 0; i < N; ++i) + assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); + } +} + +void +test3() +{ + typedef std::piecewise_linear_distribution<> D; + typedef D::param_type P; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16, 17}; + double p[] = {1, 0, 0, 0}; + const size_t Np = sizeof(p) / sizeof(p[0]) - 1; + D d(b, b+Np+1, p); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::sort(u.begin(), u.end()); + int kp = -1; + double a = std::numeric_limits<double>::quiet_NaN(); + double m = std::numeric_limits<double>::quiet_NaN(); + double bk = std::numeric_limits<double>::quiet_NaN(); + double c = std::numeric_limits<double>::quiet_NaN(); + std::vector<double> areas(Np); + double S = 0; + for (int i = 0; i < areas.size(); ++i) + { + areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; + S += areas[i]; + } + for (int i = 0; i < areas.size(); ++i) + areas[i] /= S; + for (int i = 0; i < Np+1; ++i) + p[i] /= S; + for (int i = 0; i < N; ++i) + { + int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; + if (k != kp) { - int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; - if (k != kp) - { - a = 0; - for (int j = 0; j < k; ++j) - a += areas[j]; - m = (p[k+1] - p[k]) / (b[k+1] - b[k]); - bk = b[k]; - c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); - kp = k; - } - assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); + a = 0; + for (int j = 0; j < k; ++j) + a += areas[j]; + m = (p[k+1] - p[k]) / (b[k+1] - b[k]); + bk = b[k]; + c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); + kp = k; } + assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); } +} + +void +test4() +{ + typedef std::piecewise_linear_distribution<> D; + typedef D::param_type P; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16}; + double p[] = {0, 1, 0}; + const size_t Np = sizeof(p) / sizeof(p[0]) - 1; + D d(b, b+Np+1, p); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) { - typedef std::piecewise_linear_distribution<> D; - typedef D::param_type P; - typedef std::mt19937_64 G; - G g; - double b[] = {10, 14, 16, 17}; - double p[] = {25, 62.5, 12.5, 0}; - const size_t Np = sizeof(p) / sizeof(p[0]) - 1; - D d(b, b+Np+1, p); - const int N = 1000000; - std::vector<D::result_type> u; - for (int i = 0; i < N; ++i) + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::sort(u.begin(), u.end()); + int kp = -1; + double a = std::numeric_limits<double>::quiet_NaN(); + double m = std::numeric_limits<double>::quiet_NaN(); + double bk = std::numeric_limits<double>::quiet_NaN(); + double c = std::numeric_limits<double>::quiet_NaN(); + std::vector<double> areas(Np); + double S = 0; + for (int i = 0; i < areas.size(); ++i) + { + areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; + S += areas[i]; + } + for (int i = 0; i < areas.size(); ++i) + areas[i] /= S; + for (int i = 0; i < Np+1; ++i) + p[i] /= S; + for (int i = 0; i < N; ++i) + { + int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; + if (k != kp) { - D::result_type v = d(g); - assert(d.min() <= v && v < d.max()); - u.push_back(v); + a = 0; + for (int j = 0; j < k; ++j) + a += areas[j]; + assert(k < Np); + m = (p[k+1] - p[k]) / (b[k+1] - b[k]); + bk = b[k]; + c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); + kp = k; } - std::sort(u.begin(), u.end()); - int kp = -1; - double a; - double m; - double bk; - double c; - std::vector<double> areas(Np); - double S = 0; - for (int i = 0; i < areas.size(); ++i) + assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); + } +} + +void +test5() +{ + typedef std::piecewise_linear_distribution<> D; + typedef D::param_type P; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14}; + double p[] = {1, 1}; + const size_t Np = sizeof(p) / sizeof(p[0]) - 1; + D d(b, b+Np+1, p); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::sort(u.begin(), u.end()); + int kp = -1; + double a = std::numeric_limits<double>::quiet_NaN(); + double m = std::numeric_limits<double>::quiet_NaN(); + double bk = std::numeric_limits<double>::quiet_NaN(); + double c = std::numeric_limits<double>::quiet_NaN(); + std::vector<double> areas(Np); + double S = 0; + for (int i = 0; i < areas.size(); ++i) + { + assert(i < Np); + areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; + S += areas[i]; + } + for (int i = 0; i < areas.size(); ++i) + areas[i] /= S; + for (int i = 0; i < Np+1; ++i) + p[i] /= S; + for (int i = 0; i < N; ++i) + { + int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; + if (k != kp) { - areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; - S += areas[i]; + a = 0; + for (int j = 0; j < k; ++j) + a += areas[j]; + assert(k < Np); + m = (p[k+1] - p[k]) / (b[k+1] - b[k]); + bk = b[k]; + c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); + kp = k; } - for (int i = 0; i < areas.size(); ++i) - areas[i] /= S; - for (int i = 0; i < Np+1; ++i) - p[i] /= S; - for (int i = 0; i < N; ++i) + assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); + } +} + +void +test6() +{ + typedef std::piecewise_linear_distribution<> D; + typedef D::param_type P; + typedef std::mt19937_64 G; + G g; + double b[] = {10, 14, 16, 17}; + double p[] = {25, 62.5, 12.5, 0}; + const size_t Np = sizeof(p) / sizeof(p[0]) - 1; + D d(b, b+Np+1, p); + const int N = 1000000; + std::vector<D::result_type> u; + for (int i = 0; i < N; ++i) + { + D::result_type v = d(g); + assert(d.min() <= v && v < d.max()); + u.push_back(v); + } + std::sort(u.begin(), u.end()); + int kp = -1; + double a = std::numeric_limits<double>::quiet_NaN(); + double m = std::numeric_limits<double>::quiet_NaN(); + double bk = std::numeric_limits<double>::quiet_NaN(); + double c = std::numeric_limits<double>::quiet_NaN(); + std::vector<double> areas(Np); + double S = 0; + for (int i = 0; i < areas.size(); ++i) + { + areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; + S += areas[i]; + } + for (int i = 0; i < areas.size(); ++i) + areas[i] /= S; + for (int i = 0; i < Np+1; ++i) + p[i] /= S; + for (int i = 0; i < N; ++i) + { + int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; + if (k != kp) { - int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; - if (k != kp) - { - a = 0; - for (int j = 0; j < k; ++j) - a += areas[j]; - m = (p[k+1] - p[k]) / (b[k+1] - b[k]); - bk = b[k]; - c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); - kp = k; - } - assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); + a = 0; + for (int j = 0; j < k; ++j) + a += areas[j]; + m = (p[k+1] - p[k]) / (b[k+1] - b[k]); + bk = b[k]; + c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); + kp = k; } + assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); } } + +int main() +{ + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); +} diff --git a/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.plinear/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.plinear/eval_param.pass.cpp index fe704228e7889..8054a69fed874 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.plinear/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.plinear/eval_param.pass.cpp @@ -20,7 +20,9 @@ #include <vector> #include <iterator> #include <numeric> +#include <algorithm> // for sort #include <cassert> +#include <limits> template <class T> inline @@ -58,10 +60,10 @@ int main() } std::sort(u.begin(), u.end()); int kp = -1; - double a; - double m; - double bk; - double c; + double a = std::numeric_limits<double>::quiet_NaN(); + double m = std::numeric_limits<double>::quiet_NaN(); + double bk = std::numeric_limits<double>::quiet_NaN(); + double c = std::numeric_limits<double>::quiet_NaN(); std::vector<double> areas(Np); double S = 0; for (int i = 0; i < areas.size(); ++i) diff --git a/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/eval.pass.cpp index 66693a8da55b9..2abc9d4c6dd58 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/eval.pass.cpp @@ -51,10 +51,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -92,10 +92,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -133,10 +133,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -174,10 +174,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -215,10 +215,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -256,10 +256,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -297,10 +297,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -338,10 +338,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -379,10 +379,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -431,10 +431,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/eval_param.pass.cpp index d83d48cac1e3a..849f25107fa89 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/eval_param.pass.cpp @@ -51,10 +51,10 @@ int main() double kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - double d = (u[i] - mean); - double d2 = sqr(d); + double dbl = (u[i] - mean); + double d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/eval.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/eval.pass.cpp index 2663b2683bb4b..e000363f32155 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/eval.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/eval.pass.cpp @@ -51,10 +51,10 @@ int main() D::result_type kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - D::result_type d = (u[i] - mean); - D::result_type d2 = sqr(d); + D::result_type dbl = (u[i] - mean); + D::result_type d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -91,10 +91,10 @@ int main() D::result_type kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - D::result_type d = (u[i] - mean); - D::result_type d2 = sqr(d); + D::result_type dbl = (u[i] - mean); + D::result_type d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -131,10 +131,10 @@ int main() D::result_type kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - D::result_type d = (u[i] - mean); - D::result_type d2 = sqr(d); + D::result_type dbl = (u[i] - mean); + D::result_type d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -171,10 +171,10 @@ int main() D::result_type kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - D::result_type d = (u[i] - mean); - D::result_type d2 = sqr(d); + D::result_type dbl = (u[i] - mean); + D::result_type d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -211,10 +211,10 @@ int main() D::result_type kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - D::result_type d = (u[i] - mean); - D::result_type d2 = sqr(d); + D::result_type dbl = (u[i] - mean); + D::result_type d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -251,10 +251,10 @@ int main() D::result_type kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - D::result_type d = (u[i] - mean); - D::result_type d2 = sqr(d); + D::result_type dbl = (u[i] - mean); + D::result_type d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -291,10 +291,10 @@ int main() D::result_type kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - D::result_type d = (u[i] - mean); - D::result_type d2 = sqr(d); + D::result_type dbl = (u[i] - mean); + D::result_type d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -331,10 +331,10 @@ int main() D::result_type kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - D::result_type d = (u[i] - mean); - D::result_type d2 = sqr(d); + D::result_type dbl = (u[i] - mean); + D::result_type d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -371,10 +371,10 @@ int main() D::result_type kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - D::result_type d = (u[i] - mean); - D::result_type d2 = sqr(d); + D::result_type dbl = (u[i] - mean); + D::result_type d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -411,10 +411,10 @@ int main() D::result_type kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - D::result_type d = (u[i] - mean); - D::result_type d2 = sqr(d); + D::result_type dbl = (u[i] - mean); + D::result_type d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); @@ -451,10 +451,10 @@ int main() D::result_type kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - D::result_type d = (u[i] - mean); - D::result_type d2 = sqr(d); + D::result_type dbl = (u[i] - mean); + D::result_type d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); diff --git a/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/eval_param.pass.cpp b/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/eval_param.pass.cpp index b5803f401465c..d351f0caed714 100644 --- a/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/eval_param.pass.cpp +++ b/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/eval_param.pass.cpp @@ -51,10 +51,10 @@ int main() D::result_type kurtosis = 0; for (int i = 0; i < u.size(); ++i) { - D::result_type d = (u[i] - mean); - D::result_type d2 = sqr(d); + D::result_type dbl = (u[i] - mean); + D::result_type d2 = sqr(dbl); var += d2; - skew += d * d2; + skew += dbl * d2; kurtosis += d2 * d2; } var /= u.size(); 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 e4b2f3ec50143..a32b2ca0ae320 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,6 +19,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "platform_support.h" // locale name macros diff --git a/test/std/re/re.alg/re.alg.match/basic.fail.cpp b/test/std/re/re.alg/re.alg.match/basic.fail.cpp index 82f8e3b7ee898..04ce8fdd201bd 100644 --- a/test/std/re/re.alg/re.alg.match/basic.fail.cpp +++ b/test/std/re/re.alg/re.alg.match/basic.fail.cpp @@ -9,21 +9,22 @@ // <regex> -// template <class ST, class SA, class Allocator, class charT, class traits> -// bool regex_match(const basic_string<charT, ST, SA>&&, +// template <class ST, class SA, class Allocator, class charT, class traits> +// bool regex_match(const basic_string<charT, ST, SA>&&, // match_results< -// typename basic_string<charT, ST, SA>::const_iterator, -// Allocator>&, -// const basic_regex<charT, traits>&, -// regex_constants::match_flag_type = +// typename basic_string<charT, ST, SA>::const_iterator, +// Allocator>&, +// const basic_regex<charT, traits>&, +// regex_constants::match_flag_type = // regex_constants::match_default) = delete; -#if __cplusplus <= 201402L -#error -#else - #include <regex> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER < 14 +#error +#endif int main() { @@ -33,4 +34,3 @@ int main() std::regex_match(std::string("abcde"), m, re); } } -#endif 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 2ddc07a2000fa..901bf90e63860 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,6 +23,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "platform_support.h" // locale name macros 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 785a61c47f11d..a4568f60167c7 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,6 +23,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "platform_support.h" // locale name macros diff --git a/test/std/re/re.alg/re.alg.match/egrep.pass.cpp b/test/std/re/re.alg/re.alg.match/egrep.pass.cpp index dd2e6038dc31c..53cff850e2d4c 100644 --- a/test/std/re/re.alg/re.alg.match/egrep.pass.cpp +++ b/test/std/re/re.alg/re.alg.match/egrep.pass.cpp @@ -19,6 +19,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" int main() 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 9ca31d1814a65..5e08d0ac5fdba 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,6 +23,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "platform_support.h" // locale name macros diff --git a/test/std/re/re.alg/re.alg.match/grep.pass.cpp b/test/std/re/re.alg/re.alg.match/grep.pass.cpp index 2dc0966d6b8de..efd33cb11e03c 100644 --- a/test/std/re/re.alg/re.alg.match/grep.pass.cpp +++ b/test/std/re/re.alg/re.alg.match/grep.pass.cpp @@ -19,6 +19,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" int main() diff --git a/test/std/re/re.alg/re.alg.match/lookahead_capture.pass.cpp b/test/std/re/re.alg/re.alg.match/lookahead_capture.pass.cpp index 949739b992cb3..95f400ce88c98 100644 --- a/test/std/re/re.alg/re.alg.match/lookahead_capture.pass.cpp +++ b/test/std/re/re.alg/re.alg.match/lookahead_capture.pass.cpp @@ -16,12 +16,13 @@ // const basic_regex<charT, traits>& e, // regex_constants::match_flag_type flags = regex_constants::match_default); -// std::regex in ECMAScript mode should not ignore capture groups inside lookahead assertions. +// std::regex in ECMAScript mode should not ignore capture groups inside lookahead assertions. // For example, matching /(?=(a))(a)/ to "a" should yield two captures: \1 = "a", \2 = "a" #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" int main() diff --git a/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp b/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp index 0b4c6948140ec..59b2832c4580a 100644 --- a/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp +++ b/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp @@ -21,6 +21,7 @@ #include <string> #include <regex> #include <cassert> +#include "test_macros.h" void test1() diff --git a/test/std/re/re.alg/re.alg.replace/test1.pass.cpp b/test/std/re/re.alg/re.alg.replace/test1.pass.cpp index 9fd84fdc1f6e9..13cc8f2a0dd21 100644 --- a/test/std/re/re.alg/re.alg.replace/test1.pass.cpp +++ b/test/std/re/re.alg/re.alg.replace/test1.pass.cpp @@ -22,6 +22,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" int main() diff --git a/test/std/re/re.alg/re.alg.replace/test2.pass.cpp b/test/std/re/re.alg/re.alg.replace/test2.pass.cpp index 63a4ed56933d1..679644f09b680 100644 --- a/test/std/re/re.alg/re.alg.replace/test2.pass.cpp +++ b/test/std/re/re.alg/re.alg.replace/test2.pass.cpp @@ -22,6 +22,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" int main() diff --git a/test/std/re/re.alg/re.alg.replace/test3.pass.cpp b/test/std/re/re.alg/re.alg.replace/test3.pass.cpp index d1167860646f9..c8b8c649d1da8 100644 --- a/test/std/re/re.alg/re.alg.replace/test3.pass.cpp +++ b/test/std/re/re.alg/re.alg.replace/test3.pass.cpp @@ -19,6 +19,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.alg/re.alg.replace/test4.pass.cpp b/test/std/re/re.alg/re.alg.replace/test4.pass.cpp index fba1bc19546a9..251eae8f6e201 100644 --- a/test/std/re/re.alg/re.alg.replace/test4.pass.cpp +++ b/test/std/re/re.alg/re.alg.replace/test4.pass.cpp @@ -18,6 +18,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.alg/re.alg.replace/test5.pass.cpp b/test/std/re/re.alg/re.alg.replace/test5.pass.cpp index 7190e41d52288..53720d6f72ae7 100644 --- a/test/std/re/re.alg/re.alg.replace/test5.pass.cpp +++ b/test/std/re/re.alg/re.alg.replace/test5.pass.cpp @@ -19,6 +19,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.alg/re.alg.replace/test6.pass.cpp b/test/std/re/re.alg/re.alg.replace/test6.pass.cpp index b017800773030..a00ac75193d54 100644 --- a/test/std/re/re.alg/re.alg.replace/test6.pass.cpp +++ b/test/std/re/re.alg/re.alg.replace/test6.pass.cpp @@ -19,6 +19,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { 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 7fc1b3fcc233d..05d1f59e147af 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,6 +23,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "platform_support.h" // locale name macros diff --git a/test/std/re/re.alg/re.alg.search/backup.pass.cpp b/test/std/re/re.alg/re.alg.search/backup.pass.cpp index 7da58608705b8..f33b844bed9c5 100644 --- a/test/std/re/re.alg/re.alg.search/backup.pass.cpp +++ b/test/std/re/re.alg/re.alg.search/backup.pass.cpp @@ -20,6 +20,7 @@ #include <string> #include <list> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.alg/re.alg.search/basic.fail.cpp b/test/std/re/re.alg/re.alg.search/basic.fail.cpp index 9ab6a21ad9dc5..430b0a3aa4c32 100644 --- a/test/std/re/re.alg/re.alg.search/basic.fail.cpp +++ b/test/std/re/re.alg/re.alg.search/basic.fail.cpp @@ -9,21 +9,22 @@ // <regex> -// template <class ST, class SA, class Allocator, class charT, class traits> -// bool regex_search(const basic_string<charT, ST, SA>&&, +// template <class ST, class SA, class Allocator, class charT, class traits> +// bool regex_search(const basic_string<charT, ST, SA>&&, // match_results< -// typename basic_string<charT, ST, SA>::const_iterator, -// Allocator>&, -// const basic_regex<charT, traits>&, -// regex_constants::match_flag_type = +// typename basic_string<charT, ST, SA>::const_iterator, +// Allocator>&, +// const basic_regex<charT, traits>&, +// regex_constants::match_flag_type = // regex_constants::match_default) = delete; -#if __cplusplus <= 201402L -#error -#else - #include <regex> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER < 14 +#error +#endif int main() { @@ -33,4 +34,3 @@ int main() std::regex_search(std::string("abcde"), m, re); } } -#endif 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 bdfcd9cc9bcd7..f5157f563755f 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,6 +23,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "platform_support.h" // locale name macros 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 fb9fc26a281a9..d6a3da6ea076c 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,6 +23,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "platform_support.h" // locale name macros diff --git a/test/std/re/re.alg/re.alg.search/egrep.pass.cpp b/test/std/re/re.alg/re.alg.search/egrep.pass.cpp index 1dffed44f2275..0bf8386119ee3 100644 --- a/test/std/re/re.alg/re.alg.search/egrep.pass.cpp +++ b/test/std/re/re.alg/re.alg.search/egrep.pass.cpp @@ -19,6 +19,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" int main() 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 81eef2f9e4b95..88af3b908815a 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,6 +23,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "platform_support.h" // locale name macros diff --git a/test/std/re/re.alg/re.alg.search/grep.pass.cpp b/test/std/re/re.alg/re.alg.search/grep.pass.cpp index 9d74c2417d2da..136f9958c9b21 100644 --- a/test/std/re/re.alg/re.alg.search/grep.pass.cpp +++ b/test/std/re/re.alg/re.alg.search/grep.pass.cpp @@ -34,9 +34,9 @@ extern "C" void LLVMFuzzerTestOneInput(const char *data) std::string s((const char *)data, size); std::regex re(s, flag); std::regex_match(s, re); - } - catch (std::regex_error &ex) {} - } + } + catch (std::regex_error &) {} + } } diff --git a/test/std/re/re.alg/re.alg.search/lookahead.pass.cpp b/test/std/re/re.alg/re.alg.search/lookahead.pass.cpp index 9f5f9540165a0..93424e188432f 100644 --- a/test/std/re/re.alg/re.alg.search/lookahead.pass.cpp +++ b/test/std/re/re.alg/re.alg.search/lookahead.pass.cpp @@ -20,8 +20,9 @@ #include <regex> #include <cassert> +#include "test_macros.h" -int main() +int main() { assert(!std::regex_search("ab", std::regex("(?=^)b"))); assert(!std::regex_search("ab", std::regex("a(?=^)b"))); diff --git a/test/std/re/re.alg/re.alg.search/no_update_pos.pass.cpp b/test/std/re/re.alg/re.alg.search/no_update_pos.pass.cpp index ef9cec5f736e8..600425d8de359 100644 --- a/test/std/re/re.alg/re.alg.search/no_update_pos.pass.cpp +++ b/test/std/re/re.alg/re.alg.search/no_update_pos.pass.cpp @@ -18,6 +18,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.badexp/regex_error.pass.cpp b/test/std/re/re.badexp/regex_error.pass.cpp index 02fecbda2d95b..f1752716ec75a 100644 --- a/test/std/re/re.badexp/regex_error.pass.cpp +++ b/test/std/re/re.badexp/regex_error.pass.cpp @@ -20,6 +20,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.const/re.err/error_type.pass.cpp b/test/std/re/re.const/re.err/error_type.pass.cpp index 150855beb0a4c..3609d41b9beb3 100644 --- a/test/std/re/re.const/re.err/error_type.pass.cpp +++ b/test/std/re/re.const/re.err/error_type.pass.cpp @@ -34,6 +34,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.const/re.matchflag/match_flag_type.pass.cpp b/test/std/re/re.const/re.matchflag/match_flag_type.pass.cpp index b48703c7579fb..c7b2a80cd2a4a 100644 --- a/test/std/re/re.const/re.matchflag/match_flag_type.pass.cpp +++ b/test/std/re/re.const/re.matchflag/match_flag_type.pass.cpp @@ -34,6 +34,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { 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 index 41ac0cee0d6a5..03e8770dd68d2 100644 --- 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 @@ -11,12 +11,13 @@ // <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 +// 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> +#include "test_macros.h" int main() { 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 index 594c9fb984539..1c9b154f1fccb 100644 --- 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 @@ -11,12 +11,13 @@ // <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 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> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.const/re.synopt/syntax_option_type.pass.cpp b/test/std/re/re.const/re.synopt/syntax_option_type.pass.cpp index 1c4f824448a6e..ad6111cc4ee27 100644 --- a/test/std/re/re.const/re.synopt/syntax_option_type.pass.cpp +++ b/test/std/re/re.const/re.synopt/syntax_option_type.pass.cpp @@ -31,6 +31,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.iter/re.regiter/re.regiter.cnstr/cnstr.fail.cpp b/test/std/re/re.iter/re.regiter/re.regiter.cnstr/cnstr.fail.cpp index 208de0e43cec8..24fb3787ed1f4 100644 --- a/test/std/re/re.iter/re.regiter/re.regiter.cnstr/cnstr.fail.cpp +++ b/test/std/re/re.iter/re.regiter/re.regiter.cnstr/cnstr.fail.cpp @@ -17,20 +17,20 @@ // regex_constants::match_flag_type m = // regex_constants::match_default) = delete; -#if __cplusplus <= 201402L -#error -#else - #include <regex> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER < 14 +#error +#endif int main() { { const char phone_book[] = "555-1234, 555-2345, 555-3456"; std::cregex_iterator i( - std::begin(phone_book), std::end(phone_book), + std::begin(phone_book), std::end(phone_book), std::regex("\\d{3}-\\d{4}")); } } -#endif diff --git a/test/std/re/re.iter/re.regiter/re.regiter.cnstr/cnstr.pass.cpp b/test/std/re/re.iter/re.regiter/re.regiter.cnstr/cnstr.pass.cpp index c9fc7a3cd1cc8..c1cabff39d548 100644 --- a/test/std/re/re.iter/re.regiter/re.regiter.cnstr/cnstr.pass.cpp +++ b/test/std/re/re.iter/re.regiter/re.regiter.cnstr/cnstr.pass.cpp @@ -17,6 +17,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.iter/re.regiter/re.regiter.cnstr/default.pass.cpp b/test/std/re/re.iter/re.regiter/re.regiter.cnstr/default.pass.cpp index 9d4766dc876f0..cb44fb37bc897 100644 --- a/test/std/re/re.iter/re.regiter/re.regiter.cnstr/default.pass.cpp +++ b/test/std/re/re.iter/re.regiter/re.regiter.cnstr/default.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" template <class CharT> void diff --git a/test/std/re/re.iter/re.regiter/re.regiter.deref/deref.pass.cpp b/test/std/re/re.iter/re.regiter/re.regiter.deref/deref.pass.cpp index e4933fe16f8e1..800f56434160f 100644 --- a/test/std/re/re.iter/re.regiter/re.regiter.deref/deref.pass.cpp +++ b/test/std/re/re.iter/re.regiter/re.regiter.deref/deref.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.iter/re.regiter/re.regiter.incr/post.pass.cpp b/test/std/re/re.iter/re.regiter/re.regiter.incr/post.pass.cpp index 3ec0d6c0c3b46..f3b57f6bc9da0 100644 --- a/test/std/re/re.iter/re.regiter/re.regiter.incr/post.pass.cpp +++ b/test/std/re/re.iter/re.regiter/re.regiter.incr/post.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.iter/re.regiter/types.pass.cpp b/test/std/re/re.iter/re.regiter/types.pass.cpp index db1d3eb958bff..5b79957bea241 100644 --- a/test/std/re/re.iter/re.regiter/types.pass.cpp +++ b/test/std/re/re.iter/re.regiter/types.pass.cpp @@ -24,6 +24,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" template <class CharT> void diff --git a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.fail.cpp b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.fail.cpp index 6753b0ad506b0..8f90b23907dca 100644 --- a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.fail.cpp +++ b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.fail.cpp @@ -18,13 +18,14 @@ // regex_constants::match_flag_type m = // regex_constants::match_default); -#if __cplusplus <= 201402L -#error -#else - #include <regex> #include <vector> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER < 14 +#error +#endif int main() { @@ -36,4 +37,3 @@ int main() std::regex("\\d{3}-\\d{4}"), indices); } } -#endif diff --git a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.pass.cpp b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.pass.cpp index a51b8274bdd84..6d8c2f35e4242 100644 --- a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.pass.cpp +++ b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.pass.cpp @@ -20,6 +20,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/default.pass.cpp b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/default.pass.cpp index 382815e0c1cc1..e71f3a69217eb 100644 --- a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/default.pass.cpp +++ b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/default.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" template <class CharT> void diff --git a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.fail.cpp b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.fail.cpp index e58183682ea44..9d538730e8099 100644 --- a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.fail.cpp +++ b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.fail.cpp @@ -17,12 +17,13 @@ // regex_constants::match_flag_type m = // regex_constants::match_default); -#if __cplusplus <= 201402L -#error -#else - #include <regex> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER < 14 +#error +#endif int main() { @@ -33,4 +34,3 @@ int main() std::regex("\\d{3}-\\d{4}"), {-1, 0, 1}); } } -#endif diff --git a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.pass.cpp b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.pass.cpp index b40d7eb9224de..6cffc0da9a525 100644 --- a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.pass.cpp +++ b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.pass.cpp @@ -19,6 +19,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.fail.cpp b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.fail.cpp index d0a100a1afcc5..f4601f3ed0335 100644 --- a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.fail.cpp +++ b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.fail.cpp @@ -16,12 +16,13 @@ // regex_constants::match_flag_type m = // regex_constants::match_default); -#if __cplusplus <= 201402L -#error -#else - #include <regex> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER < 14 +#error +#endif int main() { @@ -32,4 +33,3 @@ int main() std::regex("\\d{3}-\\d{4}"), -1); } } -#endif diff --git a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.pass.cpp b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.pass.cpp index d8111363c176e..37fe2d9767ef6 100644 --- a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.pass.cpp +++ b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.pass.cpp @@ -18,6 +18,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.fail.cpp b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.fail.cpp index 94d8f9667d2ce..d5d5f4c63ceba 100644 --- a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.fail.cpp +++ b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.fail.cpp @@ -18,12 +18,13 @@ // regex_constants::match_flag_type m = // regex_constants::match_default); -#if __cplusplus <= 201402L -#error -#else - #include <regex> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER < 14 +#error +#endif int main() { @@ -37,4 +38,3 @@ int main() std::regex("\\d{3}-\\d{4}"), v); } } -#endif diff --git a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.pass.cpp b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.pass.cpp index b04f5804509f4..473a706dd854f 100644 --- a/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.pass.cpp +++ b/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.pass.cpp @@ -19,6 +19,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.iter/re.tokiter/re.tokiter.comp/equal.pass.cpp b/test/std/re/re.iter/re.tokiter/re.tokiter.comp/equal.pass.cpp index d6399f1148b4a..49d1b1b7ed547 100644 --- a/test/std/re/re.iter/re.tokiter/re.tokiter.comp/equal.pass.cpp +++ b/test/std/re/re.iter/re.tokiter/re.tokiter.comp/equal.pass.cpp @@ -16,6 +16,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.iter/re.tokiter/re.tokiter.deref/deref.pass.cpp b/test/std/re/re.iter/re.tokiter/re.tokiter.deref/deref.pass.cpp index b096e3c08275f..73ec62cfc67d5 100644 --- a/test/std/re/re.iter/re.tokiter/re.tokiter.deref/deref.pass.cpp +++ b/test/std/re/re.iter/re.tokiter/re.tokiter.deref/deref.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.iter/re.tokiter/re.tokiter.incr/post.pass.cpp b/test/std/re/re.iter/re.tokiter/re.tokiter.incr/post.pass.cpp index 727ab7af93760..7d55bc1113fad 100644 --- a/test/std/re/re.iter/re.tokiter/re.tokiter.incr/post.pass.cpp +++ b/test/std/re/re.iter/re.tokiter/re.tokiter.incr/post.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.iter/re.tokiter/types.pass.cpp b/test/std/re/re.iter/re.tokiter/types.pass.cpp index 89287bdd1d002..b7777fbeefff0 100644 --- a/test/std/re/re.iter/re.tokiter/types.pass.cpp +++ b/test/std/re/re.iter/re.tokiter/types.pass.cpp @@ -24,6 +24,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" template <class CharT> void diff --git a/test/std/re/re.regex/re.regex.assign/assign.il.pass.cpp b/test/std/re/re.regex/re.regex.assign/assign.il.pass.cpp index 96cadf166001b..39c3a22ef7257 100644 --- a/test/std/re/re.regex/re.regex.assign/assign.il.pass.cpp +++ b/test/std/re/re.regex/re.regex.assign/assign.il.pass.cpp @@ -17,6 +17,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.regex/re.regex.assign/assign.pass.cpp b/test/std/re/re.regex/re.regex.assign/assign.pass.cpp index 9c5f834b9452a..97208c68c8d6c 100644 --- a/test/std/re/re.regex/re.regex.assign/assign.pass.cpp +++ b/test/std/re/re.regex/re.regex.assign/assign.pass.cpp @@ -16,6 +16,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { @@ -25,7 +26,7 @@ int main() assert(r2.flags() == std::regex::ECMAScript); assert(r2.mark_count() == 2); assert(std::regex_search("ab", r2)); - + bool caught = false; try { r2.assign("(def", std::regex::extended); } catch(std::regex_error &) { caught = true; } diff --git a/test/std/re/re.regex/re.regex.assign/assign_iter_iter_flag.pass.cpp b/test/std/re/re.regex/re.regex.assign/assign_iter_iter_flag.pass.cpp index 529a64a239a0e..7cd4845f30733 100644 --- a/test/std/re/re.regex/re.regex.assign/assign_iter_iter_flag.pass.cpp +++ b/test/std/re/re.regex/re.regex.assign/assign_iter_iter_flag.pass.cpp @@ -19,6 +19,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" int main() diff --git a/test/std/re/re.regex/re.regex.assign/assign_ptr_flag.pass.cpp b/test/std/re/re.regex/re.regex.assign/assign_ptr_flag.pass.cpp index dd39dee13ffbe..33b9cad18335a 100644 --- a/test/std/re/re.regex/re.regex.assign/assign_ptr_flag.pass.cpp +++ b/test/std/re/re.regex/re.regex.assign/assign_ptr_flag.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.regex/re.regex.assign/assign_ptr_size_flag.pass.cpp b/test/std/re/re.regex/re.regex.assign/assign_ptr_size_flag.pass.cpp index 679cd9df17fce..7ec4f77a50529 100644 --- a/test/std/re/re.regex/re.regex.assign/assign_ptr_size_flag.pass.cpp +++ b/test/std/re/re.regex/re.regex.assign/assign_ptr_size_flag.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.regex/re.regex.assign/assign_string_flag.pass.cpp b/test/std/re/re.regex/re.regex.assign/assign_string_flag.pass.cpp index 46f984da04db6..247d27721be77 100644 --- a/test/std/re/re.regex/re.regex.assign/assign_string_flag.pass.cpp +++ b/test/std/re/re.regex/re.regex.assign/assign_string_flag.pass.cpp @@ -17,6 +17,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.regex/re.regex.assign/copy.pass.cpp b/test/std/re/re.regex/re.regex.assign/copy.pass.cpp index 2a616ff012c1d..3f212f772a38b 100644 --- a/test/std/re/re.regex/re.regex.assign/copy.pass.cpp +++ b/test/std/re/re.regex/re.regex.assign/copy.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.regex/re.regex.assign/il.pass.cpp b/test/std/re/re.regex/re.regex.assign/il.pass.cpp index a9d8ada4ff0ef..022170f2d1366 100644 --- a/test/std/re/re.regex/re.regex.assign/il.pass.cpp +++ b/test/std/re/re.regex/re.regex.assign/il.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.regex/re.regex.assign/ptr.pass.cpp b/test/std/re/re.regex/re.regex.assign/ptr.pass.cpp index 4c42f822a1e51..d2af1f9b3d1af 100644 --- a/test/std/re/re.regex/re.regex.assign/ptr.pass.cpp +++ b/test/std/re/re.regex/re.regex.assign/ptr.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.regex/re.regex.assign/string.pass.cpp b/test/std/re/re.regex/re.regex.assign/string.pass.cpp index 7f09e5364ac41..65cc4a345ed8e 100644 --- a/test/std/re/re.regex/re.regex.assign/string.pass.cpp +++ b/test/std/re/re.regex/re.regex.assign/string.pass.cpp @@ -16,6 +16,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.regex/re.regex.const/constants.pass.cpp b/test/std/re/re.regex/re.regex.const/constants.pass.cpp index 85297b91f4337..e699de819b0d8 100644 --- a/test/std/re/re.regex/re.regex.const/constants.pass.cpp +++ b/test/std/re/re.regex/re.regex.const/constants.pass.cpp @@ -27,6 +27,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" template <class _Tp> void where(const _Tp &) {} diff --git a/test/std/re/re.regex/re.regex.construct/awk_oct.pass.cpp b/test/std/re/re.regex/re.regex.construct/awk_oct.pass.cpp index 4b7e5e6292942..3f1eaf6b959ef 100644 --- a/test/std/re/re.regex/re.regex.construct/awk_oct.pass.cpp +++ b/test/std/re/re.regex/re.regex.construct/awk_oct.pass.cpp @@ -16,13 +16,14 @@ #include <regex> #include <cassert> +#include "test_macros.h" -int main() +int main() { using std::regex_constants::awk; assert(std::regex_match("\4", std::regex("\\4", awk))); assert(std::regex_match("\41", std::regex("\\41", awk))); assert(std::regex_match("\141", std::regex("\\141", awk))); - assert(std::regex_match("\1411", std::regex("\\1411", awk))); + assert(std::regex_match("\141" "1", std::regex("\\1411", awk))); } 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 9459cd74ccff0..3c7e9f5e33c73 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 @@ -17,8 +17,9 @@ #include <regex> #include <cassert> +#include "test_macros.h" -static bool error_escape_thrown(const char *pat) +static bool error_escape_thrown(const char *pat) { bool result = false; try { @@ -29,7 +30,7 @@ static bool error_escape_thrown(const char *pat) return result; } -int main() +int main() { assert(error_escape_thrown("[\\a]")); assert(error_escape_thrown("\\a")); 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 index c21672f02c98f..0692a59542f6b 100644 --- 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 @@ -17,8 +17,9 @@ #include <regex> #include <cassert> +#include "test_macros.h" -static bool error_badrepeat_thrown(const char *pat) +static bool error_badrepeat_thrown(const char *pat) { bool result = false; try { @@ -29,7 +30,7 @@ static bool error_badrepeat_thrown(const char *pat) return result; } -int main() +int main() { assert(error_badrepeat_thrown("?a")); assert(error_badrepeat_thrown("*a")); diff --git a/test/std/re/re.regex/re.regex.construct/copy.pass.cpp b/test/std/re/re.regex/re.regex.construct/copy.pass.cpp index c2788f0fa2c61..a266289c6a881 100644 --- a/test/std/re/re.regex/re.regex.construct/copy.pass.cpp +++ b/test/std/re/re.regex/re.regex.construct/copy.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.regex/re.regex.construct/default.pass.cpp b/test/std/re/re.regex/re.regex.construct/default.pass.cpp index d959c1ec58208..f1d7bf7696d91 100644 --- a/test/std/re/re.regex/re.regex.construct/default.pass.cpp +++ b/test/std/re/re.regex/re.regex.construct/default.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" template <class CharT> void diff --git a/test/std/re/re.regex/re.regex.construct/il_flg.pass.cpp b/test/std/re/re.regex/re.regex.construct/il_flg.pass.cpp index 70d28df370d11..c1554d6c3ebb7 100644 --- a/test/std/re/re.regex/re.regex.construct/il_flg.pass.cpp +++ b/test/std/re/re.regex/re.regex.construct/il_flg.pass.cpp @@ -16,6 +16,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS diff --git a/test/std/re/re.regex/re.regex.construct/iter_iter.pass.cpp b/test/std/re/re.regex/re.regex.construct/iter_iter.pass.cpp index a38e16234191a..4a93d173e6fcf 100644 --- a/test/std/re/re.regex/re.regex.construct/iter_iter.pass.cpp +++ b/test/std/re/re.regex/re.regex.construct/iter_iter.pass.cpp @@ -18,6 +18,7 @@ #include <cassert> #include "test_iterators.h" +#include "test_macros.h" template <class Iter> void diff --git a/test/std/re/re.regex/re.regex.construct/iter_iter_flg.pass.cpp b/test/std/re/re.regex/re.regex.construct/iter_iter_flg.pass.cpp index c4c440e6d2464..347989c5de151 100644 --- a/test/std/re/re.regex/re.regex.construct/iter_iter_flg.pass.cpp +++ b/test/std/re/re.regex/re.regex.construct/iter_iter_flg.pass.cpp @@ -19,6 +19,7 @@ #include <cassert> #include "test_iterators.h" +#include "test_macros.h" template <class Iter> void diff --git a/test/std/re/re.regex/re.regex.construct/ptr.pass.cpp b/test/std/re/re.regex/re.regex.construct/ptr.pass.cpp index b99b58b469cf4..05fba020566bc 100644 --- a/test/std/re/re.regex/re.regex.construct/ptr.pass.cpp +++ b/test/std/re/re.regex/re.regex.construct/ptr.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" template <class CharT> void diff --git a/test/std/re/re.regex/re.regex.construct/ptr_flg.pass.cpp b/test/std/re/re.regex/re.regex.construct/ptr_flg.pass.cpp index 138e20efbf657..d37b81592b4e7 100644 --- a/test/std/re/re.regex/re.regex.construct/ptr_flg.pass.cpp +++ b/test/std/re/re.regex/re.regex.construct/ptr_flg.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" template <class CharT> void diff --git a/test/std/re/re.regex/re.regex.construct/ptr_size_flg.pass.cpp b/test/std/re/re.regex/re.regex.construct/ptr_size_flg.pass.cpp index d623a15936f4a..a0ceb70514bfe 100644 --- a/test/std/re/re.regex/re.regex.construct/ptr_size_flg.pass.cpp +++ b/test/std/re/re.regex/re.regex.construct/ptr_size_flg.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" template <class CharT> void diff --git a/test/std/re/re.regex/re.regex.construct/string.pass.cpp b/test/std/re/re.regex/re.regex.construct/string.pass.cpp index b58b8e03cd208..a8f2e9bf6c20e 100644 --- a/test/std/re/re.regex/re.regex.construct/string.pass.cpp +++ b/test/std/re/re.regex/re.regex.construct/string.pass.cpp @@ -16,6 +16,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" template <class String> void diff --git a/test/std/re/re.regex/re.regex.construct/string_flg.pass.cpp b/test/std/re/re.regex/re.regex.construct/string_flg.pass.cpp index 768de568e2295..5f87af10224a4 100644 --- a/test/std/re/re.regex/re.regex.construct/string_flg.pass.cpp +++ b/test/std/re/re.regex/re.regex.construct/string_flg.pass.cpp @@ -17,6 +17,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" template <class String> void diff --git a/test/std/re/re.regex/re.regex.locale/imbue.pass.cpp b/test/std/re/re.regex/re.regex.locale/imbue.pass.cpp index c7ad39414c653..85900488f2351 100644 --- a/test/std/re/re.regex/re.regex.locale/imbue.pass.cpp +++ b/test/std/re/re.regex/re.regex.locale/imbue.pass.cpp @@ -19,6 +19,7 @@ #include <locale> #include <cassert> +#include "test_macros.h" #include "platform_support.h" // locale name macros int main() diff --git a/test/std/re/re.regex/re.regex.nonmemb/re.regex.nmswap/swap.pass.cpp b/test/std/re/re.regex/re.regex.nonmemb/re.regex.nmswap/swap.pass.cpp index 9d3c481686e78..7b231726557d6 100644 --- a/test/std/re/re.regex/re.regex.nonmemb/re.regex.nmswap/swap.pass.cpp +++ b/test/std/re/re.regex/re.regex.nonmemb/re.regex.nmswap/swap.pass.cpp @@ -16,6 +16,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.regex/re.regex.swap/swap.pass.cpp b/test/std/re/re.regex/re.regex.swap/swap.pass.cpp index cda8ef3541a2c..a04c64d4a471e 100644 --- a/test/std/re/re.regex/re.regex.swap/swap.pass.cpp +++ b/test/std/re/re.regex/re.regex.swap/swap.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.regex/types.pass.cpp b/test/std/re/re.regex/types.pass.cpp index 02011ac56ebb9..5c0a5920d2013 100644 --- a/test/std/re/re.regex/types.pass.cpp +++ b/test/std/re/re.regex/types.pass.cpp @@ -20,6 +20,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.results/re.results.acc/begin_end.pass.cpp b/test/std/re/re.results/re.results.acc/begin_end.pass.cpp index 80c06f299bd7c..a5ed051265ccd 100644 --- a/test/std/re/re.results/re.results.acc/begin_end.pass.cpp +++ b/test/std/re/re.results/re.results.acc/begin_end.pass.cpp @@ -16,6 +16,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" void test() diff --git a/test/std/re/re.results/re.results.acc/cbegin_cend.pass.cpp b/test/std/re/re.results/re.results.acc/cbegin_cend.pass.cpp index a983c8afc81a7..67ec606e9060b 100644 --- a/test/std/re/re.results/re.results.acc/cbegin_cend.pass.cpp +++ b/test/std/re/re.results/re.results.acc/cbegin_cend.pass.cpp @@ -16,6 +16,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" void test() diff --git a/test/std/re/re.results/re.results.acc/index.pass.cpp b/test/std/re/re.results/re.results.acc/index.pass.cpp index 79d4b9a237887..8118d3c9c3001 100644 --- a/test/std/re/re.results/re.results.acc/index.pass.cpp +++ b/test/std/re/re.results/re.results.acc/index.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" void test(std::regex_constants::syntax_option_type syntax) diff --git a/test/std/re/re.results/re.results.acc/length.pass.cpp b/test/std/re/re.results/re.results.acc/length.pass.cpp index 91020851a3088..7bf689c5b7909 100644 --- a/test/std/re/re.results/re.results.acc/length.pass.cpp +++ b/test/std/re/re.results/re.results.acc/length.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" void test() diff --git a/test/std/re/re.results/re.results.acc/position.pass.cpp b/test/std/re/re.results/re.results.acc/position.pass.cpp index 2698e2d91693e..b7df2c7c21c97 100644 --- a/test/std/re/re.results/re.results.acc/position.pass.cpp +++ b/test/std/re/re.results/re.results.acc/position.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" void test() diff --git a/test/std/re/re.results/re.results.acc/prefix.pass.cpp b/test/std/re/re.results/re.results.acc/prefix.pass.cpp index 58cdabc24df86..0c8572a0d713d 100644 --- a/test/std/re/re.results/re.results.acc/prefix.pass.cpp +++ b/test/std/re/re.results/re.results.acc/prefix.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" void test() diff --git a/test/std/re/re.results/re.results.acc/str.pass.cpp b/test/std/re/re.results/re.results.acc/str.pass.cpp index 2ebfeabb2078b..512bd9e69a88c 100644 --- a/test/std/re/re.results/re.results.acc/str.pass.cpp +++ b/test/std/re/re.results/re.results.acc/str.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" void test() diff --git a/test/std/re/re.results/re.results.acc/suffix.pass.cpp b/test/std/re/re.results/re.results.acc/suffix.pass.cpp index b842ea861e437..a78bb67b4f0da 100644 --- a/test/std/re/re.results/re.results.acc/suffix.pass.cpp +++ b/test/std/re/re.results/re.results.acc/suffix.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" void test() diff --git a/test/std/re/re.results/re.results.all/get_allocator.pass.cpp b/test/std/re/re.results/re.results.all/get_allocator.pass.cpp index 04367953ad29d..c4fe96d4a8a95 100644 --- a/test/std/re/re.results/re.results.all/get_allocator.pass.cpp +++ b/test/std/re/re.results/re.results.all/get_allocator.pass.cpp @@ -16,6 +16,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" template <class CharT, class Allocator> diff --git a/test/std/re/re.results/re.results.const/allocator.pass.cpp b/test/std/re/re.results/re.results.const/allocator.pass.cpp index a24c669f657de..73347d08c6945 100644 --- a/test/std/re/re.results/re.results.const/allocator.pass.cpp +++ b/test/std/re/re.results/re.results.const/allocator.pass.cpp @@ -16,6 +16,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" template <class CharT, class Allocator> diff --git a/test/std/re/re.results/re.results.const/default.pass.cpp b/test/std/re/re.results/re.results.const/default.pass.cpp index e10fbfd76cf0c..2fa85533a0ae0 100644 --- a/test/std/re/re.results/re.results.const/default.pass.cpp +++ b/test/std/re/re.results/re.results.const/default.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" template <class CharT> void diff --git a/test/std/re/re.results/re.results.form/form1.pass.cpp b/test/std/re/re.results/re.results.form/form1.pass.cpp index 5b04c684fef1a..55b5ade790a5d 100644 --- a/test/std/re/re.results/re.results.form/form1.pass.cpp +++ b/test/std/re/re.results/re.results.form/form1.pass.cpp @@ -19,6 +19,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" int main() diff --git a/test/std/re/re.results/re.results.form/form2.pass.cpp b/test/std/re/re.results/re.results.form/form2.pass.cpp index b18b7fb9f555b..ab7a525f48934 100644 --- a/test/std/re/re.results/re.results.form/form2.pass.cpp +++ b/test/std/re/re.results/re.results.form/form2.pass.cpp @@ -21,6 +21,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "test_allocator.h" diff --git a/test/std/re/re.results/re.results.form/form3.pass.cpp b/test/std/re/re.results/re.results.form/form3.pass.cpp index 27f2388adce0f..e4c2e3d202836 100644 --- a/test/std/re/re.results/re.results.form/form3.pass.cpp +++ b/test/std/re/re.results/re.results.form/form3.pass.cpp @@ -21,6 +21,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" int main() diff --git a/test/std/re/re.results/re.results.form/form4.pass.cpp b/test/std/re/re.results/re.results.form/form4.pass.cpp index 1d44c32f6a8bb..2c8aa9b8f9b50 100644 --- a/test/std/re/re.results/re.results.form/form4.pass.cpp +++ b/test/std/re/re.results/re.results.form/form4.pass.cpp @@ -19,6 +19,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.results/re.results.nonmember/equal.pass.cpp b/test/std/re/re.results/re.results.nonmember/equal.pass.cpp index 7902b8e642e49..0a32f2e258a9d 100644 --- a/test/std/re/re.results/re.results.nonmember/equal.pass.cpp +++ b/test/std/re/re.results/re.results.nonmember/equal.pass.cpp @@ -23,6 +23,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" void test() diff --git a/test/std/re/re.results/re.results.size/empty.pass.cpp b/test/std/re/re.results/re.results.size/empty.pass.cpp index 6634d92830dc7..f03f5f752b3dc 100644 --- a/test/std/re/re.results/re.results.size/empty.pass.cpp +++ b/test/std/re/re.results/re.results.size/empty.pass.cpp @@ -16,6 +16,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" template <class CharT> void diff --git a/test/std/re/re.results/re.results.size/max_size.pass.cpp b/test/std/re/re.results/re.results.size/max_size.pass.cpp index 0b31409275bf5..1ba29b926d5e8 100644 --- a/test/std/re/re.results/re.results.size/max_size.pass.cpp +++ b/test/std/re/re.results/re.results.size/max_size.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" template <class CharT> void diff --git a/test/std/re/re.results/re.results.state/ready.pass.cpp b/test/std/re/re.results/re.results.state/ready.pass.cpp index 8f586c3f32d65..1348016bbd915 100644 --- a/test/std/re/re.results/re.results.state/ready.pass.cpp +++ b/test/std/re/re.results/re.results.state/ready.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" void test1() diff --git a/test/std/re/re.results/re.results.swap/member_swap.pass.cpp b/test/std/re/re.results/re.results.swap/member_swap.pass.cpp index 09b85c0ff5d20..cd1d72a2d4d18 100644 --- a/test/std/re/re.results/re.results.swap/member_swap.pass.cpp +++ b/test/std/re/re.results/re.results.swap/member_swap.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" void test() diff --git a/test/std/re/re.results/re.results.swap/non_member_swap.pass.cpp b/test/std/re/re.results/re.results.swap/non_member_swap.pass.cpp index 3f5e34df44c5b..81e6c819e54cc 100644 --- a/test/std/re/re.results/re.results.swap/non_member_swap.pass.cpp +++ b/test/std/re/re.results/re.results.swap/non_member_swap.pass.cpp @@ -17,6 +17,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" void test() diff --git a/test/std/re/re.results/types.pass.cpp b/test/std/re/re.results/types.pass.cpp index 4d553837efe8b..0b76875feaeee 100644 --- a/test/std/re/re.results/types.pass.cpp +++ b/test/std/re/re.results/types.pass.cpp @@ -27,6 +27,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" template <class CharT> void diff --git a/test/std/re/re.submatch/re.submatch.members/compare_string_type.pass.cpp b/test/std/re/re.submatch/re.submatch.members/compare_string_type.pass.cpp index c14d5bcdefae7..be05afd4cf880 100644 --- a/test/std/re/re.submatch/re.submatch.members/compare_string_type.pass.cpp +++ b/test/std/re/re.submatch/re.submatch.members/compare_string_type.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.submatch/re.submatch.members/compare_sub_match.pass.cpp b/test/std/re/re.submatch/re.submatch.members/compare_sub_match.pass.cpp index 0874742f1c9ab..4b74f65d78261 100644 --- a/test/std/re/re.submatch/re.submatch.members/compare_sub_match.pass.cpp +++ b/test/std/re/re.submatch/re.submatch.members/compare_sub_match.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.submatch/re.submatch.members/compare_value_type_ptr.pass.cpp b/test/std/re/re.submatch/re.submatch.members/compare_value_type_ptr.pass.cpp index 48c05ca91d05a..097a3918ed131 100644 --- a/test/std/re/re.submatch/re.submatch.members/compare_value_type_ptr.pass.cpp +++ b/test/std/re/re.submatch/re.submatch.members/compare_value_type_ptr.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.submatch/re.submatch.members/default.pass.cpp b/test/std/re/re.submatch/re.submatch.members/default.pass.cpp index 451466af83cd8..1805f7eb3001f 100644 --- a/test/std/re/re.submatch/re.submatch.members/default.pass.cpp +++ b/test/std/re/re.submatch/re.submatch.members/default.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.submatch/re.submatch.members/length.pass.cpp b/test/std/re/re.submatch/re.submatch.members/length.pass.cpp index 4874c0d059218..20095483d80b1 100644 --- a/test/std/re/re.submatch/re.submatch.members/length.pass.cpp +++ b/test/std/re/re.submatch/re.submatch.members/length.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.submatch/re.submatch.members/operator_string.pass.cpp b/test/std/re/re.submatch/re.submatch.members/operator_string.pass.cpp index dd856a56d0b06..4c2877cd4db03 100644 --- a/test/std/re/re.submatch/re.submatch.members/operator_string.pass.cpp +++ b/test/std/re/re.submatch/re.submatch.members/operator_string.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.submatch/re.submatch.members/str.pass.cpp b/test/std/re/re.submatch/re.submatch.members/str.pass.cpp index ca5fd7d78ac76..9a821890178c8 100644 --- a/test/std/re/re.submatch/re.submatch.members/str.pass.cpp +++ b/test/std/re/re.submatch/re.submatch.members/str.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.submatch/re.submatch.op/compare.pass.cpp b/test/std/re/re.submatch/re.submatch.op/compare.pass.cpp index 36376aa0563c3..8000ab6b75ce0 100644 --- a/test/std/re/re.submatch/re.submatch.op/compare.pass.cpp +++ b/test/std/re/re.submatch/re.submatch.op/compare.pass.cpp @@ -215,6 +215,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" template <class CharT> void @@ -282,6 +283,6 @@ int main() test(std::string("1234"), std::string("123")); test(std::wstring(L"123"), std::wstring(L"123")); test(std::wstring(L"1234"), std::wstring(L"123")); - test(std::string("123\00056", 6), std::string("123\00056", 6), false); - test(std::wstring(L"123\00056", 6), std::wstring(L"123\00056", 6), false); + test(std::string("123\000" "56", 6), std::string("123\000" "56", 6), false); + test(std::wstring(L"123\000" L"56", 6), std::wstring(L"123\000" L"56", 6), false); } diff --git a/test/std/re/re.submatch/re.submatch.op/stream.pass.cpp b/test/std/re/re.submatch/re.submatch.op/stream.pass.cpp index 050bb062e7108..9f8c9869e12ee 100644 --- a/test/std/re/re.submatch/re.submatch.op/stream.pass.cpp +++ b/test/std/re/re.submatch/re.submatch.op/stream.pass.cpp @@ -18,6 +18,7 @@ #include <regex> #include <sstream> #include <cassert> +#include "test_macros.h" template <class CharT> void diff --git a/test/std/re/re.submatch/types.pass.cpp b/test/std/re/re.submatch/types.pass.cpp index 47c79149a8d3b..e5a00ca0416c7 100644 --- a/test/std/re/re.submatch/types.pass.cpp +++ b/test/std/re/re.submatch/types.pass.cpp @@ -26,6 +26,7 @@ #include <regex> #include <type_traits> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/cmatch.pass.cpp b/test/std/re/re.syn/cmatch.pass.cpp index 1364b7873ea51..bf467bcbc7724 100644 --- a/test/std/re/re.syn/cmatch.pass.cpp +++ b/test/std/re/re.syn/cmatch.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/cregex_iterator.pass.cpp b/test/std/re/re.syn/cregex_iterator.pass.cpp index 7b6ac133f5ace..ed5839da0ee52 100644 --- a/test/std/re/re.syn/cregex_iterator.pass.cpp +++ b/test/std/re/re.syn/cregex_iterator.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/cregex_token_iterator.pass.cpp b/test/std/re/re.syn/cregex_token_iterator.pass.cpp index 36ee9b66ea9d1..85dca0cf26020 100644 --- a/test/std/re/re.syn/cregex_token_iterator.pass.cpp +++ b/test/std/re/re.syn/cregex_token_iterator.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/csub_match.pass.cpp b/test/std/re/re.syn/csub_match.pass.cpp index e0de67b4feb75..2a87d8b6ef5c8 100644 --- a/test/std/re/re.syn/csub_match.pass.cpp +++ b/test/std/re/re.syn/csub_match.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/regex.pass.cpp b/test/std/re/re.syn/regex.pass.cpp index a208442b966c0..32fcb82f1a9c6 100644 --- a/test/std/re/re.syn/regex.pass.cpp +++ b/test/std/re/re.syn/regex.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/smatch.pass.cpp b/test/std/re/re.syn/smatch.pass.cpp index 87323538968e1..e2fc061133af8 100644 --- a/test/std/re/re.syn/smatch.pass.cpp +++ b/test/std/re/re.syn/smatch.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/sregex_iterator.pass.cpp b/test/std/re/re.syn/sregex_iterator.pass.cpp index 7acd96194b0e7..146316408ba6b 100644 --- a/test/std/re/re.syn/sregex_iterator.pass.cpp +++ b/test/std/re/re.syn/sregex_iterator.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/sregex_token_iterator.pass.cpp b/test/std/re/re.syn/sregex_token_iterator.pass.cpp index 185fd627b4fb5..aa85680c5a3bd 100644 --- a/test/std/re/re.syn/sregex_token_iterator.pass.cpp +++ b/test/std/re/re.syn/sregex_token_iterator.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/ssub_match.pass.cpp b/test/std/re/re.syn/ssub_match.pass.cpp index b378339664c00..181b7a307b587 100644 --- a/test/std/re/re.syn/ssub_match.pass.cpp +++ b/test/std/re/re.syn/ssub_match.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/wcmatch.pass.cpp b/test/std/re/re.syn/wcmatch.pass.cpp index 3ca8ed51eabc1..0eb125602305b 100644 --- a/test/std/re/re.syn/wcmatch.pass.cpp +++ b/test/std/re/re.syn/wcmatch.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/wcregex_iterator.pass.cpp b/test/std/re/re.syn/wcregex_iterator.pass.cpp index 99469ecf82b06..20c0d0d546e89 100644 --- a/test/std/re/re.syn/wcregex_iterator.pass.cpp +++ b/test/std/re/re.syn/wcregex_iterator.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/wcregex_token_iterator.pass.cpp b/test/std/re/re.syn/wcregex_token_iterator.pass.cpp index f16911f2985a7..01a7f3c746a9e 100644 --- a/test/std/re/re.syn/wcregex_token_iterator.pass.cpp +++ b/test/std/re/re.syn/wcregex_token_iterator.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/wcsub_match.pass.cpp b/test/std/re/re.syn/wcsub_match.pass.cpp index 7e8c872b6033a..f757d3f7c5ccf 100644 --- a/test/std/re/re.syn/wcsub_match.pass.cpp +++ b/test/std/re/re.syn/wcsub_match.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/wregex.pass.cpp b/test/std/re/re.syn/wregex.pass.cpp index 635eac0176cc6..23be43baa9145 100644 --- a/test/std/re/re.syn/wregex.pass.cpp +++ b/test/std/re/re.syn/wregex.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/wsmatch.pass.cpp b/test/std/re/re.syn/wsmatch.pass.cpp index 092c7d16d7a72..1483808bd8322 100644 --- a/test/std/re/re.syn/wsmatch.pass.cpp +++ b/test/std/re/re.syn/wsmatch.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/wsregex_iterator.pass.cpp b/test/std/re/re.syn/wsregex_iterator.pass.cpp index 0052716e46d8a..436e6d717f8a0 100644 --- a/test/std/re/re.syn/wsregex_iterator.pass.cpp +++ b/test/std/re/re.syn/wsregex_iterator.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/wsregex_token_iterator.pass.cpp b/test/std/re/re.syn/wsregex_token_iterator.pass.cpp index dc71991eb9b10..5ceb241f3dc15 100644 --- a/test/std/re/re.syn/wsregex_token_iterator.pass.cpp +++ b/test/std/re/re.syn/wsregex_token_iterator.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.syn/wssub_match.pass.cpp b/test/std/re/re.syn/wssub_match.pass.cpp index 2360a15513db5..23b92bb2d4ee8 100644 --- a/test/std/re/re.syn/wssub_match.pass.cpp +++ b/test/std/re/re.syn/wssub_match.pass.cpp @@ -13,6 +13,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.traits/default.pass.cpp b/test/std/re/re.traits/default.pass.cpp index defadd95378ba..b1e23587d21f7 100644 --- a/test/std/re/re.traits/default.pass.cpp +++ b/test/std/re/re.traits/default.pass.cpp @@ -19,6 +19,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "platform_support.h" // locale name macros int main() diff --git a/test/std/re/re.traits/getloc.pass.cpp b/test/std/re/re.traits/getloc.pass.cpp index 0b7810a2099d5..929659d004b0e 100644 --- a/test/std/re/re.traits/getloc.pass.cpp +++ b/test/std/re/re.traits/getloc.pass.cpp @@ -18,6 +18,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "platform_support.h" // locale name macros int main() diff --git a/test/std/re/re.traits/imbue.pass.cpp b/test/std/re/re.traits/imbue.pass.cpp index 6988058a832c7..04b4f5f7692b5 100644 --- a/test/std/re/re.traits/imbue.pass.cpp +++ b/test/std/re/re.traits/imbue.pass.cpp @@ -19,6 +19,7 @@ #include <locale> #include <cassert> +#include "test_macros.h" #include "platform_support.h" // locale name macros int main() diff --git a/test/std/re/re.traits/isctype.pass.cpp b/test/std/re/re.traits/isctype.pass.cpp index ad69f05ae75e5..3d1e7470a8837 100644 --- a/test/std/re/re.traits/isctype.pass.cpp +++ b/test/std/re/re.traits/isctype.pass.cpp @@ -13,8 +13,13 @@ // bool isctype(charT c, char_class_type f) const; +// TODO(EricWF): This test takes 40+ minutes to build with Clang 3.8 under ASAN or MSAN. +// UNSUPPORTED: asan, msan + + #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.traits/length.pass.cpp b/test/std/re/re.traits/length.pass.cpp index 473c233c531e7..b80f9b5b400ae 100644 --- a/test/std/re/re.traits/length.pass.cpp +++ b/test/std/re/re.traits/length.pass.cpp @@ -16,6 +16,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.traits/lookup_classname.pass.cpp b/test/std/re/re.traits/lookup_classname.pass.cpp index 0b1b18eb50774..4f7cf61ebf99c 100644 --- a/test/std/re/re.traits/lookup_classname.pass.cpp +++ b/test/std/re/re.traits/lookup_classname.pass.cpp @@ -18,6 +18,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" template <class char_type> @@ -33,6 +34,19 @@ test(const char_type* A, int main() { +// if __regex_word is not distinct from all the classes, bad things happen +// See https://llvm.org/bugs/show_bug.cgi?id=26476 for an example. + assert((std::ctype_base::space & std::regex_traits<char>::__regex_word) == 0); + assert((std::ctype_base::print & std::regex_traits<char>::__regex_word) == 0); + assert((std::ctype_base::cntrl & std::regex_traits<char>::__regex_word) == 0); + assert((std::ctype_base::upper & std::regex_traits<char>::__regex_word) == 0); + assert((std::ctype_base::lower & std::regex_traits<char>::__regex_word) == 0); + assert((std::ctype_base::alpha & std::regex_traits<char>::__regex_word) == 0); + assert((std::ctype_base::digit & std::regex_traits<char>::__regex_word) == 0); + assert((std::ctype_base::punct & std::regex_traits<char>::__regex_word) == 0); + assert((std::ctype_base::xdigit & std::regex_traits<char>::__regex_word) == 0); + assert((std::ctype_base::blank & std::regex_traits<char>::__regex_word) == 0); + test("d", std::ctype_base::digit); test("D", std::ctype_base::digit); test("d", std::ctype_base::digit, true); diff --git a/test/std/re/re.traits/lookup_collatename.pass.cpp b/test/std/re/re.traits/lookup_collatename.pass.cpp index a7cd5f0715612..3aeed7bddf755 100644 --- a/test/std/re/re.traits/lookup_collatename.pass.cpp +++ b/test/std/re/re.traits/lookup_collatename.pass.cpp @@ -23,8 +23,9 @@ #include <regex> #include <iterator> #include <cassert> -#include "test_iterators.h" +#include "test_macros.h" +#include "test_iterators.h" #include "platform_support.h" // locale name macros template <class char_type> diff --git a/test/std/re/re.traits/transform.pass.cpp b/test/std/re/re.traits/transform.pass.cpp index 85235e045d883..57e6b753abefa 100644 --- a/test/std/re/re.traits/transform.pass.cpp +++ b/test/std/re/re.traits/transform.pass.cpp @@ -19,8 +19,8 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" - #include "platform_support.h" // locale name macros int main() diff --git a/test/std/re/re.traits/transform_primary.pass.cpp b/test/std/re/re.traits/transform_primary.pass.cpp index 438cd75452bbb..03b4f3985a609 100644 --- a/test/std/re/re.traits/transform_primary.pass.cpp +++ b/test/std/re/re.traits/transform_primary.pass.cpp @@ -20,8 +20,9 @@ #include <regex> #include <cassert> -#include "test_iterators.h" +#include "test_macros.h" +#include "test_iterators.h" #include "platform_support.h" // locale name macros int main() diff --git a/test/std/re/re.traits/translate.pass.cpp b/test/std/re/re.traits/translate.pass.cpp index c3523387c56ba..7eaf30ea71c32 100644 --- a/test/std/re/re.traits/translate.pass.cpp +++ b/test/std/re/re.traits/translate.pass.cpp @@ -16,6 +16,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.traits/translate_nocase.pass.cpp b/test/std/re/re.traits/translate_nocase.pass.cpp index f9fa38ddf26a6..bf79629d33b4d 100644 --- a/test/std/re/re.traits/translate_nocase.pass.cpp +++ b/test/std/re/re.traits/translate_nocase.pass.cpp @@ -25,6 +25,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" #include "platform_support.h" int main() diff --git a/test/std/re/re.traits/types.pass.cpp b/test/std/re/re.traits/types.pass.cpp index 50586a1f29f37..611ef04342fec 100644 --- a/test/std/re/re.traits/types.pass.cpp +++ b/test/std/re/re.traits/types.pass.cpp @@ -20,6 +20,7 @@ #include <regex> #include <type_traits> +#include "test_macros.h" int main() { diff --git a/test/std/re/re.traits/value.pass.cpp b/test/std/re/re.traits/value.pass.cpp index 349a29cc6bc15..dfed66c35c46b 100644 --- a/test/std/re/re.traits/value.pass.cpp +++ b/test/std/re/re.traits/value.pass.cpp @@ -15,6 +15,7 @@ #include <regex> #include <cassert> +#include "test_macros.h" int main() { diff --git a/test/std/strings/basic.string.literals/literal.pass.cpp b/test/std/strings/basic.string.literals/literal.pass.cpp index dbb5f681395b2..d121e25ba2707 100644 --- a/test/std/strings/basic.string.literals/literal.pass.cpp +++ b/test/std/strings/basic.string.literals/literal.pass.cpp @@ -7,12 +7,14 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + #include <string> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 using namespace std::literals::string_literals; static_assert ( std::is_same<decltype( "Hi"s), std::string>::value, "" ); @@ -20,28 +22,27 @@ int main() static_assert ( std::is_same<decltype( L"Hi"s), std::wstring>::value, "" ); static_assert ( std::is_same<decltype( u"Hi"s), std::u16string>::value, "" ); static_assert ( std::is_same<decltype( U"Hi"s), std::u32string>::value, "" ); - + std::string foo; std::wstring Lfoo; std::u16string ufoo; std::u32string Ufoo; - + foo = ""s; assert( foo.size() == 0); foo = u8""s; assert( foo.size() == 0); Lfoo = L""s; assert(Lfoo.size() == 0); ufoo = u""s; assert(ufoo.size() == 0); Ufoo = U""s; assert(Ufoo.size() == 0); - + foo = " "s; assert( foo.size() == 1); foo = u8" "s; assert( foo.size() == 1); Lfoo = L" "s; assert(Lfoo.size() == 1); ufoo = u" "s; assert(ufoo.size() == 1); Ufoo = U" "s; assert(Ufoo.size() == 1); - + foo = "ABC"s; assert( foo == "ABC"); assert( foo == std::string ( "ABC")); foo = u8"ABC"s; assert( foo == u8"ABC"); assert( foo == std::string (u8"ABC")); Lfoo = L"ABC"s; assert(Lfoo == L"ABC"); assert(Lfoo == std::wstring ( L"ABC")); ufoo = u"ABC"s; assert(ufoo == u"ABC"); assert(ufoo == std::u16string( u"ABC")); Ufoo = U"ABC"s; assert(Ufoo == U"ABC"); assert(Ufoo == std::u32string( U"ABC")); -#endif } diff --git a/test/std/strings/basic.string.literals/literal1.fail.cpp b/test/std/strings/basic.string.literals/literal1.fail.cpp index 6ba0b30d458d5..721440d8a3a54 100644 --- a/test/std/strings/basic.string.literals/literal1.fail.cpp +++ b/test/std/strings/basic.string.literals/literal1.fail.cpp @@ -7,16 +7,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + #include <string> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 using std::string; string foo = ""s; // should fail w/conversion operator not found -#else -#error -#endif } diff --git a/test/std/strings/basic.string.literals/literal1.pass.cpp b/test/std/strings/basic.string.literals/literal1.pass.cpp index f5143746b0bb1..f0b7b463f85ef 100644 --- a/test/std/strings/basic.string.literals/literal1.pass.cpp +++ b/test/std/strings/basic.string.literals/literal1.pass.cpp @@ -7,14 +7,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + #include <string> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 using namespace std::literals; std::string foo = ""s; -#endif } diff --git a/test/std/strings/basic.string.literals/literal2.fail.cpp b/test/std/strings/basic.string.literals/literal2.fail.cpp index 68f1d254e3279..99f92fde97247 100644 --- a/test/std/strings/basic.string.literals/literal2.fail.cpp +++ b/test/std/strings/basic.string.literals/literal2.fail.cpp @@ -7,14 +7,13 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + #include <string> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 std::string foo = ""s; // should fail w/conversion operator not found -#else -#error -#endif } diff --git a/test/std/strings/basic.string.literals/literal2.pass.cpp b/test/std/strings/basic.string.literals/literal2.pass.cpp index 86d28e60e52b7..3cc2936a115dd 100644 --- a/test/std/strings/basic.string.literals/literal2.pass.cpp +++ b/test/std/strings/basic.string.literals/literal2.pass.cpp @@ -7,14 +7,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + #include <string> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 using namespace std::literals::string_literals; std::string foo = ""s; -#endif } diff --git a/test/std/strings/basic.string.literals/literal3.pass.cpp b/test/std/strings/basic.string.literals/literal3.pass.cpp index 98e3e40e058c9..d6e8c8f88ecd1 100644 --- a/test/std/strings/basic.string.literals/literal3.pass.cpp +++ b/test/std/strings/basic.string.literals/literal3.pass.cpp @@ -7,14 +7,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + #include <string> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 using namespace std; string foo = ""s; -#endif } diff --git a/test/std/strings/basic.string/string.access/at.pass.cpp b/test/std/strings/basic.string/string.access/at.pass.cpp index 87998e18c581a..8dc0c57cb7b4b 100644 --- a/test/std/strings/basic.string/string.access/at.pass.cpp +++ b/test/std/strings/basic.string/string.access/at.pass.cpp @@ -46,7 +46,7 @@ int main() test(S("123"), 2); test(S("123"), 3); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(), 0); diff --git a/test/std/strings/basic.string/string.access/back.pass.cpp b/test/std/strings/basic.string/string.access/back.pass.cpp index e91521441b801..adf22bf0d27b9 100644 --- a/test/std/strings/basic.string/string.access/back.pass.cpp +++ b/test/std/strings/basic.string/string.access/back.pass.cpp @@ -39,7 +39,7 @@ int main() test(S("1")); test(S("1234567890123456789012345678901234567890")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S("1")); diff --git a/test/std/strings/basic.string/string.access/db_back.pass.cpp b/test/std/strings/basic.string/string.access/db_back.pass.cpp index 2b31fabc7c702..e65ef2cef88d6 100644 --- a/test/std/strings/basic.string/string.access/db_back.pass.cpp +++ b/test/std/strings/basic.string/string.access/db_back.pass.cpp @@ -33,7 +33,7 @@ int main() assert(s.back() == 0); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s(1, '\0'); diff --git a/test/std/strings/basic.string/string.access/db_cback.pass.cpp b/test/std/strings/basic.string/string.access/db_cback.pass.cpp index 7feb4239f07a2..ee99aee10e329 100644 --- a/test/std/strings/basic.string/string.access/db_cback.pass.cpp +++ b/test/std/strings/basic.string/string.access/db_cback.pass.cpp @@ -31,7 +31,7 @@ int main() assert(s.back() == 0); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; const S s; diff --git a/test/std/strings/basic.string/string.access/db_cfront.pass.cpp b/test/std/strings/basic.string/string.access/db_cfront.pass.cpp index 9f7785b85cdad..13049624534f8 100644 --- a/test/std/strings/basic.string/string.access/db_cfront.pass.cpp +++ b/test/std/strings/basic.string/string.access/db_cfront.pass.cpp @@ -31,7 +31,7 @@ int main() assert(s.front() == 0); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; const S s; diff --git a/test/std/strings/basic.string/string.access/db_cindex.pass.cpp b/test/std/strings/basic.string/string.access/db_cindex.pass.cpp index 6294200104baf..f96ead7bf2514 100644 --- a/test/std/strings/basic.string/string.access/db_cindex.pass.cpp +++ b/test/std/strings/basic.string/string.access/db_cindex.pass.cpp @@ -32,7 +32,7 @@ int main() assert(s[1] == 0); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; const S s; diff --git a/test/std/strings/basic.string/string.access/db_front.pass.cpp b/test/std/strings/basic.string/string.access/db_front.pass.cpp index ff675bc5c2174..881a5ede37384 100644 --- a/test/std/strings/basic.string/string.access/db_front.pass.cpp +++ b/test/std/strings/basic.string/string.access/db_front.pass.cpp @@ -33,7 +33,7 @@ int main() assert(s.front() == 0); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s(1, '\0'); diff --git a/test/std/strings/basic.string/string.access/db_index.pass.cpp b/test/std/strings/basic.string/string.access/db_index.pass.cpp index b20e201880239..981a55d110375 100644 --- a/test/std/strings/basic.string/string.access/db_index.pass.cpp +++ b/test/std/strings/basic.string/string.access/db_index.pass.cpp @@ -32,7 +32,7 @@ int main() assert(s[1] == 0); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s; diff --git a/test/std/strings/basic.string/string.access/front.pass.cpp b/test/std/strings/basic.string/string.access/front.pass.cpp index ed80916f16f0c..5400ddb39dc0a 100644 --- a/test/std/strings/basic.string/string.access/front.pass.cpp +++ b/test/std/strings/basic.string/string.access/front.pass.cpp @@ -39,7 +39,7 @@ int main() test(S("1")); test(S("1234567890123456789012345678901234567890")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S("1")); diff --git a/test/std/strings/basic.string/string.access/index.pass.cpp b/test/std/strings/basic.string/string.access/index.pass.cpp index cd31623851602..b45a399320ba3 100644 --- a/test/std/strings/basic.string/string.access/index.pass.cpp +++ b/test/std/strings/basic.string/string.access/index.pass.cpp @@ -36,7 +36,7 @@ int main() const S s2 = S(); assert(s2[0] == '\0'); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s("0123456789"); diff --git a/test/std/strings/basic.string/string.capacity/capacity.pass.cpp b/test/std/strings/basic.string/string.capacity/capacity.pass.cpp index c05346a633e9a..4b09c096792c9 100644 --- a/test/std/strings/basic.string/string.capacity/capacity.pass.cpp +++ b/test/std/strings/basic.string/string.capacity/capacity.pass.cpp @@ -49,7 +49,7 @@ int main() s.erase(50); test(s); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s; diff --git a/test/std/strings/basic.string/string.capacity/clear.pass.cpp b/test/std/strings/basic.string/string.capacity/clear.pass.cpp index b73af7599344c..e0254c0460e4f 100644 --- a/test/std/strings/basic.string/string.capacity/clear.pass.cpp +++ b/test/std/strings/basic.string/string.capacity/clear.pass.cpp @@ -39,7 +39,7 @@ int main() s.erase(50); test(s); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s; diff --git a/test/std/strings/basic.string/string.capacity/empty.pass.cpp b/test/std/strings/basic.string/string.capacity/empty.pass.cpp index ac65f51448580..fbed5c36c3f42 100644 --- a/test/std/strings/basic.string/string.capacity/empty.pass.cpp +++ b/test/std/strings/basic.string/string.capacity/empty.pass.cpp @@ -31,7 +31,7 @@ int main() test(S("123")); test(S("12345678901234567890123456789012345678901234567890")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S()); diff --git a/test/std/strings/basic.string/string.capacity/length.pass.cpp b/test/std/strings/basic.string/string.capacity/length.pass.cpp index d3ae1aaee0363..13e966dc619ed 100644 --- a/test/std/strings/basic.string/string.capacity/length.pass.cpp +++ b/test/std/strings/basic.string/string.capacity/length.pass.cpp @@ -31,7 +31,7 @@ int main() test(S("123")); test(S("12345678901234567890123456789012345678901234567890")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S()); 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 d857be28a6c9f..fca14ddca561d 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 @@ -63,7 +63,7 @@ int main() test(S("123")); test(S("12345678901234567890123456789012345678901234567890")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S()); diff --git a/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp b/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp index 9c8f67950fb40..e92a0e1054f6f 100644 --- a/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp +++ b/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp @@ -37,7 +37,7 @@ int main() test(S("123")); test(S("12345678901234567890123456789012345678901234567890")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S()); diff --git a/test/std/strings/basic.string/string.capacity/reserve.pass.cpp b/test/std/strings/basic.string/string.capacity/reserve.pass.cpp index 569ca760c7ced..b2c254d1fb253 100644 --- a/test/std/strings/basic.string/string.capacity/reserve.pass.cpp +++ b/test/std/strings/basic.string/string.capacity/reserve.pass.cpp @@ -16,6 +16,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -25,7 +26,7 @@ test(S s) typename S::size_type old_cap = s.capacity(); S s0 = s; s.reserve(); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == s0); assert(s.capacity() <= old_cap); assert(s.capacity() >= s.size()); @@ -83,7 +84,7 @@ int main() test(s, S::npos); } } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; { diff --git a/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp b/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp index 16eca38e8012d..5589415995789 100644 --- a/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp +++ b/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp @@ -16,6 +16,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -25,7 +26,7 @@ test(S s, typename S::size_type n, S expected) try { s.resize(n); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(n <= s.max_size()); assert(s == expected); } @@ -56,7 +57,7 @@ int main() S("12345678901234567890123456789012345678901234567890\0\0\0\0\0\0\0\0\0\0", 60)); test(S(), S::npos, S("not going to happen")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(), 0, S()); diff --git a/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp b/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp index cb01be01f34b3..79f972b2fee36 100644 --- a/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp +++ b/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp @@ -16,6 +16,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -25,7 +26,7 @@ test(S s, typename S::size_type n, typename S::value_type c, S expected) try { s.resize(n, c); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(n <= s.max_size()); assert(s == expected); } @@ -56,7 +57,7 @@ int main() S("12345678901234567890123456789012345678901234567890aaaaaaaaaa")); test(S(), S::npos, 'a', S("not going to happen")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(), 0, 'a', S()); diff --git a/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp b/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp index aacbffd098f06..656ea1d11a7c0 100644 --- a/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp +++ b/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -23,7 +24,7 @@ test(S s) typename S::size_type old_cap = s.capacity(); S s0 = s; s.shrink_to_fit(); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == s0); assert(s.capacity() <= old_cap); assert(s.capacity() >= s.size()); @@ -44,7 +45,7 @@ int main() s.erase(50); test(s); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s; diff --git a/test/std/strings/basic.string/string.capacity/size.pass.cpp b/test/std/strings/basic.string/string.capacity/size.pass.cpp index 21b475a8113f1..4657aea442f7a 100644 --- a/test/std/strings/basic.string/string.capacity/size.pass.cpp +++ b/test/std/strings/basic.string/string.capacity/size.pass.cpp @@ -31,7 +31,7 @@ int main() test(S("123"), 3); test(S("12345678901234567890123456789012345678901234567890"), 50); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(), 0); 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 1c4f2044834e5..a803d331b8f65 100644 --- a/test/std/strings/basic.string/string.cons/alloc.pass.cpp +++ b/test/std/strings/basic.string/string.cons/alloc.pass.cpp @@ -29,7 +29,7 @@ test() static_assert((noexcept(S()) == noexcept(typename S::allocator_type())), "" ); #endif S s; - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s.data()); assert(s.size() == 0); assert(s.capacity() >= s.size()); @@ -42,7 +42,7 @@ test() 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()); + LIBCPP_ASSERT(s.__invariants()); assert(s.data()); assert(s.size() == 0); assert(s.capacity() >= s.size()); @@ -63,7 +63,7 @@ test2() static_assert((noexcept(S()) == noexcept(typename S::allocator_type())), "" ); #endif S s; - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s.data()); assert(s.size() == 0); assert(s.capacity() >= s.size()); @@ -76,7 +76,7 @@ test2() 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()); + LIBCPP_ASSERT(s.__invariants()); assert(s.data()); assert(s.size() == 0); assert(s.capacity() >= s.size()); diff --git a/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp b/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp index 1c582bc516373..f6bacb70e4ce5 100644 --- a/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp +++ b/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -22,7 +23,7 @@ test(S s1, typename S::value_type s2) { typedef typename S::traits_type T; s1 = s2; - assert(s1.__invariants()); + LIBCPP_ASSERT(s1.__invariants()); assert(s1.size() == 1); assert(T::eq(s1[0], s2)); assert(s1.capacity() >= s1.size()); @@ -37,7 +38,7 @@ int main() test(S("123456789"), 'a'); test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), 'a'); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(), 'a'); diff --git a/test/std/strings/basic.string/string.cons/copy.pass.cpp b/test/std/strings/basic.string/string.cons/copy.pass.cpp index 9c9fc32306685..cc4deb992a8b2 100644 --- a/test/std/strings/basic.string/string.cons/copy.pass.cpp +++ b/test/std/strings/basic.string/string.cons/copy.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" @@ -22,7 +23,7 @@ void test(S s1) { S s2 = s1; - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s2 == s1); assert(s2.capacity() >= s2.size()); assert(s2.get_allocator() == s1.get_allocator()); @@ -37,7 +38,7 @@ int main() test(S("1", A(5))); test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7))); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<char> A; typedef std::basic_string<char, std::char_traits<char>, A> S; diff --git a/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp b/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp index cf8021019a2ed..b3447b94b8038 100644 --- a/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp +++ b/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" @@ -22,7 +23,7 @@ void test(S s1, const typename S::allocator_type& a) { S s2(s1, a); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s2 == s1); assert(s2.capacity() >= s2.size()); assert(s2.get_allocator() == a); @@ -37,7 +38,7 @@ int main() test(S("1"), A(5)); test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<char> A; typedef std::basic_string<char, std::char_traits<char>, A> S; diff --git a/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp b/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp index ccb6c599974b0..b1e9108e90ba2 100644 --- a/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp +++ b/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp @@ -15,6 +15,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -22,7 +23,7 @@ void test(S s1, const S& s2) { s1 = s2; - assert(s1.__invariants()); + LIBCPP_ASSERT(s1.__invariants()); assert(s1 == s2); assert(s1.capacity() >= s1.size()); } @@ -47,7 +48,7 @@ int main() "1234567890123456789012345678901234567890123456789012345678901234567890"), S("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(), S()); 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 af117103d8276..87698ec551031 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <string> // basic_string() @@ -29,7 +31,6 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::string C; static_assert(std::is_nothrow_default_constructible<C>::value, ""); @@ -42,5 +43,4 @@ int main() typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C; static_assert(!std::is_nothrow_default_constructible<C>::value, ""); } -#endif } diff --git a/test/std/strings/basic.string/string.cons/dtor_noexcept.pass.cpp b/test/std/strings/basic.string/string.cons/dtor_noexcept.pass.cpp index b3cc127fbc46c..c4ac1f1a47bb0 100644 --- a/test/std/strings/basic.string/string.cons/dtor_noexcept.pass.cpp +++ b/test/std/strings/basic.string/string.cons/dtor_noexcept.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <string> // ~basic_string() // implied noexcept; @@ -16,8 +18,6 @@ #include "test_allocator.h" -#if __has_feature(cxx_noexcept) - template <class T> struct some_alloc { @@ -26,11 +26,8 @@ struct some_alloc ~some_alloc() noexcept(false); }; -#endif - int main() { -#if __has_feature(cxx_noexcept) { typedef std::string C; static_assert(std::is_nothrow_destructible<C>::value, ""); @@ -43,5 +40,4 @@ int main() typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C; static_assert(!std::is_nothrow_destructible<C>::value, ""); } -#endif } diff --git a/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp b/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp index d6ff8504e9daf..3007b9e8f68ca 100644 --- a/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp +++ b/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <string> // basic_string(initializer_list<charT> il, const Allocator& a = Allocator()); @@ -19,7 +21,6 @@ int main() { -#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS { std::string s = {'a', 'b', 'c'}; assert(s == "abc"); @@ -29,7 +30,6 @@ int main() s = {L'a', L'b', L'c'}; assert(s == L"abc"); } -#if __cplusplus >= 201103L { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s = {'a', 'b', 'c'}; @@ -41,6 +41,4 @@ int main() s = {L'a', L'b', L'c'}; assert(s == L"abc"); } -#endif -#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS } diff --git a/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp b/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp index 7530768953596..20279c853eafa 100644 --- a/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp +++ b/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <string> // basic_string& operator=(initializer_list<charT> il); @@ -18,19 +20,15 @@ int main() { -#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS { std::string s; s = {'a', 'b', 'c'}; assert(s == "abc"); } -#if __cplusplus >= 201103L { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s; s = {'a', 'b', 'c'}; assert(s == "abc"); } -#endif -#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS } diff --git a/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp b/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp index 664cb80b10fe6..cb0792ab23b3e 100644 --- a/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp +++ b/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp @@ -17,6 +17,7 @@ #include <iterator> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" #include "../input_iterator.h" #include "min_allocator.h" @@ -30,7 +31,7 @@ test(It first, It last) typedef typename S::traits_type T; typedef typename S::allocator_type A; S s2(first, last); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s2.size() == std::distance(first, last)); unsigned i = 0; for (It it = first; it != last; ++it, ++i) @@ -47,7 +48,7 @@ test(It first, It last, const A& a) typedef std::basic_string<charT, std::char_traits<charT>, A> S; typedef typename S::traits_type T; S s2(first, last, a); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s2.size() == std::distance(first, last)); unsigned i = 0; for (It it = first; it != last; ++it, ++i) @@ -86,7 +87,7 @@ int main() test(input_iterator<const char*>(s), input_iterator<const char*>(s+50)); test(input_iterator<const char*>(s), input_iterator<const char*>(s+50), A(2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<char> A; const char* s = "12345678901234567890123456789012345678901234567890"; diff --git a/test/std/strings/basic.string/string.cons/move.pass.cpp b/test/std/strings/basic.string/string.cons/move.pass.cpp index b94f189ecb469..9ed244406d018 100644 --- a/test/std/strings/basic.string/string.cons/move.pass.cpp +++ b/test/std/strings/basic.string/string.cons/move.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <string> // basic_string(basic_string<charT,traits,Allocator>&& str); @@ -14,8 +16,7 @@ #include <string> #include <cassert> -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - +#include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" @@ -25,18 +26,15 @@ test(S s0) { S s1 = s0; S s2 = std::move(s0); - assert(s2.__invariants()); - assert(s0.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); + LIBCPP_ASSERT(s0.__invariants()); assert(s2 == s1); assert(s2.capacity() >= s2.size()); assert(s2.get_allocator() == s1.get_allocator()); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - int main() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef test_allocator<char> A; typedef std::basic_string<char, std::char_traits<char>, A> S; @@ -44,7 +42,6 @@ int main() test(S("1", A(5))); test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7))); } -#if __cplusplus >= 201103L { typedef min_allocator<char> A; typedef std::basic_string<char, std::char_traits<char>, A> S; @@ -52,6 +49,4 @@ int main() test(S("1", A())); test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A())); } -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } 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 a232a46bd9fba..d4866921af7af 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <string> // basic_string(basic_string&& str, const Allocator& alloc); @@ -14,8 +16,6 @@ #include <string> #include <cassert> -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - #include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" @@ -27,23 +27,16 @@ test(S s0, const typename S::allocator_type& a) { S s1 = s0; S s2(std::move(s0), a); - assert(s2.__invariants()); - assert(s0.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); + LIBCPP_ASSERT(s0.__invariants()); assert(s2 == s1); assert(s2.capacity() >= s2.size()); assert(s2.get_allocator() == a); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -// #if _LIBCPP_STD_VER <= 14 -// _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); -// #else -// _NOEXCEPT; -// #endif int main() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef test_allocator<char> A; typedef std::basic_string<char, std::char_traits<char>, A> S; @@ -70,8 +63,6 @@ int main() S s2 (std::move(s1), A(1)); } assert ( test_alloc_base::alloc_count == alloc_count ); - -#if TEST_STD_VER >= 11 { typedef min_allocator<char> A; typedef std::basic_string<char, std::char_traits<char>, A> S; @@ -84,6 +75,4 @@ int main() test(S("1"), A()); test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A()); } -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp b/test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp index d7bd5e06bbe97..136a60fe627bf 100644 --- a/test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp +++ b/test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <string> // basic_string& operator=(basic_string&& c) @@ -36,7 +38,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -49,7 +51,7 @@ template <class T> struct some_alloc3 { typedef T value_type; - + some_alloc3() {} some_alloc3(const some_alloc3&); void deallocate(void*, unsigned) {} @@ -60,7 +62,6 @@ struct some_alloc3 int main() { -#if __has_feature(cxx_noexcept) { typedef std::string C; static_assert(std::is_nothrow_move_assignable<C>::value, ""); @@ -90,6 +91,4 @@ int main() static_assert(!std::is_nothrow_move_assignable<C>::value, ""); } #endif - -#endif } diff --git a/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp b/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp index 5bc1c8a9153fd..006b5b9b4cb0a 100644 --- a/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp +++ b/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <string> // basic_string<charT,traits,Allocator>& @@ -15,8 +17,7 @@ #include <string> #include <cassert> -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - +#include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" @@ -26,17 +27,14 @@ test(S s1, S s2) { S s0 = s2; s1 = std::move(s2); - assert(s1.__invariants()); - assert(s2.__invariants()); + LIBCPP_ASSERT(s1.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s1 == s0); assert(s1.capacity() >= s1.size()); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - int main() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::string S; test(S(), S()); @@ -55,7 +53,6 @@ int main() "1234567890123456789012345678901234567890123456789012345678901234567890"), S("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); } -#if __cplusplus >= 201103L { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(), S()); @@ -74,6 +71,4 @@ int main() "1234567890123456789012345678901234567890123456789012345678901234567890"), S("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); } -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } 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 b287a940cc82e..9a7c65ca2cf52 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <string> // basic_string(basic_string&&) @@ -29,7 +31,6 @@ struct some_alloc int main() { -#if __has_feature(cxx_noexcept) { typedef std::string C; static_assert(std::is_nothrow_move_constructible<C>::value, ""); @@ -46,5 +47,4 @@ int main() static_assert( std::is_nothrow_move_constructible<C>::value, ""); #endif } -#endif } diff --git a/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp b/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp index f6e9e00e590f5..b678247fb241b 100644 --- a/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp +++ b/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp @@ -16,6 +16,7 @@ #include <algorithm> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" @@ -28,7 +29,7 @@ test(const charT* s) typedef typename S::allocator_type A; unsigned n = T::length(s); S s2(s); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s2.size() == n); assert(T::compare(s2.data(), s, n) == 0); assert(s2.get_allocator() == A()); @@ -43,7 +44,7 @@ test(const charT* s, const A& a) typedef typename S::traits_type T; unsigned n = T::length(s); S s2(s, a); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s2.size() == n); assert(T::compare(s2.data(), s, n) == 0); assert(s2.get_allocator() == a); @@ -68,7 +69,7 @@ int main() test("123456798012345679801234567980123456798012345679801234567980"); test("123456798012345679801234567980123456798012345679801234567980", A(2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<char> A; typedef std::basic_string<char, std::char_traits<char>, A> S; diff --git a/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp b/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp index c691613379a27..506ab9374002e 100644 --- a/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp +++ b/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp @@ -15,6 +15,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -23,7 +24,7 @@ test(S s1, const typename S::value_type* s2) { typedef typename S::traits_type T; s1 = s2; - assert(s1.__invariants()); + LIBCPP_ASSERT(s1.__invariants()); assert(s1.size() == T::length(s2)); assert(T::compare(s1.data(), s2, s1.size()) == 0); assert(s1.capacity() >= s1.size()); @@ -49,7 +50,7 @@ int main() "1234567890123456789012345678901234567890123456789012345678901234567890"), "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(), ""); diff --git a/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp b/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp index f1f107af20bb1..bcab9eb6789e1 100644 --- a/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp +++ b/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp @@ -16,6 +16,7 @@ #include <algorithm> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" @@ -27,7 +28,7 @@ test(const charT* s, unsigned n) typedef typename S::traits_type T; typedef typename S::allocator_type A; S s2(s, n); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s2.size() == n); assert(T::compare(s2.data(), s, n) == 0); assert(s2.get_allocator() == A()); @@ -41,7 +42,7 @@ test(const charT* s, unsigned n, const A& a) typedef std::basic_string<charT, std::char_traits<charT>, A> S; typedef typename S::traits_type T; S s2(s, n, a); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s2.size() == n); assert(T::compare(s2.data(), s, n) == 0); assert(s2.get_allocator() == a); @@ -66,7 +67,7 @@ int main() test("123456798012345679801234567980123456798012345679801234567980", 60); test("123456798012345679801234567980123456798012345679801234567980", 60, A(2)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<char> A; typedef std::basic_string<char, std::char_traits<char>, A> S; diff --git a/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp b/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp index 4dfe9063a23eb..60d41b1d35be1 100644 --- a/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp +++ b/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp @@ -16,6 +16,7 @@ #include <algorithm> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" @@ -27,7 +28,7 @@ test(unsigned n, charT c) typedef typename S::traits_type T; typedef typename S::allocator_type A; S s2(n, c); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s2.size() == n); for (unsigned i = 0; i < n; ++i) assert(s2[i] == c); @@ -42,7 +43,7 @@ test(unsigned n, charT c, const A& a) typedef std::basic_string<charT, std::char_traits<charT>, A> S; typedef typename S::traits_type T; S s2(n, c, a); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s2.size() == n); for (unsigned i = 0; i < n; ++i) assert(s2[i] == c); @@ -59,7 +60,7 @@ test(Tp n, Tp c) typedef typename S::traits_type T; typedef typename S::allocator_type A; S s2(n, c); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s2.size() == n); for (unsigned i = 0; i < n; ++i) assert(s2[i] == c); @@ -75,7 +76,7 @@ test(Tp n, Tp c, const A& a) typedef std::basic_string<charT, std::char_traits<charT>, A> S; typedef typename S::traits_type T; S s2(n, c, a); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s2.size() == n); for (unsigned i = 0; i < n; ++i) assert(s2[i] == c); @@ -104,7 +105,7 @@ int main() test(100, 65); test(100, 65, A(3)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<char> A; typedef std::basic_string<char, std::char_traits<char>, A> S; diff --git a/test/std/strings/basic.string/string.cons/substr.pass.cpp b/test/std/strings/basic.string/string.cons/substr.pass.cpp index 2e42be13a842c..a10239bb34145 100644 --- a/test/std/strings/basic.string/string.cons/substr.pass.cpp +++ b/test/std/strings/basic.string/string.cons/substr.pass.cpp @@ -11,14 +11,21 @@ // <string> // basic_string(const basic_string<charT,traits,Allocator>& str, -// size_type pos, size_type n = npos, +// size_type pos, size_type n, +// const Allocator& a = Allocator()); +// +// basic_string(const basic_string<charT,traits,Allocator>& str, +// size_type pos, // const Allocator& a = Allocator()); #include <string> #include <stdexcept> #include <algorithm> +#include <vector> +#include <scoped_allocator> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" @@ -31,7 +38,7 @@ test(S str, unsigned pos) try { S s2(str, pos); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(pos <= str.size()); unsigned rlen = str.size() - pos; assert(s2.size() == rlen); @@ -54,7 +61,7 @@ test(S str, unsigned pos, unsigned n) try { S s2(str, pos, n); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(pos <= str.size()); unsigned rlen = std::min<unsigned>(str.size() - pos, n); assert(s2.size() == rlen); @@ -77,7 +84,7 @@ test(S str, unsigned pos, unsigned n, const typename S::allocator_type& a) try { S s2(str, pos, n, a); - assert(s2.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(pos <= str.size()); unsigned rlen = std::min<unsigned>(str.size() - pos, n); assert(s2.size() == rlen); @@ -91,6 +98,20 @@ test(S str, unsigned pos, unsigned n, const typename S::allocator_type& a) } } +#if TEST_STD_VER >= 11 +void test2583() +{ // LWG #2583 + typedef std::basic_string<char, std::char_traits<char>, test_allocator<char> > StringA; + std::vector<StringA, std::scoped_allocator_adaptor<test_allocator<StringA>>> vs; + StringA s{"1234"}; + vs.emplace_back(s, 2); + + try { vs.emplace_back(s, 5); } + catch (const std::out_of_range&) { return; } + assert(false); +} +#endif + int main() { { @@ -131,7 +152,7 @@ int main() test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 10, A(8)); test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 100, A(8)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<char> A; typedef std::basic_string<char, std::char_traits<char>, A> S; @@ -170,5 +191,7 @@ int main() test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 10, A()); test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 100, A()); } + + test2583(); #endif } diff --git a/test/std/strings/basic.string/string.iterators/begin.pass.cpp b/test/std/strings/basic.string/string.iterators/begin.pass.cpp index 55f2eb30f80a2..ea811113dfe9a 100644 --- a/test/std/strings/basic.string/string.iterators/begin.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/begin.pass.cpp @@ -38,7 +38,7 @@ int main() test(S()); test(S("123")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S()); diff --git a/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp b/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp index d0c6ddbb95085..fb4b4bdc3d8ec 100644 --- a/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp @@ -35,7 +35,7 @@ int main() test(S()); test(S("123")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S()); diff --git a/test/std/strings/basic.string/string.iterators/cend.pass.cpp b/test/std/strings/basic.string/string.iterators/cend.pass.cpp index 6b86d263245b4..9ee56be783a2a 100644 --- a/test/std/strings/basic.string/string.iterators/cend.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/cend.pass.cpp @@ -31,7 +31,7 @@ int main() test(S()); test(S("123")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S()); diff --git a/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp b/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp index 6f29f433f314f..90988a39a35e8 100644 --- a/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp @@ -35,7 +35,7 @@ int main() test(S()); test(S("123")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S()); diff --git a/test/std/strings/basic.string/string.iterators/crend.pass.cpp b/test/std/strings/basic.string/string.iterators/crend.pass.cpp index 1fb422c080ac2..bb383787fe492 100644 --- a/test/std/strings/basic.string/string.iterators/crend.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/crend.pass.cpp @@ -31,7 +31,7 @@ int main() test(S()); test(S("123")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S()); diff --git a/test/std/strings/basic.string/string.iterators/db_iterators_2.pass.cpp b/test/std/strings/basic.string/string.iterators/db_iterators_2.pass.cpp index 6cac1875ce813..e46368c7717af 100644 --- a/test/std/strings/basic.string/string.iterators/db_iterators_2.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/db_iterators_2.pass.cpp @@ -32,7 +32,7 @@ int main() bool b = s1.begin() < s2.begin(); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s1; diff --git a/test/std/strings/basic.string/string.iterators/db_iterators_3.pass.cpp b/test/std/strings/basic.string/string.iterators/db_iterators_3.pass.cpp index d90387e3a46dd..3ed15d7c0c04f 100644 --- a/test/std/strings/basic.string/string.iterators/db_iterators_3.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/db_iterators_3.pass.cpp @@ -32,7 +32,7 @@ int main() int i = s1.begin() - s2.begin(); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s1; diff --git a/test/std/strings/basic.string/string.iterators/db_iterators_4.pass.cpp b/test/std/strings/basic.string/string.iterators/db_iterators_4.pass.cpp index c4a2d0a4baf6c..85ea2201f2a0c 100644 --- a/test/std/strings/basic.string/string.iterators/db_iterators_4.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/db_iterators_4.pass.cpp @@ -33,7 +33,7 @@ int main() assert(i[1] == 0); assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> C; C c(1, '\0'); diff --git a/test/std/strings/basic.string/string.iterators/db_iterators_5.pass.cpp b/test/std/strings/basic.string/string.iterators/db_iterators_5.pass.cpp index ce44cb1ba5b48..9702090e41f8c 100644 --- a/test/std/strings/basic.string/string.iterators/db_iterators_5.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/db_iterators_5.pass.cpp @@ -35,7 +35,7 @@ int main() i += 2; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> C; C c(1, '\0'); diff --git a/test/std/strings/basic.string/string.iterators/db_iterators_6.pass.cpp b/test/std/strings/basic.string/string.iterators/db_iterators_6.pass.cpp index 8fab8babc6134..e42ba4cf15d76 100644 --- a/test/std/strings/basic.string/string.iterators/db_iterators_6.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/db_iterators_6.pass.cpp @@ -34,7 +34,7 @@ int main() --i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> C; C c(1, '\0'); diff --git a/test/std/strings/basic.string/string.iterators/db_iterators_7.pass.cpp b/test/std/strings/basic.string/string.iterators/db_iterators_7.pass.cpp index d1cac07e222b6..69a682142c144 100644 --- a/test/std/strings/basic.string/string.iterators/db_iterators_7.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/db_iterators_7.pass.cpp @@ -34,7 +34,7 @@ int main() ++i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> C; C c(1, '\0'); diff --git a/test/std/strings/basic.string/string.iterators/db_iterators_8.pass.cpp b/test/std/strings/basic.string/string.iterators/db_iterators_8.pass.cpp index 914c77d48c5c7..5472773e6dfeb 100644 --- a/test/std/strings/basic.string/string.iterators/db_iterators_8.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/db_iterators_8.pass.cpp @@ -32,7 +32,7 @@ int main() char j = *i; assert(false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> C; C c(1, '\0'); diff --git a/test/std/strings/basic.string/string.iterators/end.pass.cpp b/test/std/strings/basic.string/string.iterators/end.pass.cpp index 02180bbd73de2..abd0c2d853dc5 100644 --- a/test/std/strings/basic.string/string.iterators/end.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/end.pass.cpp @@ -40,7 +40,7 @@ int main() test(S()); test(S("123")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S()); diff --git a/test/std/strings/basic.string/string.iterators/iterators.pass.cpp b/test/std/strings/basic.string/string.iterators/iterators.pass.cpp index 386cededa53fb..9466f11351023 100644 --- a/test/std/strings/basic.string/string.iterators/iterators.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/iterators.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 + // <string> // iterator begin(); @@ -21,7 +23,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 { // N3644 testing typedef std::string C; C::iterator ii1{}, ii2{}; @@ -40,7 +41,7 @@ int main() C::iterator ii4 = ii1; C::const_iterator cii{}; assert ( ii1 == ii2 ); - assert ( ii1 == ii4 ); + assert ( ii1 == ii4 ); assert ( ii1 == cii ); assert ( !(ii1 != ii2 )); assert ( !(ii1 != cii )); @@ -69,5 +70,4 @@ int main() assert ( !(ii1 != ii2 )); assert ( !(ii1 != cii )); } -#endif } diff --git a/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp b/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp index 0111ad113638f..698d613ca6ada 100644 --- a/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp @@ -38,7 +38,7 @@ int main() test(S()); test(S("123")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S()); diff --git a/test/std/strings/basic.string/string.iterators/rend.pass.cpp b/test/std/strings/basic.string/string.iterators/rend.pass.cpp index 750173dc342e5..c8c2d9ccadcad 100644 --- a/test/std/strings/basic.string/string.iterators/rend.pass.cpp +++ b/test/std/strings/basic.string/string.iterators/rend.pass.cpp @@ -40,7 +40,7 @@ int main() test(S()); test(S("123")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S()); diff --git a/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp index 2abfbf0a172bc..d30ca44695a83 100644 --- a/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <string> // basic_string& append(initializer_list<charT> il); @@ -14,23 +16,20 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" int main() { -#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS { std::string s("123"); s.append({'a', 'b', 'c'}); assert(s == "123abc"); } -#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s("123"); s.append({'a', 'b', 'c'}); assert(s == "123abc"); } -#endif -#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS } diff --git a/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp index 82e6fb5895e7c..55fc63d062145 100644 --- a/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp @@ -23,10 +23,11 @@ void test(S s, It first, It last, S expected) { s.append(first, last); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } +#ifndef TEST_HAS_NO_EXCEPTIONS template <class S, class It> void test_exceptions(S s, It first, It last) @@ -37,9 +38,10 @@ test_exceptions(S s, It first, It last) assert(false); } catch (...) {} - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == aCopy); } +#endif int main() { @@ -161,6 +163,7 @@ int main() S("12345678901234567890""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); } #endif +#ifndef TEST_HAS_NO_EXCEPTIONS { // test iterator operations that throw typedef std::string S; typedef ThrowingIterator<char> TIter; @@ -174,4 +177,5 @@ int main() test_exceptions(S(), TIter(s, s+10, 5, TIter::TADereference), TIter()); test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter()); } +#endif } diff --git a/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp index c0413d607e8f2..7c45068a53e19 100644 --- a/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp @@ -15,6 +15,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -22,7 +23,7 @@ void test(S s, const typename S::value_type* str, S expected) { s.append(str); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp index f3ea3b0a89d79..6c594ebac3be9 100644 --- a/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp @@ -16,6 +16,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -23,7 +24,7 @@ void test(S s, const typename S::value_type* str, typename S::size_type n, S expected) { s.append(str, n); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp index d6116d3f48239..f2fb8782a21da 100644 --- a/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -21,7 +22,7 @@ void test(S s, typename S::value_type c, S expected) { s.push_back(c); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp index a049e6112a8a7..1610ab5a17d1e 100644 --- a/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp @@ -15,6 +15,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -22,7 +23,7 @@ void test(S s, typename S::size_type n, typename S::value_type c, S expected) { s.append(n, c); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp index e25627fa6a24c..b58ed632893e1 100644 --- a/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp @@ -15,6 +15,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -22,7 +23,7 @@ void test(S s, S str, S expected) { s.append(str); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp index d67b0304b41aa..9e8158c3e43e5 100644 --- a/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp @@ -18,6 +18,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -27,7 +28,7 @@ test(S s, S str, typename S::size_type pos, typename S::size_type n, S expected) try { s.append(str, pos, n); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos <= str.size()); assert(s == expected); } @@ -44,7 +45,7 @@ test_npos(S s, S str, typename S::size_type pos, S expected) try { s.append(str, pos); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos <= str.size()); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp index 003af0eef827a..a2114cf5a83b6 100644 --- a/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <string> // basic_string& assign(initializer_list<charT> il); @@ -14,23 +16,20 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" int main() { -#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS { std::string s("123"); s.assign({'a', 'b', 'c'}); assert(s == "abc"); } -#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s("123"); s.assign({'a', 'b', 'c'}); assert(s == "abc"); } -#endif -#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS } diff --git a/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp index 690aebd4c2a69..e6a57519f34be 100644 --- a/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp @@ -15,6 +15,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "test_iterators.h" #include "min_allocator.h" @@ -23,10 +24,11 @@ void test(S s, It first, It last, S expected) { s.assign(first, last); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } +#ifndef TEST_HAS_NO_EXCEPTIONS template <class S, class It> void test_exceptions(S s, It first, It last) @@ -35,11 +37,12 @@ test_exceptions(S s, It first, It last) try { s.assign(first, last); assert(false); - } + } catch (...) {} - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == aCopy); } +#endif int main() { @@ -101,7 +104,7 @@ int main() test(S("12345678901234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+52), S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; @@ -161,6 +164,7 @@ int main() S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); } #endif +#ifndef TEST_HAS_NO_EXCEPTIONS { // test iterator operations that throw typedef std::string S; typedef ThrowingIterator<char> TIter; @@ -174,4 +178,5 @@ int main() test_exceptions(S(), TIter(s, s+10, 5, TIter::TADereference), TIter()); test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter()); } +#endif } diff --git a/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp index 07dbcea704dc2..386dee6d58087 100644 --- a/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp @@ -15,6 +15,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -22,7 +23,7 @@ void test(S s, const typename S::value_type* str, S expected) { s.assign(str); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp index a9c71cec882bb..0eeb9266f40fa 100644 --- a/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp @@ -16,6 +16,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -23,7 +24,7 @@ void test(S s, const typename S::value_type* str, typename S::size_type n, S expected) { s.assign(str, n); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp index b3d225a8d04a9..6b89df98de72b 100644 --- a/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp @@ -16,6 +16,7 @@ #include <utility> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -23,7 +24,7 @@ void test(S s, S str, S expected) { s.assign(std::move(str)); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp index 9dd19d877c902..a899e0dbe7b55 100644 --- a/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp @@ -15,6 +15,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -22,7 +23,7 @@ void test(S s, typename S::size_type n, typename S::value_type c, S expected) { s.assign(n, c); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp index 2bc5dd223e62f..788512ba3d3e8 100644 --- a/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp @@ -15,17 +15,29 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" +#include "test_allocator.h" template <class S> void test(S s, S str, S expected) { s.assign(str); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } +template <class S> +void +testAlloc(S s, S str, const typename S::allocator_type& a) +{ + s.assign(str); + LIBCPP_ASSERT(s.__invariants()); + assert(s == str); + assert(s.get_allocator() == a); +} + int main() { { @@ -50,7 +62,22 @@ int main() test(S("12345678901234567890"), S("1234567890"), S("1234567890")); test(S("12345678901234567890"), S("12345678901234567890"), S("12345678901234567890")); + + testAlloc(S(), S(), std::allocator<char>()); + testAlloc(S(), S("12345"), std::allocator<char>()); + testAlloc(S(), S("1234567890"), std::allocator<char>()); + testAlloc(S(), S("12345678901234567890"), std::allocator<char>()); + } + + { // LWG#5579 make sure assign takes the allocators where appropriate + typedef other_allocator<char> A; // has POCCA --> true + typedef std::basic_string<char, std::char_traits<char>, A> S; + testAlloc(S(A(5)), S(A(3)), A(3)); + testAlloc(S(A(5)), S("1"), A()); + testAlloc(S(A(5)), S("1", A(7)), A(7)); + testAlloc(S(A(5)), S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), A(7)); } + #if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; @@ -74,9 +101,14 @@ int main() test(S("12345678901234567890"), S("1234567890"), S("1234567890")); test(S("12345678901234567890"), S("12345678901234567890"), S("12345678901234567890")); + + testAlloc(S(), S(), min_allocator<char>()); + testAlloc(S(), S("12345"), min_allocator<char>()); + testAlloc(S(), S("1234567890"), min_allocator<char>()); + testAlloc(S(), S("12345678901234567890"), min_allocator<char>()); } #endif -#if __cplusplus > 201402L +#if TEST_STD_VER > 14 { typedef std::string S; static_assert(noexcept(S().assign(S())), ""); // LWG#2063 diff --git a/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp index 275d249d304cb..d9d3cb422ae50 100644 --- a/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp @@ -18,6 +18,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -27,7 +28,7 @@ test(S s, S str, typename S::size_type pos, typename S::size_type n, S expected) try { s.assign(str, pos, n); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos <= str.size()); assert(s == expected); } @@ -44,7 +45,7 @@ test_npos(S s, S str, typename S::size_type pos, S expected) try { s.assign(str, pos); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos <= str.size()); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_copy/copy.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_copy/copy.pass.cpp index 69f001cf4f001..b66877652837f 100644 --- a/test/std/strings/basic.string/string.modifiers/string_copy/copy.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_copy/copy.pass.cpp @@ -17,6 +17,7 @@ #include <algorithm> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -104,7 +105,7 @@ int main() test(S("abcdefghijklmnopqrst"), s, 20, 1); test(S("abcdefghijklmnopqrst"), s, 21, 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; char s[50]; diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp index c44db71ae3b0a..8de5fc7bab85a 100644 --- a/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -22,7 +23,7 @@ test(S s, typename S::difference_type pos, S expected) { typename S::const_iterator p = s.begin() + pos; typename S::iterator i = s.erase(p); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); assert(i - s.begin() == pos); } @@ -44,7 +45,7 @@ int main() test(S("abcdefghijklmnopqrst"), 10, S("abcdefghijlmnopqrst")); test(S("abcdefghijklmnopqrst"), 19, S("abcdefghijklmnopqrs")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S("abcde"), 0, S("bcde")); diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp index dbe6d7ba0e738..e4fe2cdfd0223 100644 --- a/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -23,7 +24,7 @@ test(S s, typename S::difference_type pos, typename S::difference_type n, S expe typename S::const_iterator first = s.cbegin() + pos; typename S::const_iterator last = s.cbegin() + pos + n; typename S::iterator i = s.erase(first, last); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); assert(i - s.begin() == pos); } @@ -87,7 +88,7 @@ int main() test(S("abcdefghijklmnopqrst"), 19, 1, S("abcdefghijklmnopqrs")); test(S("abcdefghijklmnopqrst"), 20, 0, S("abcdefghijklmnopqrst")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), 0, 0, S("")); diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp index 790ce40b0a00f..64f8e506b13ef 100644 --- a/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp @@ -11,13 +11,10 @@ // void pop_back(); -#if _LIBCPP_DEBUG >= 1 -#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) -#endif - #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -25,7 +22,7 @@ void test(S s, S expected) { s.pop_back(); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } @@ -37,7 +34,7 @@ int main() test(S("abcdefghij"), S("abcdefghi")); test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrs")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S("abcde"), S("abcd")); @@ -45,11 +42,4 @@ int main() test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrs")); } #endif -#if _LIBCPP_DEBUG >= 1 - { - std::string s; - s.pop_back(); - assert(false); - } -#endif } diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp index 11015cb973ed5..5db97ec2cf5fe 100644 --- a/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp @@ -17,6 +17,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -28,7 +29,7 @@ test(S s, typename S::size_type pos, typename S::size_type n, S expected) try { s.erase(pos, n); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos <= old_size); assert(s == expected); } @@ -48,7 +49,7 @@ test(S s, typename S::size_type pos, S expected) try { s.erase(pos); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos <= old_size); assert(s == expected); } @@ -64,7 +65,7 @@ void test(S s, S expected) { s.erase(); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } @@ -173,7 +174,7 @@ int main() test(S("abcdefghij"), S("")); test(S("abcdefghijklmnopqrst"), S("")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), 0, 0, S("")); diff --git a/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp index 6b0a3aa006ee0..6bd9b7e01c377 100644 --- a/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp @@ -11,14 +11,11 @@ // iterator insert(const_iterator p, charT c); -#if _LIBCPP_DEBUG >= 1 -#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) -#endif - #include <string> #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -28,7 +25,7 @@ test(S& s, typename S::const_iterator p, typename S::value_type c, S expected) bool sufficient_cap = s.size() < s.capacity(); typename S::difference_type pos = p - s.begin(); typename S::iterator i = s.insert(p, c); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); assert(i - s.begin() == pos); assert(*i == c); @@ -76,13 +73,4 @@ int main() test(s, s.begin()+6, 'C', S("a567ABC1432dcb")); } #endif -#if _LIBCPP_DEBUG >= 1 - { - typedef std::string S; - S s; - S s2; - s.insert(s2.begin(), '1'); - assert(false); - } -#endif } diff --git a/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp index 4c29ab4ed0933..bbae39419da4c 100644 --- a/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp @@ -28,11 +28,12 @@ test(S s, typename S::difference_type pos, It first, It last, S expected) { typename S::const_iterator p = s.cbegin() + pos; typename S::iterator i = s.insert(p, first, last); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(i - s.begin() == pos); assert(s == expected); } +#ifndef TEST_HAS_NO_EXCEPTIONS template <class S, class It> void test_exceptions(S s, typename S::difference_type pos, It first, It last) @@ -44,9 +45,10 @@ test_exceptions(S s, typename S::difference_type pos, It first, It last) assert(false); } catch (...) {} - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == aCopy); } +#endif int main() { @@ -142,6 +144,7 @@ int main() S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); } #endif +#ifndef TEST_HAS_NO_EXCEPTIONS { // test iterator operations that throw typedef std::string S; typedef ThrowingIterator<char> TIter; @@ -155,6 +158,7 @@ int main() test_exceptions(S(), 0, TIter(s, s+10, 5, TIter::TADereference), TIter()); test_exceptions(S(), 0, TIter(s, s+10, 6, TIter::TAComparison), TIter()); } +#endif #if _LIBCPP_DEBUG >= 1 { std::string v; diff --git a/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp index e6d1db6fc0df5..c9cd0c2c9248d 100644 --- a/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp @@ -11,13 +11,10 @@ // iterator insert(const_iterator p, size_type n, charT c); -#if _LIBCPP_DEBUG >= 1 -#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) -#endif - #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -27,7 +24,7 @@ test(S s, typename S::difference_type pos, typename S::size_type n, { typename S::const_iterator p = s.cbegin() + pos; typename S::iterator i = s.insert(p, n, c); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(i - s.begin() == pos); assert(s == expected); } @@ -170,12 +167,4 @@ int main() test(S("abcdefghijklmnopqrst"), 20, 20, '1', S("abcdefghijklmnopqrst11111111111111111111")); } #endif -#if _LIBCPP_DEBUG >= 1 - { - std::string s; - std::string s2; - s.insert(s2.begin(), 1, 'a'); - assert(false); - } -#endif } diff --git a/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp index 247b3308f96e4..faab5bd926721 100644 --- a/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp @@ -17,6 +17,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -28,7 +29,7 @@ test(S s, typename S::size_type pos, const typename S::value_type* str, S expect try { s.insert(pos, str); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos <= old_size); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp index 41b81231075ed..30d3df9f259fd 100644 --- a/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp @@ -17,6 +17,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -29,7 +30,7 @@ test(S s, typename S::size_type pos, const typename S::value_type* str, try { s.insert(pos, str, n); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos <= old_size); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp index 945ec48012bad..04ea1d3769407 100644 --- a/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp @@ -17,6 +17,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -29,7 +30,7 @@ test(S s, typename S::size_type pos, typename S::size_type n, try { s.insert(pos, n, str); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos <= old_size); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp index 04b47ec789887..1945871b99ac6 100644 --- a/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp @@ -17,6 +17,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -28,7 +29,7 @@ test(S s, typename S::size_type pos, S str, S expected) try { s.insert(pos, str); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos <= old_size); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp index c3745c3749db8..32485db478d82 100644 --- a/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp @@ -19,6 +19,7 @@ #include <stdexcept> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -31,7 +32,7 @@ test(S s, typename S::size_type pos1, S str, typename S::size_type pos2, try { s.insert(pos1, str, pos2, n); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos1 <= old_size && pos2 <= str.size()); assert(s == expected); } @@ -51,7 +52,7 @@ test_npos(S s, typename S::size_type pos1, S str, typename S::size_type pos2, S try { s.insert(pos1, str, pos2); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos1 <= old_size && pos2 <= str.size()); assert(s == expected); } diff --git a/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp index 7384ae7f1d3c4..f39ed036e1491 100644 --- a/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -21,7 +22,7 @@ void test(S s, typename S::value_type str, S expected) { s += str; - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } @@ -34,7 +35,7 @@ int main() test(S("1234567890"), 'a', S("1234567890a")); test(S("12345678901234567890"), 'a', S("12345678901234567890a")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(), 'a', S("a")); diff --git a/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp index c291028998df4..5b32af9516242 100644 --- a/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <string> // basic_string& operator+=(initializer_list<charT> il); @@ -18,19 +20,15 @@ int main() { -#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS { std::string s("123"); s += {'a', 'b', 'c'}; assert(s == "123abc"); } -#if __cplusplus >= 201103L { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s("123"); s += {'a', 'b', 'c'}; assert(s == "123abc"); } -#endif -#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS } diff --git a/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/pointer.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/pointer.pass.cpp index 77b20d1bc0806..c19fd2909011b 100644 --- a/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/pointer.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/pointer.pass.cpp @@ -14,6 +14,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -21,7 +22,7 @@ void test(S s, const typename S::value_type* str, S expected) { s += str; - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } @@ -50,7 +51,7 @@ int main() test(S("12345678901234567890"), "12345678901234567890", S("1234567890123456789012345678901234567890")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(), "", S()); diff --git a/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp index 33649792521cd..1064855c1506c 100644 --- a/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp @@ -15,6 +15,7 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -22,7 +23,7 @@ void test(S s, S str, S expected) { s += str; - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); } @@ -51,7 +52,7 @@ int main() test(S("12345678901234567890"), S("12345678901234567890"), S("1234567890123456789012345678901234567890")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(), S(), S()); diff --git a/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp index 057964112aa15..cc37e79c79326 100644 --- a/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp @@ -29,12 +29,13 @@ test(S s, typename S::size_type pos1, typename S::size_type n1, It f, It l, S ex typename S::const_iterator last = s.begin() + pos1 + n1; typename S::size_type xlen = last - first; s.replace(first, last, f, l); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); typename S::size_type rlen = std::distance(f, l); assert(s.size() == old_size - xlen + rlen); } +#ifndef TEST_HAS_NO_EXCEPTIONS template <class S, class It> void test_exceptions(S s, typename S::size_type pos1, typename S::size_type n1, It f, It l) @@ -47,9 +48,10 @@ test_exceptions(S s, typename S::size_type pos1, typename S::size_type n1, It f, assert(false); } catch (...) {} - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == aCopy); } +#endif const char* str = "12345678901234567890"; @@ -990,6 +992,7 @@ int main() test8<S>(); } #endif +#ifndef TEST_HAS_NO_EXCEPTIONS { // test iterator operations that throw typedef std::string S; typedef ThrowingIterator<char> TIter; @@ -1003,4 +1006,5 @@ int main() test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 5, TIter::TADereference), TIter()); test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 6, TIter::TAComparison), TIter()); } +#endif } diff --git a/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp index c7551b928ec1a..730fc1a501cfa 100644 --- a/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp @@ -29,7 +29,7 @@ test(S s, typename S::size_type pos1, typename S::size_type n1, const typename S typename S::const_iterator last = s.begin() + pos1 + n1; typename S::size_type xlen = last - first; s.replace(first, last, str); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); typename S::size_type rlen = S::traits_type::length(str); assert(s.size() == old_size - xlen + rlen); diff --git a/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp index 087df7824ac22..4a910e499819b 100644 --- a/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp @@ -12,12 +12,11 @@ // basic_string<charT,traits,Allocator>& // replace(const_iterator i1, const_iterator i2, const charT* s, size_type n); -#include <stdio.h> - #include <string> #include <algorithm> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -30,7 +29,7 @@ test(S s, typename S::size_type pos1, typename S::size_type n1, const typename S typename S::const_iterator last = s.begin() + pos1 + n1; typename S::size_type xlen = last - first; s.replace(first, last, str, n2); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); typename S::size_type rlen = n2; assert(s.size() == old_size - xlen + rlen); diff --git a/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp index 8be8b52982371..4dbc8ab1f22ce 100644 --- a/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp @@ -12,12 +12,11 @@ // basic_string<charT,traits,Allocator>& // replace(const_iterator i1, const_iterator i2, size_type n, charT c); -#include <stdio.h> - #include <string> #include <algorithm> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -30,7 +29,7 @@ test(S s, typename S::size_type pos1, typename S::size_type n1, typename S::size typename S::const_iterator last = s.begin() + pos1 + n1; typename S::size_type xlen = last - first; s.replace(first, last, n2, c); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); typename S::size_type rlen = n2; assert(s.size() == old_size - xlen + rlen); diff --git a/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp index b85a1063ebe1d..190e10d5c8303 100644 --- a/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp @@ -12,12 +12,11 @@ // basic_string<charT,traits,Allocator>& // replace(const_iterator i1, const_iterator i2, const basic_string& str); -#include <stdio.h> - #include <string> #include <algorithm> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -29,7 +28,7 @@ test(S s, typename S::size_type pos1, typename S::size_type n1, S str, S expecte typename S::const_iterator last = s.begin() + pos1 + n1; typename S::size_type xlen = last - first; s.replace(first, last, str); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(s == expected); typename S::size_type rlen = str.size(); assert(s.size() == old_size - xlen + rlen); diff --git a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp index eb0e982ef16e9..3beb074c0fd33 100644 --- a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp @@ -13,13 +13,12 @@ // basic_string<charT,traits,Allocator>& // replace(size_type pos, size_type n1, const charT* s); -#include <stdio.h> - #include <string> #include <stdexcept> #include <algorithm> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -32,7 +31,7 @@ test(S s, typename S::size_type pos, typename S::size_type n1, try { s.replace(pos, n1, str); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos <= old_size); assert(s == expected); typename S::size_type xlen = std::min(n1, old_size - pos); diff --git a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp index 898ab2a144c17..d961e9e8f76f7 100644 --- a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp @@ -13,13 +13,12 @@ // basic_string<charT,traits,Allocator>& // replace(size_type pos, size_type n1, const charT* s, size_type n2); -#include <stdio.h> - #include <string> #include <stdexcept> #include <algorithm> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -33,7 +32,7 @@ test(S s, typename S::size_type pos, typename S::size_type n1, try { s.replace(pos, n1, str, n2); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos <= old_size); assert(s == expected); typename S::size_type xlen = std::min(n1, old_size - pos); diff --git a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp index e616ecc04261d..d4696fba8a832 100644 --- a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp @@ -18,6 +18,7 @@ #include <algorithm> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -31,7 +32,7 @@ test(S s, typename S::size_type pos, typename S::size_type n1, try { s.replace(pos, n1, n2, c); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos <= old_size); assert(s == expected); typename S::size_type xlen = std::min(n1, old_size - pos); diff --git a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp index ea311dd1564fa..1be45d8a6624a 100644 --- a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp @@ -18,6 +18,7 @@ #include <algorithm> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -29,7 +30,7 @@ test(S s, typename S::size_type pos1, typename S::size_type n1, S str, S expecte try { s.replace(pos1, n1, str); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos1 <= old_size); assert(s == expected); typename S::size_type xlen = std::min(n1, old_size - pos1); diff --git a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp index 01f4a1f6ccef7..3f4bf450d8588 100644 --- a/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp @@ -20,6 +20,7 @@ #include <algorithm> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -33,7 +34,7 @@ test(S s, typename S::size_type pos1, typename S::size_type n1, try { s.replace(pos1, n1, str, pos2, n2); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos1 <= old_size && pos2 <= str.size()); assert(s == expected); typename S::size_type xlen = std::min(n1, old_size - pos1); @@ -58,7 +59,7 @@ test_npos(S s, typename S::size_type pos1, typename S::size_type n1, try { s.replace(pos1, n1, str, pos2); - assert(s.__invariants()); + LIBCPP_ASSERT(s.__invariants()); assert(pos1 <= old_size && pos2 <= str.size()); assert(s == expected); typename S::size_type xlen = std::min(n1, old_size - pos1); diff --git a/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp index 4973bda4ddf0d..fe2ee1fa6da96 100644 --- a/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp +++ b/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp @@ -16,6 +16,7 @@ #include <algorithm> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -25,8 +26,8 @@ test(S s1, S s2) S s1_ = s1; S s2_ = s2; s1.swap(s2); - assert(s1.__invariants()); - assert(s2.__invariants()); + LIBCPP_ASSERT(s1.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s1 == s2_); assert(s2 == s1_); } @@ -52,7 +53,7 @@ int main() test(S("abcdefghijklmnopqrst"), S("1234567890")); test(S("abcdefghijklmnopqrst"), S("12345678901234567890")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), S("")); diff --git a/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp index 4a912eaec6fab..6011ea1586fc1 100644 --- a/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp @@ -48,7 +48,7 @@ int main() assert(in.eof()); assert(s == L" ghij"); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; std::istringstream in(" abc\n def\n ghij"); diff --git a/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp index 6596f2fffa792..79852337a033b 100644 --- a/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp @@ -54,7 +54,7 @@ int main() assert(in.eof()); assert(s == L" ghij"); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; std::istringstream in(" abc* def** ghij"); diff --git a/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim_rv.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim_rv.pass.cpp index 84f52bb2e50f9..48d1854808c04 100644 --- a/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim_rv.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim_rv.pass.cpp @@ -33,7 +33,7 @@ int main() getline(std::wistringstream(L" abc* def* ghij"), s, L'*'); assert(s == L" abc"); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s("initial text"); diff --git a/test/std/strings/basic.string/string.nonmembers/string.io/get_line_rv.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string.io/get_line_rv.pass.cpp index a3c9911abe9b7..18c22f915ca09 100644 --- a/test/std/strings/basic.string/string.nonmembers/string.io/get_line_rv.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string.io/get_line_rv.pass.cpp @@ -33,7 +33,7 @@ int main() getline(std::wistringstream(L" abc\n def\n ghij"), s); assert(s == L" abc"); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; S s("initial text"); diff --git a/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp index af806bc045700..30e7dc6c12e07 100644 --- a/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp @@ -66,7 +66,7 @@ int main() in >> s; assert(in.fail()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; std::istringstream in("a bc defghij"); diff --git a/test/std/strings/basic.string/string.nonmembers/string.io/stream_insert.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string.io/stream_insert.pass.cpp index 102e8ea08159c..6489ddfca4665 100644 --- a/test/std/strings/basic.string/string.nonmembers/string.io/stream_insert.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string.io/stream_insert.pass.cpp @@ -52,7 +52,7 @@ int main() assert(out.good()); assert(L" " + s == out.str()); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; std::basic_ostringstream<S::value_type, S::traits_type, S::allocator_type> out; diff --git a/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp index cee538800dd0b..a2e25196d26f0 100644 --- a/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp @@ -18,6 +18,7 @@ #include <algorithm> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -27,8 +28,8 @@ test(S s1, S s2) S s1_ = s1; S s2_ = s2; swap(s1, s2); - assert(s1.__invariants()); - assert(s2.__invariants()); + LIBCPP_ASSERT(s1.__invariants()); + LIBCPP_ASSERT(s2.__invariants()); assert(s1 == s2_); assert(s2 == s1_); } @@ -54,7 +55,7 @@ int main() test(S("abcdefghijklmnopqrst"), S("1234567890")); test(S("abcdefghijklmnopqrst"), S("12345678901234567890")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), S("")); 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 cfe03655a8a16..4ac13d10e6700 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <string> // void swap(basic_string& c) @@ -22,13 +24,14 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" template <class T> struct some_alloc { typedef T value_type; - + some_alloc() {} some_alloc(const some_alloc&); void deallocate(void*, unsigned) {} @@ -40,7 +43,7 @@ template <class T> struct some_alloc2 { typedef T value_type; - + some_alloc2() {} some_alloc2(const some_alloc2&); void deallocate(void*, unsigned) {} @@ -51,7 +54,6 @@ struct some_alloc2 int main() { -#if __has_feature(cxx_noexcept) { typedef std::string C; C c1, c2; @@ -80,6 +82,4 @@ int main() static_assert( noexcept(swap(c1, c2)), ""); } #endif - -#endif } diff --git a/test/std/strings/basic.string/string.nonmembers/string_op!=/pointer_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_op!=/pointer_string.pass.cpp index cc08982a5ca36..6d39d025c5851 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_op!=/pointer_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_op!=/pointer_string.pass.cpp @@ -45,7 +45,7 @@ int main() test("abcdefghijklmnopqrst", S("abcdefghij"), true); test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test("", S(""), false); diff --git a/test/std/strings/basic.string/string.nonmembers/string_op!=/string_pointer.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_op!=/string_pointer.pass.cpp index b496d70dc2f0b..67d18b7a9ca7e 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_op!=/string_pointer.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_op!=/string_pointer.pass.cpp @@ -45,7 +45,7 @@ int main() test(S("abcdefghijklmnopqrst"), "abcdefghij", true); test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), "", false); diff --git a/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string.pass.cpp index 069b305111d44..27e97788c6372 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string.pass.cpp @@ -46,7 +46,7 @@ int main() test(S("abcdefghijklmnopqrst"), S("abcdefghij"), true); test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), S(""), false); diff --git a/test/std/strings/basic.string/string.nonmembers/string_op+/char_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_op+/char_string.pass.cpp index 23a89c6fc8fb3..9a8213e230fbd 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_op+/char_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_op+/char_string.pass.cpp @@ -49,7 +49,7 @@ int main() test0('a', S("12345"), S("a12345")); test0('a', S("1234567890"), S("a1234567890")); test0('a', S("12345678901234567890"), S("a12345678901234567890")); - + #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES test1('a', S(""), S("a")); @@ -59,14 +59,14 @@ int main() #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0('a', S(""), S("a")); test0('a', S("12345"), S("a12345")); test0('a', S("1234567890"), S("a1234567890")); test0('a', S("12345678901234567890"), S("a12345678901234567890")); - + #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES test1('a', S(""), S("a")); diff --git a/test/std/strings/basic.string/string.nonmembers/string_op+/pointer_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_op+/pointer_string.pass.cpp index 665e86f2c2398..88fa678ec44f9 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_op+/pointer_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_op+/pointer_string.pass.cpp @@ -83,7 +83,7 @@ int main() #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0("", S(""), S("")); diff --git a/test/std/strings/basic.string/string.nonmembers/string_op+/string_char.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_op+/string_char.pass.cpp index 12903fe8118e4..b4c2c97043cce 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_op+/string_char.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_op+/string_char.pass.cpp @@ -59,7 +59,7 @@ int main() #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0(S(""), '1', S("1")); diff --git a/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp index 63a7b769b787e..3b669e7d98697 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp @@ -83,7 +83,7 @@ int main() #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0(S(""), "", S("")); diff --git a/test/std/strings/basic.string/string.nonmembers/string_op+/string_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_op+/string_string.pass.cpp index 318b648d6eb02..1977b6f517ba0 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_op+/string_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_op+/string_string.pass.cpp @@ -143,7 +143,7 @@ int main() #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0(S(""), S(""), S("")); diff --git a/test/std/strings/basic.string/string.nonmembers/string_operator==/pointer_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_operator==/pointer_string.pass.cpp index 19a5bdd977e4d..19dd8bfbd92e5 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_operator==/pointer_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_operator==/pointer_string.pass.cpp @@ -45,7 +45,7 @@ int main() test("abcdefghijklmnopqrst", S("abcdefghij"), false); test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test("", S(""), true); diff --git a/test/std/strings/basic.string/string.nonmembers/string_operator==/string_pointer.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_operator==/string_pointer.pass.cpp index 22006bb1be68d..f6e3ddec46e27 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_operator==/string_pointer.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_operator==/string_pointer.pass.cpp @@ -45,7 +45,7 @@ int main() test(S("abcdefghijklmnopqrst"), "abcdefghij", false); test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), "", true); diff --git a/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string.pass.cpp index 0bff70a977a6c..c1d57b0bcc8b7 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string.pass.cpp @@ -46,7 +46,7 @@ int main() test(S("abcdefghijklmnopqrst"), S("abcdefghij"), false); test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), S(""), true); diff --git a/test/std/strings/basic.string/string.nonmembers/string_opgt/pointer_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_opgt/pointer_string.pass.cpp index f9fa204b9eeac..363e6d36100b1 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_opgt/pointer_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_opgt/pointer_string.pass.cpp @@ -45,7 +45,7 @@ int main() test("abcdefghijklmnopqrst", S("abcdefghij"), true); test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test("", S(""), false); diff --git a/test/std/strings/basic.string/string.nonmembers/string_opgt/string_pointer.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_opgt/string_pointer.pass.cpp index daa6f40ae3c02..4b5f7c3689a2e 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_opgt/string_pointer.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_opgt/string_pointer.pass.cpp @@ -45,7 +45,7 @@ int main() test(S("abcdefghijklmnopqrst"), "abcdefghij", true); test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), "", false); diff --git a/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string.pass.cpp index 95073bf7644c3..01c7c5311b953 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string.pass.cpp @@ -46,7 +46,7 @@ int main() test(S("abcdefghijklmnopqrst"), S("abcdefghij"), true); test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), S(""), false); diff --git a/test/std/strings/basic.string/string.nonmembers/string_opgt=/pointer_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_opgt=/pointer_string.pass.cpp index eab117a843faf..f4ab04d60d8ae 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_opgt=/pointer_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_opgt=/pointer_string.pass.cpp @@ -45,7 +45,7 @@ int main() test("abcdefghijklmnopqrst", S("abcdefghij"), true); test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test("", S(""), true); diff --git a/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_pointer.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_pointer.pass.cpp index 56b3b35b3d946..4042997f462ff 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_pointer.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_pointer.pass.cpp @@ -45,7 +45,7 @@ int main() test(S("abcdefghijklmnopqrst"), "abcdefghij", true); test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), "", true); diff --git a/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string.pass.cpp index c02b202c49e6f..cdcfc9d8d14a0 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string.pass.cpp @@ -46,7 +46,7 @@ int main() test(S("abcdefghijklmnopqrst"), S("abcdefghij"), true); test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), S(""), true); diff --git a/test/std/strings/basic.string/string.nonmembers/string_oplt/pointer_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_oplt/pointer_string.pass.cpp index 86f6a2db119a5..e709aa4fbc42a 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_oplt/pointer_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_oplt/pointer_string.pass.cpp @@ -45,7 +45,7 @@ int main() test("abcdefghijklmnopqrst", S("abcdefghij"), false); test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test("", S(""), false); diff --git a/test/std/strings/basic.string/string.nonmembers/string_oplt/string_pointer.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_oplt/string_pointer.pass.cpp index b935da5426fdc..8e4f2fab13a42 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_oplt/string_pointer.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_oplt/string_pointer.pass.cpp @@ -45,7 +45,7 @@ int main() test(S("abcdefghijklmnopqrst"), "abcdefghij", false); test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), "", false); diff --git a/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string.pass.cpp index 487e2056f2cae..c14e92a0003cd 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string.pass.cpp @@ -46,7 +46,7 @@ int main() test(S("abcdefghijklmnopqrst"), S("abcdefghij"), false); test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), S(""), false); diff --git a/test/std/strings/basic.string/string.nonmembers/string_oplt=/pointer_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_oplt=/pointer_string.pass.cpp index 21959405194d4..acab3592ec17b 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_oplt=/pointer_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_oplt=/pointer_string.pass.cpp @@ -45,7 +45,7 @@ int main() test("abcdefghijklmnopqrst", S("abcdefghij"), false); test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test("", S(""), true); diff --git a/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_pointer.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_pointer.pass.cpp index bb1bce8d40434..f0f540a499c70 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_pointer.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_pointer.pass.cpp @@ -45,7 +45,7 @@ int main() test(S("abcdefghijklmnopqrst"), "abcdefghij", false); test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), "", true); diff --git a/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string.pass.cpp index 2b975f160d5de..208f9623929da 100644 --- a/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string.pass.cpp +++ b/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string.pass.cpp @@ -46,7 +46,7 @@ int main() test(S("abcdefghijklmnopqrst"), S("abcdefghij"), false); test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), S(""), true); diff --git a/test/std/strings/basic.string/string.ops/string.accessors/c_str.pass.cpp b/test/std/strings/basic.string/string.ops/string.accessors/c_str.pass.cpp index 3bdb800bf7361..d6695b0b34bc2 100644 --- a/test/std/strings/basic.string/string.ops/string.accessors/c_str.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string.accessors/c_str.pass.cpp @@ -40,7 +40,7 @@ int main() test(S("abcdefghij")); test(S("abcdefghijklmnopqrst")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S("")); diff --git a/test/std/strings/basic.string/string.ops/string.accessors/data.pass.cpp b/test/std/strings/basic.string/string.ops/string.accessors/data.pass.cpp index 917248fa69163..9b66cb0049902 100644 --- a/test/std/strings/basic.string/string.ops/string.accessors/data.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string.accessors/data.pass.cpp @@ -10,15 +10,17 @@ // <string> // const charT* data() const; +// charT* data(); // C++17 #include <string> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> void -test(const S& s) +test_const(const S& s) { typedef typename S::traits_type T; const typename S::value_type* str = s.data(); @@ -31,22 +33,46 @@ test(const S& s) assert(T::eq(str[0], typename S::value_type())); } +template <class S> +void +test_nonconst(S& s) +{ + typedef typename S::traits_type T; + typename S::value_type* str = s.data(); + if (s.size() > 0) + { + assert(T::compare(str, &s[0], s.size()) == 0); + assert(T::eq(str[s.size()], typename S::value_type())); + } + else + assert(T::eq(str[0], typename S::value_type())); +} + int main() { { typedef std::string S; - test(S("")); - test(S("abcde")); - test(S("abcdefghij")); - test(S("abcdefghijklmnopqrst")); + test_const(S("")); + test_const(S("abcde")); + test_const(S("abcdefghij")); + test_const(S("abcdefghijklmnopqrst")); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; - test(S("")); - test(S("abcde")); - test(S("abcdefghij")); - test(S("abcdefghijklmnopqrst")); + test_const(S("")); + test_const(S("abcde")); + test_const(S("abcdefghij")); + test_const(S("abcdefghijklmnopqrst")); + } +#endif +#if TEST_STD_VER > 14 + { + typedef std::string S; + S s1(""); test_nonconst(s1); + S s2("abcde"); test_nonconst(s2); + S s3("abcdefghij"); test_nonconst(s3); + S s4("abcdefghijklmnopqrst"); test_nonconst(s4); } #endif } diff --git a/test/std/strings/basic.string/string.ops/string.accessors/get_allocator.pass.cpp b/test/std/strings/basic.string/string.ops/string.accessors/get_allocator.pass.cpp index 6ba040d2635d2..e50c61fb162af 100644 --- a/test/std/strings/basic.string/string.ops/string.accessors/get_allocator.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string.accessors/get_allocator.pass.cpp @@ -34,7 +34,7 @@ int main() test(S("abcdefghij", A(2)), A(2)); test(S("abcdefghijklmnopqrst", A(3)), A(3)); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<char> A; typedef std::basic_string<char, std::char_traits<char>, A> S; diff --git a/test/std/strings/basic.string/string.ops/string_compare/pointer.pass.cpp b/test/std/strings/basic.string/string.ops/string_compare/pointer.pass.cpp index dda7428992a19..150973a7f4e4c 100644 --- a/test/std/strings/basic.string/string.ops/string_compare/pointer.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_compare/pointer.pass.cpp @@ -53,7 +53,7 @@ int main() test(S("abcdefghijklmnopqrst"), "abcdefghij", 10); test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), "", 0); diff --git a/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp b/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp index 2fef19a24df93..094c227030b84 100644 --- a/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp @@ -362,7 +362,7 @@ int main() test1<S>(); test2<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer_size.pass.cpp index cc61a2e453c44..22aae785c19a0 100644 --- a/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer_size.pass.cpp @@ -1304,7 +1304,7 @@ int main() test10<S>(); test11<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp b/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp index 66417482fb581..90b4230f64daf 100644 --- a/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp @@ -362,7 +362,7 @@ int main() test1<S>(); test2<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_compare/size_size_string_size_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_compare/size_size_string_size_size.pass.cpp index f5c0676992339..3cbbea7b490b7 100644 --- a/test/std/strings/basic.string/string.ops/string_compare/size_size_string_size_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_compare/size_size_string_size_size.pass.cpp @@ -5885,7 +5885,7 @@ int main() test54<S>(); test55<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp b/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp index 7de95a8cda564..3f6c169d223ae 100644 --- a/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp @@ -53,7 +53,7 @@ int main() test(S("abcdefghijklmnopqrst"), S("abcdefghij"), 10); test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), S(""), 0); diff --git a/test/std/strings/basic.string/string.ops/string_find.first.not.of/char_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.first.not.of/char_size.pass.cpp index 590173eddf41f..945f8805487dd 100644 --- a/test/std/strings/basic.string/string.ops/string_find.first.not.of/char_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.first.not.of/char_size.pass.cpp @@ -67,7 +67,7 @@ int main() test(S("gfsmthlkon"), 'q', 0); test(S("laenfsbridchgotmkqpj"), 'q', 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), 'q', 0, S::npos); diff --git a/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size.pass.cpp index 53d3a95292c2f..0c239b3235084 100644 --- a/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size.pass.cpp @@ -148,7 +148,7 @@ int main() test0<S>(); test1<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp index 14ac4b2a153b1..0296e2cbee380 100644 --- a/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp @@ -375,7 +375,7 @@ int main() test2<S>(); test3<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp index 4fb072fa47443..b7df3461792be 100644 --- a/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp @@ -147,7 +147,7 @@ int main() test0<S>(); test1<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find.first.of/char_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.first.of/char_size.pass.cpp index 32d0e86f3d843..494a1181f2ae0 100644 --- a/test/std/strings/basic.string/string.ops/string_find.first.of/char_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.first.of/char_size.pass.cpp @@ -65,7 +65,7 @@ int main() test(S("gfsmthlkon"), 'e', S::npos); test(S("laenfsbridchgotmkqpj"), 'e', 2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), 'e', 0, S::npos); diff --git a/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size.pass.cpp index 6dd176df01656..b2a05b29f1342 100644 --- a/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size.pass.cpp @@ -148,7 +148,7 @@ int main() test0<S>(); test1<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size_size.pass.cpp index 9e98a6ad20f7a..8b7f7b4a58846 100644 --- a/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size_size.pass.cpp @@ -375,7 +375,7 @@ int main() test2<S>(); test3<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp index e409edc25f488..765d1603af8c4 100644 --- a/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp @@ -147,7 +147,7 @@ int main() test0<S>(); test1<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find.last.not.of/char_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.last.not.of/char_size.pass.cpp index b130f9287ba3a..3212389bb3a8a 100644 --- a/test/std/strings/basic.string/string.ops/string_find.last.not.of/char_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.last.not.of/char_size.pass.cpp @@ -65,7 +65,7 @@ int main() test(S("gfsmthlkon"), 'i', 9); test(S("laenfsbridchgotmkqpj"), 'i', 19); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), 'i', 0, S::npos); diff --git a/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size.pass.cpp index 3e6bd9d093ea4..7dc75184ff99c 100644 --- a/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size.pass.cpp @@ -148,7 +148,7 @@ int main() test0<S>(); test1<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp index 4db7762b2755f..2024266df4a63 100644 --- a/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp @@ -375,7 +375,7 @@ int main() test2<S>(); test3<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp index ba93adbe445e7..f3377596ab3de 100644 --- a/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp @@ -147,7 +147,7 @@ int main() test0<S>(); test1<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find.last.of/char_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.last.of/char_size.pass.cpp index 12765b71f28f4..e0bbd82f6679e 100644 --- a/test/std/strings/basic.string/string.ops/string_find.last.of/char_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.last.of/char_size.pass.cpp @@ -65,7 +65,7 @@ int main() test(S("gfsmthlkon"), 'm', 3); test(S("laenfsbridchgotmkqpj"), 'm', 15); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), 'm', 0, S::npos); diff --git a/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size.pass.cpp index f1b447c43f4b2..c3d6044c4201e 100644 --- a/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size.pass.cpp @@ -148,7 +148,7 @@ int main() test0<S>(); test1<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size_size.pass.cpp index 7f96e6351aa6a..42a076aa4c569 100644 --- a/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size_size.pass.cpp @@ -375,7 +375,7 @@ int main() test2<S>(); test3<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp index 351c6727de2db..5cb2df7c6c7fd 100644 --- a/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp @@ -147,7 +147,7 @@ int main() test0<S>(); test1<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find/char_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find/char_size.pass.cpp index 24e58fc5f1ad8..a084348b3e635 100644 --- a/test/std/strings/basic.string/string.ops/string_find/char_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find/char_size.pass.cpp @@ -65,7 +65,7 @@ int main() test(S("abcdeabcde"), 'c', 2); test(S("abcdeabcdeabcdeabcde"), 'c', 2); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), 'c', 0, S::npos); diff --git a/test/std/strings/basic.string/string.ops/string_find/pointer_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find/pointer_size.pass.cpp index e00d7fd8a3dc6..0257e125953ff 100644 --- a/test/std/strings/basic.string/string.ops/string_find/pointer_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find/pointer_size.pass.cpp @@ -154,7 +154,7 @@ int main() test0<S>(); test1<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find/pointer_size_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find/pointer_size_size.pass.cpp index 3006c466eed30..9a380f72982dc 100644 --- a/test/std/strings/basic.string/string.ops/string_find/pointer_size_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find/pointer_size_size.pass.cpp @@ -375,7 +375,7 @@ int main() test2<S>(); test3<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp index a89df4e3ffa1d..e519a7943ba9d 100644 --- a/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp @@ -147,7 +147,7 @@ int main() test0<S>(); test1<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_rfind/char_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_rfind/char_size.pass.cpp index cbc0c9b353673..c53d77f348b89 100644 --- a/test/std/strings/basic.string/string.ops/string_rfind/char_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_rfind/char_size.pass.cpp @@ -65,7 +65,7 @@ int main() test(S("abcdeabcde"), 'b', 6); test(S("abcdeabcdeabcdeabcde"), 'b', 16); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), 'b', 0, S::npos); diff --git a/test/std/strings/basic.string/string.ops/string_rfind/pointer_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_rfind/pointer_size.pass.cpp index 450aebedd59c2..ebcb0ea3859a8 100644 --- a/test/std/strings/basic.string/string.ops/string_rfind/pointer_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_rfind/pointer_size.pass.cpp @@ -155,7 +155,7 @@ int main() test0<S>(); test1<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_rfind/pointer_size_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_rfind/pointer_size_size.pass.cpp index 47baf40b265bb..e8d0c6b738715 100644 --- a/test/std/strings/basic.string/string.ops/string_rfind/pointer_size_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_rfind/pointer_size_size.pass.cpp @@ -375,7 +375,7 @@ int main() test2<S>(); test3<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp b/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp index 05e6e51742327..ef571c284b812 100644 --- a/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp @@ -147,7 +147,7 @@ int main() test0<S>(); test1<S>(); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test0<S>(); diff --git a/test/std/strings/basic.string/string.ops/string_substr/substr.pass.cpp b/test/std/strings/basic.string/string.ops/string_substr/substr.pass.cpp index dc01f4f477475..145e8dde58bf5 100644 --- a/test/std/strings/basic.string/string.ops/string_substr/substr.pass.cpp +++ b/test/std/strings/basic.string/string.ops/string_substr/substr.pass.cpp @@ -17,6 +17,7 @@ #include <algorithm> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" template <class S> @@ -26,7 +27,7 @@ test(const S& s, typename S::size_type pos, typename S::size_type n) try { S str = s.substr(pos, n); - assert(str.__invariants()); + LIBCPP_ASSERT(str.__invariants()); assert(pos <= s.size()); typename S::size_type rlen = std::min(n, s.size() - pos); assert(str.size() == rlen); @@ -101,7 +102,7 @@ int main() test(S("lsaijeqhtrbgcdmpfkno"), 20, 0); test(S("dplqartnfgejichmoskb"), 21, 0); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; test(S(""), 0, 0); diff --git a/test/std/strings/basic.string/string.require/contiguous.pass.cpp b/test/std/strings/basic.string/string.require/contiguous.pass.cpp index ca31ace0ef0b3..49773fe491a22 100644 --- a/test/std/strings/basic.string/string.require/contiguous.pass.cpp +++ b/test/std/strings/basic.string/string.require/contiguous.pass.cpp @@ -41,7 +41,7 @@ int main() test_contiguous(S("1", A(5))); test_contiguous(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7))); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 { typedef min_allocator<char> A; typedef std::basic_string<char, std::char_traits<char>, A> S; diff --git a/test/std/strings/basic.string/types.pass.cpp b/test/std/strings/basic.string/types.pass.cpp index dcb3bbc35ebff..a6832a158ecaf 100644 --- a/test/std/strings/basic.string/types.pass.cpp +++ b/test/std/strings/basic.string/types.pass.cpp @@ -79,7 +79,7 @@ int main() std::char_traits<char> >::value), ""); static_assert((std::is_same<std::basic_string<char>::allocator_type, std::allocator<char> >::value), ""); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<std::char_traits<char>, min_allocator<char> >(); #endif } diff --git a/test/std/strings/c.strings/cstring.pass.cpp b/test/std/strings/c.strings/cstring.pass.cpp index 20f4050cfbdb1..63f86d350610f 100644 --- a/test/std/strings/c.strings/cstring.pass.cpp +++ b/test/std/strings/c.strings/cstring.pass.cpp @@ -34,17 +34,12 @@ int main() static_assert((std::is_same<decltype(std::strncmp(cpc, cpc, s)), int>::value), ""); static_assert((std::is_same<decltype(std::strcoll(cpc, cpc)), int>::value), ""); static_assert((std::is_same<decltype(std::strxfrm(cp, cpc, s)), std::size_t>::value), ""); -// static_assert((std::is_same<decltype(std::memchr(vpc, 0, s)), const void*>::value), ""); static_assert((std::is_same<decltype(std::memchr(vp, 0, s)), void*>::value), ""); -// static_assert((std::is_same<decltype(std::strchr(cpc, 0)), const char*>::value), ""); static_assert((std::is_same<decltype(std::strchr(cp, 0)), char*>::value), ""); static_assert((std::is_same<decltype(std::strcspn(cpc, cpc)), std::size_t>::value), ""); -// static_assert((std::is_same<decltype(std::strpbrk(cpc, cpc)), const char*>::value), ""); static_assert((std::is_same<decltype(std::strpbrk(cp, cpc)), char*>::value), ""); -// static_assert((std::is_same<decltype(std::strrchr(cpc, 0)), const char*>::value), ""); static_assert((std::is_same<decltype(std::strrchr(cp, 0)), char*>::value), ""); 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), ""); @@ -52,4 +47,15 @@ int main() 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), ""); + + // These tests fail on systems whose C library doesn't provide a correct overload + // set for strchr, strpbrk, strrchr, strstr, and memchr, unless the compiler is + // a suitably recent version of Clang. +#if !defined(__APPLE__) || defined(_LIBCPP_PREFERRED_OVERLOAD) + static_assert((std::is_same<decltype(std::memchr(vpc, 0, s)), const void*>::value), ""); + static_assert((std::is_same<decltype(std::strchr(cpc, 0)), const char*>::value), ""); + static_assert((std::is_same<decltype(std::strpbrk(cpc, cpc)), const char*>::value), ""); + static_assert((std::is_same<decltype(std::strrchr(cpc, 0)), const char*>::value), ""); + static_assert((std::is_same<decltype(std::strstr(cpc, cpc)), const char*>::value), ""); +#endif } diff --git a/test/std/strings/c.strings/cwchar.pass.cpp b/test/std/strings/c.strings/cwchar.pass.cpp index 93d2bb1efa505..2b7c3c465f6db 100644 --- a/test/std/strings/c.strings/cwchar.pass.cpp +++ b/test/std/strings/c.strings/cwchar.pass.cpp @@ -10,6 +10,7 @@ // <cwchar> #include <cwchar> +#include <cstdarg> #include <type_traits> #ifndef NULL @@ -35,13 +36,20 @@ int main() std::tm *tm = 0; std::wint_t w = 0; ::FILE* fp = 0; -#ifdef __APPLE__ - __darwin_va_list va; -#else - __builtin_va_list va; -#endif + std::va_list va; + char* ns = 0; wchar_t* ws = 0; + + ((void)mb); // Prevent unused warning + ((void)s); // Prevent unused warning + ((void)tm); // Prevent unused warning + ((void)w); // Prevent unused warning + ((void)fp); // Prevent unused warning + ((void)va); // Prevent unused warning + ((void)ns); // Prevent unused warning + ((void)ws); // Prevent unused warning + static_assert((std::is_same<decltype(std::fwprintf(fp, L"")), int>::value), ""); static_assert((std::is_same<decltype(std::fwscanf(fp, L"")), int>::value), ""); static_assert((std::is_same<decltype(std::swprintf(ws, s, L"")), int>::value), ""); @@ -73,19 +81,14 @@ int main() static_assert((std::is_same<decltype(std::wcscoll(L"", L"")), int>::value), ""); static_assert((std::is_same<decltype(std::wcsncmp(L"", L"", s)), int>::value), ""); static_assert((std::is_same<decltype(std::wcsxfrm(ws, L"", s)), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::wcschr((const wchar_t*)0, L' ')), const wchar_t*>::value), ""); static_assert((std::is_same<decltype(std::wcschr((wchar_t*)0, L' ')), wchar_t*>::value), ""); static_assert((std::is_same<decltype(std::wcscspn(L"", L"")), std::size_t>::value), ""); static_assert((std::is_same<decltype(std::wcslen(L"")), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::wcspbrk((const wchar_t*)0, L"")), const wchar_t*>::value), ""); static_assert((std::is_same<decltype(std::wcspbrk((wchar_t*)0, L"")), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wcsrchr((const wchar_t*)0, L' ')), const wchar_t*>::value), ""); static_assert((std::is_same<decltype(std::wcsrchr((wchar_t*)0, L' ')), wchar_t*>::value), ""); static_assert((std::is_same<decltype(std::wcsspn(L"", L"")), std::size_t>::value), ""); - static_assert((std::is_same<decltype(std::wcsstr((const wchar_t*)0, L"")), const wchar_t*>::value), ""); static_assert((std::is_same<decltype(std::wcsstr((wchar_t*)0, L"")), wchar_t*>::value), ""); static_assert((std::is_same<decltype(std::wcstok(ws, L"", (wchar_t**)0)), wchar_t*>::value), ""); - static_assert((std::is_same<decltype(std::wmemchr((const wchar_t*)0, L' ', s)), const wchar_t*>::value), ""); static_assert((std::is_same<decltype(std::wmemchr((wchar_t*)0, L' ', s)), wchar_t*>::value), ""); static_assert((std::is_same<decltype(std::wmemcmp(L"", L"", s)), int>::value), ""); static_assert((std::is_same<decltype(std::wmemcpy(ws, L"", s)), wchar_t*>::value), ""); @@ -101,6 +104,17 @@ int main() 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), ""); + // These tests fail on systems whose C library doesn't provide a correct overload + // set for wcschr, wcspbrk, wcsrchr, wcsstr, and wmemchr, unless the compiler is + // a suitably recent version of Clang. +#if !defined(__APPLE__) || defined(_LIBCPP_PREFERRED_OVERLOAD) + static_assert((std::is_same<decltype(std::wcschr((const wchar_t*)0, L' ')), const wchar_t*>::value), ""); + static_assert((std::is_same<decltype(std::wcspbrk((const wchar_t*)0, L"")), const wchar_t*>::value), ""); + static_assert((std::is_same<decltype(std::wcsrchr((const wchar_t*)0, L' ')), const wchar_t*>::value), ""); + static_assert((std::is_same<decltype(std::wcsstr((const wchar_t*)0, L"")), const wchar_t*>::value), ""); + static_assert((std::is_same<decltype(std::wmemchr((const wchar_t*)0, L' ', s)), const wchar_t*>::value), ""); +#endif + #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), ""); diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/lt.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/lt.pass.cpp index 3ff9c0f1ff92b..9b552347fe9eb 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/lt.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char/lt.pass.cpp @@ -1,6 +1,6 @@ //===----------------------------------------------------------------------===// // -// The LLVM Compiler Infrastructure +// 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. @@ -18,11 +18,16 @@ int main() { - char c = '\0'; - assert(!std::char_traits<char>::lt('a', 'a')); - assert( std::char_traits<char>::lt('A', 'a')); - assert(!std::char_traits<char>::lt('A' + 127, 'a')); - assert(!std::char_traits<char>::lt('A' - 127, 'a')); - assert( std::char_traits<char>::lt('A', 'a' + 127)); - assert( std::char_traits<char>::lt('A', 'a' - 127)); + assert( std::char_traits<char>::lt('\0', 'A')); + assert(!std::char_traits<char>::lt('A', '\0')); + + assert(!std::char_traits<char>::lt('a', 'a')); + assert( std::char_traits<char>::lt('A', 'a')); + assert(!std::char_traits<char>::lt('a', 'A')); + + assert( std::char_traits<char>::lt('a', 'z')); + assert( std::char_traits<char>::lt('A', 'Z')); + + assert( std::char_traits<char>::lt(' ', 'A')); + assert( std::char_traits<char>::lt('A', '~')); } diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/assign2.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/assign2.pass.cpp index af87052ff2194..7f223af57414c 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/assign2.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/assign2.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 char16_t c = u'\0'; std::char_traits<char16_t>::assign(c, u'a'); assert(c == u'a'); diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/compare.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/compare.pass.cpp index b5039072dbfda..7356097a66771 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/compare.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/compare.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert(std::char_traits<char16_t>::compare(u"", u"", 0) == 0); assert(std::char_traits<char16_t>::compare(NULL, NULL, 0) == 0); diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/eq.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/eq.pass.cpp index 8216934658ce9..1ae4cb8fe8d92 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/eq.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/eq.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 char16_t c = u'\0'; assert(std::char_traits<char16_t>::eq(u'a', u'a')); assert(!std::char_traits<char16_t>::eq(u'a', u'A')); diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/eq_int_type.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/eq_int_type.pass.cpp index a20aa7d471895..42546f450fc7f 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/eq_int_type.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/eq_int_type.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert( std::char_traits<char16_t>::eq_int_type(u'a', u'a')); assert(!std::char_traits<char16_t>::eq_int_type(u'a', u'A')); assert(!std::char_traits<char16_t>::eq_int_type(std::char_traits<char16_t>::eof(), u'A')); diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/length.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/length.pass.cpp index 9f6acca83e368..ff5a2a934a9fc 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/length.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/length.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert(std::char_traits<char16_t>::length(u"") == 0); assert(std::char_traits<char16_t>::length(u"a") == 1); assert(std::char_traits<char16_t>::length(u"aa") == 2); diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/lt.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/lt.pass.cpp index 135ecc05e1996..b27ee06f4a594 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/lt.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/lt.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 char16_t c = u'\0'; assert(!std::char_traits<char16_t>::lt(u'a', u'a')); assert( std::char_traits<char16_t>::lt(u'A', u'a')); diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/not_eof.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/not_eof.pass.cpp index 3c213e6e0a37c..af9378073bec1 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/not_eof.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/not_eof.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert(std::char_traits<char16_t>::not_eof(u'a') == u'a'); assert(std::char_traits<char16_t>::not_eof(u'A') == u'A'); #endif diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/to_char_type.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/to_char_type.pass.cpp index ab47403dbe01b..2a679d0cf4208 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/to_char_type.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/to_char_type.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert(std::char_traits<char16_t>::to_char_type(u'a') == u'a'); assert(std::char_traits<char16_t>::to_char_type(u'A') == u'A'); #endif diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/to_int_type.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/to_int_type.pass.cpp index 11eb8f5254664..93861461baaf1 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/to_int_type.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char16_t/to_int_type.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert(std::char_traits<char16_t>::to_int_type(u'a') == u'a'); assert(std::char_traits<char16_t>::to_int_type(u'A') == u'A'); #endif diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/assign2.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/assign2.pass.cpp index 35dcd9602d3cf..6cd55ea58bff2 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/assign2.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/assign2.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 char32_t c = U'\0'; std::char_traits<char32_t>::assign(c, U'a'); assert(c == U'a'); diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/compare.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/compare.pass.cpp index 25f2099896a64..2671b5624100f 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/compare.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/compare.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert(std::char_traits<char32_t>::compare(U"", U"", 0) == 0); assert(std::char_traits<char32_t>::compare(NULL, NULL, 0) == 0); diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/eq.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/eq.pass.cpp index ffeff0cf45a40..0284d9f7933b9 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/eq.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/eq.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 char32_t c = U'\0'; assert(std::char_traits<char32_t>::eq(U'a', U'a')); assert(!std::char_traits<char32_t>::eq(U'a', U'A')); diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/eq_int_type.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/eq_int_type.pass.cpp index eb5c696610146..d39798c74bb62 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/eq_int_type.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/eq_int_type.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert( std::char_traits<char32_t>::eq_int_type(U'a', U'a')); assert(!std::char_traits<char32_t>::eq_int_type(U'a', U'A')); assert(!std::char_traits<char32_t>::eq_int_type(std::char_traits<char32_t>::eof(), U'A')); diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/length.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/length.pass.cpp index d80ce051d1fa7..e0bee5dc50800 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/length.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/length.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert(std::char_traits<char32_t>::length(U"") == 0); assert(std::char_traits<char32_t>::length(U"a") == 1); assert(std::char_traits<char32_t>::length(U"aa") == 2); diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/lt.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/lt.pass.cpp index f667507f04571..9816df7387097 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/lt.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/lt.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 char32_t c = U'\0'; assert(!std::char_traits<char32_t>::lt(U'a', U'a')); assert( std::char_traits<char32_t>::lt(U'A', U'a')); diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/not_eof.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/not_eof.pass.cpp index d794417bfd7aa..b83fd0fe07fff 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/not_eof.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/not_eof.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert(std::char_traits<char32_t>::not_eof(U'a') == U'a'); assert(std::char_traits<char32_t>::not_eof(U'A') == U'A'); #endif diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/to_char_type.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/to_char_type.pass.cpp index 1f67242b2aec5..c9820424fb667 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/to_char_type.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/to_char_type.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert(std::char_traits<char32_t>::to_char_type(U'a') == U'a'); assert(std::char_traits<char32_t>::to_char_type(U'A') == U'A'); #endif diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/to_int_type.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/to_int_type.pass.cpp index a378186bdd6fb..801c4cf7cddf5 100644 --- a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/to_int_type.pass.cpp +++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char32_t/to_int_type.pass.cpp @@ -16,10 +16,12 @@ #include <string> #include <cassert> +#include "test_macros.h" + int main() { #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 assert(std::char_traits<char32_t>::to_int_type(U'a') == U'a'); assert(std::char_traits<char32_t>::to_int_type(U'A') == U'A'); #endif diff --git a/test/std/thread/futures/futures.async/async.pass.cpp b/test/std/thread/futures/futures.async/async.pass.cpp index 2c1313b7a2f0f..5cb824d482240 100644 --- a/test/std/thread/futures/futures.async/async.pass.cpp +++ b/test/std/thread/futures/futures.async/async.pass.cpp @@ -21,15 +21,22 @@ // future<typename result_of<F(Args...)>::type> // async(launch policy, F&& f, Args&&... args); + #include <future> +#include <atomic> #include <memory> #include <cassert> +#include "test_macros.h" + typedef std::chrono::high_resolution_clock Clock; typedef std::chrono::milliseconds ms; +std::atomic_bool invoked = ATOMIC_VAR_INIT(false); + int f0() { + invoked = true; std::this_thread::sleep_for(ms(200)); return 3; } @@ -38,163 +45,109 @@ int i = 0; int& f1() { + invoked = true; std::this_thread::sleep_for(ms(200)); return i; } void f2() { + invoked = true; std::this_thread::sleep_for(ms(200)); } -std::unique_ptr<int> f3(int i) +std::unique_ptr<int> f3(int j) { + invoked = true; std::this_thread::sleep_for(ms(200)); - return std::unique_ptr<int>(new int(i)); + return std::unique_ptr<int>(new int(j)); } std::unique_ptr<int> f4(std::unique_ptr<int>&& p) { + invoked = true; std::this_thread::sleep_for(ms(200)); return std::move(p); } -void f5(int i) +void f5(int j) { std::this_thread::sleep_for(ms(200)); - throw i; + throw j; } -int main() -{ - { - std::future<int> f = std::async(f0); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int> f = std::async(std::launch::async, f0); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int> f = std::async(std::launch::any, f0); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int> f = std::async(std::launch::deferred, f0); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 > ms(100)); - } +template <class Ret, class CheckLamdba, class ...Args> +void test(CheckLamdba&& getAndCheckFn, bool IsDeferred, Args&&... args) { + // Reset global state. + invoked = false; - { - std::future<int&> f = std::async(f1); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(&f.get() == &i); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int&> f = std::async(std::launch::async, f1); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(&f.get() == &i); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int&> f = std::async(std::launch::any, f1); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(&f.get() == &i); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int&> f = std::async(std::launch::deferred, f1); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(&f.get() == &i); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 > ms(100)); - } + // Create the future and wait + std::future<Ret> f = std::async(std::forward<Args>(args)...); + std::this_thread::sleep_for(ms(300)); - { - std::future<void> f = std::async(f2); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - f.get(); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<void> f = std::async(std::launch::async, f2); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - f.get(); - Clock::time_point t1 = Clock::now(); + // Check that deferred async's have not invoked the function. + assert(invoked == !IsDeferred); + + // Time the call to f.get() and check that the returned value matches + // what is expected. + Clock::time_point t0 = Clock::now(); + assert(getAndCheckFn(f)); + Clock::time_point t1 = Clock::now(); + + // If the async is deferred it should take more than 100ms, otherwise + // it should take less than 100ms. + if (IsDeferred) { + assert(t1-t0 > ms(100)); + } else { assert(t1-t0 < ms(100)); } +} + +int main() +{ + // The default launch policy is implementation defined. libc++ defines + // it to be std::launch::async. + bool DefaultPolicyIsDeferred = false; + bool DPID = DefaultPolicyIsDeferred; + + std::launch AnyPolicy = std::launch::async | std::launch::deferred; + LIBCPP_ASSERT(AnyPolicy == std::launch::any); + { - std::future<void> f = std::async(std::launch::any, f2); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - f.get(); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); + auto checkInt = [](std::future<int>& f) { return f.get() == 3; }; + test<int>(checkInt, DPID, f0); + test<int>(checkInt, false, std::launch::async, f0); + test<int>(checkInt, true, std::launch::deferred, f0); + test<int>(checkInt, DPID, AnyPolicy, f0); } { - std::future<void> f = std::async(std::launch::deferred, f2); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - f.get(); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 > ms(100)); + auto checkIntRef = [&](std::future<int&>& f) { return &f.get() == &i; }; + test<int&>(checkIntRef, DPID, f1); + test<int&>(checkIntRef, false, std::launch::async, f1); + test<int&>(checkIntRef, true, std::launch::deferred, f1); + test<int&>(checkIntRef, DPID, AnyPolicy, f1); } - { - std::future<std::unique_ptr<int>> f = std::async(f3, 3); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(*f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); + auto checkVoid = [](std::future<void>& f) { f.get(); return true; }; + test<void>(checkVoid, DPID, f2); + test<void>(checkVoid, false, std::launch::async, f2); + test<void>(checkVoid, true, std::launch::deferred, f2); + test<void>(checkVoid, DPID, AnyPolicy, f2); } - { - std::future<std::unique_ptr<int>> f = - std::async(f4, std::unique_ptr<int>(new int(3))); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(*f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); + using Ret = std::unique_ptr<int>; + auto checkUPtr = [](std::future<Ret>& f) { return *f.get() == 3; }; + test<Ret>(checkUPtr, DPID, f3, 3); + test<Ret>(checkUPtr, DPID, f4, std::unique_ptr<int>(new int(3))); } - { std::future<void> f = std::async(f5, 3); std::this_thread::sleep_for(ms(300)); - try { f.get(); assert (false); } catch ( int ex ) {} + try { f.get(); assert (false); } catch ( int ) {} } - { std::future<void> f = std::async(std::launch::deferred, f5, 3); std::this_thread::sleep_for(ms(300)); - try { f.get(); assert (false); } catch ( int ex ) {} + try { f.get(); assert (false); } catch ( int ) {} } - } diff --git a/test/std/thread/futures/futures.overview/future_errc.pass.cpp b/test/std/thread/futures/futures.overview/future_errc.pass.cpp index 1e6fcb76a0e73..06397487a7344 100644 --- a/test/std/thread/futures/futures.overview/future_errc.pass.cpp +++ b/test/std/thread/futures/futures.overview/future_errc.pass.cpp @@ -9,22 +9,32 @@ // // UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: c++98, c++03 +// Libc++'s enum class emulation does not allow static_cast<Enum>(0) to work. + // <future> // enum class future_errc // { -// future_already_retrieved = 1, -// promise_already_satisfied, -// no_state -// broken_promise, +// broken_promise = implementation-defined, +// future_already_retrieved = implementation-defined, +// promise_already_satisfied = implementation-defined, +// no_state = implementation-defined // }; #include <future> int main() { - static_assert(static_cast<int>(std::future_errc::future_already_retrieved) == 1, ""); - static_assert(static_cast<int>(std::future_errc::promise_already_satisfied) == 2, ""); - static_assert(static_cast<int>(std::future_errc::no_state) == 3, ""); - static_assert(static_cast<int>(std::future_errc::broken_promise) == 4, ""); + static_assert(std::future_errc::broken_promise != std::future_errc::future_already_retrieved, ""); + static_assert(std::future_errc::broken_promise != std::future_errc::promise_already_satisfied, ""); + static_assert(std::future_errc::broken_promise != std::future_errc::no_state, ""); + static_assert(std::future_errc::future_already_retrieved != std::future_errc::promise_already_satisfied, ""); + static_assert(std::future_errc::future_already_retrieved != std::future_errc::no_state, ""); + static_assert(std::future_errc::promise_already_satisfied != std::future_errc::no_state, ""); + + static_assert(std::future_errc::broken_promise != static_cast<std::future_errc>(0), ""); + static_assert(std::future_errc::future_already_retrieved != static_cast<std::future_errc>(0), ""); + static_assert(std::future_errc::promise_already_satisfied != static_cast<std::future_errc>(0), ""); + static_assert(std::future_errc::no_state != static_cast<std::future_errc>(0), ""); } diff --git a/test/std/thread/futures/futures.overview/launch.pass.cpp b/test/std/thread/futures/futures.overview/launch.pass.cpp index da54f7ee67329..a26b01f67b3e7 100644 --- a/test/std/thread/futures/futures.overview/launch.pass.cpp +++ b/test/std/thread/futures/futures.overview/launch.pass.cpp @@ -15,28 +15,30 @@ // { // async = 1, // deferred = 2, -// any = async | deferred +// any = async | deferred /* EXTENSION */ // }; #include <future> #include <cassert> +#include "test_macros.h" + int main() { #ifdef _LIBCPP_HAS_NO_STRONG_ENUMS - static_assert(static_cast<int>(std::launch::any) == + LIBCPP_STATIC_ASSERT(static_cast<int>(std::launch::any) == (static_cast<int>(std::launch::async) | static_cast<int>(std::launch::deferred)), ""); #else - static_assert(std::launch::any == (std::launch::async | std::launch::deferred), ""); + LIBCPP_STATIC_ASSERT(std::launch::any == (std::launch::async | std::launch::deferred), ""); static_assert(std::launch(0) == (std::launch::async & std::launch::deferred), ""); - static_assert(std::launch::any == (std::launch::async ^ std::launch::deferred), ""); - static_assert(std::launch::deferred == ~std::launch::async, ""); + LIBCPP_STATIC_ASSERT(std::launch::any == (std::launch::async ^ std::launch::deferred), ""); + LIBCPP_STATIC_ASSERT(std::launch::deferred == ~std::launch::async, ""); std::launch x = std::launch::async; x &= std::launch::deferred; assert(x == std::launch(0)); x = std::launch::async; x |= std::launch::deferred; - assert(x == std::launch::any); + LIBCPP_ASSERT(x == std::launch::any); x ^= std::launch::deferred; assert(x == std::launch::async); #endif diff --git a/test/std/thread/futures/futures.promise/copy_assign.fail.cpp b/test/std/thread/futures/futures.promise/copy_assign.fail.cpp index e150ba0df65a1..0311cf9b6b00f 100644 --- a/test/std/thread/futures/futures.promise/copy_assign.fail.cpp +++ b/test/std/thread/futures/futures.promise/copy_assign.fail.cpp @@ -6,6 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads // <future> diff --git a/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp b/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp index 34becbc1259b3..779fc5bfc7c44 100644 --- a/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp +++ b/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp @@ -6,6 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads // <future> diff --git a/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp b/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp index 9cce3f59550a2..e0c6e15d98d5e 100644 --- a/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp +++ b/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp @@ -7,8 +7,7 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: libcpp-no-exceptions -// UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: libcpp-has-no-threads, libcpp-no-exceptions // <future> diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp b/test/std/thread/futures/futures.task/futures.task.members/assign_copy.fail.cpp index 6c6418594d007..9449e1490270d 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/assign_copy.fail.cpp @@ -6,7 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// - +// +// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03 // <future> diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/assign_move.pass.cpp index 3f11d670bede3..3f11d670bede3 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/assign_move.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor1.fail.cpp index 7097d428962af..6d7d734bd5e7e 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor1.fail.cpp @@ -6,7 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// - +// +// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03 // <future> @@ -14,7 +15,7 @@ // class packaged_task<R(ArgTypes...)> // template <class F> // packaged_task(F&& f); -// These constructors shall not participate in overload resolution if +// These constructors shall not participate in overload resolution if // decay<F>::type is the same type as std::packaged_task<R(ArgTypes...)>. #include <future> diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor2.fail.cpp index feb7657bed37e..984dcdc80b32e 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor2.fail.cpp @@ -6,7 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// - +// +// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03 // <future> @@ -14,7 +15,7 @@ // class packaged_task<R(ArgTypes...)> // template <class F, class Allocator> // packaged_task(allocator_arg_t, const Allocator& a, F&& f); -// These constructors shall not participate in overload resolution if +// These constructors shall not participate in overload resolution if // decay<F>::type is the same type as std::packaged_task<R(ArgTypes...)>. #include <future> diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor_copy.fail.cpp index 97624f90f3dfe..ff07db9a2e6f1 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor_copy.fail.cpp @@ -6,7 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// - +// +// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03 // <future> diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor_default.pass.cpp index ed147d74895b1..ed147d74895b1 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor_default.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor_func.pass.cpp index 14ac7614bb8e5..14ac7614bb8e5 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor_func.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor_func_alloc.pass.cpp index 39784876b8c31..39784876b8c31 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor_func_alloc.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor_move.pass.cpp index d9951dca585ab..d9951dca585ab 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor_move.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/dtor.pass.cpp index 7fafd10056490..7fafd10056490 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/dtor.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/get_future.pass.cpp index c8e5d6efd6b42..c8e5d6efd6b42 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/get_future.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/make_ready_at_thread_exit.pass.cpp index 54ac644582486..54ac644582486 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/make_ready_at_thread_exit.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/operator.pass.cpp index 9ad1509517f64..9ad1509517f64 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/operator.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/reset.pass.cpp index 02a567500ee2d..02a567500ee2d 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/reset.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/swap.pass.cpp index eb0091c8e8171..eb0091c8e8171 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/swap.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp b/test/std/thread/futures/futures.task/futures.task.nonmembers/swap.pass.cpp index d90d593a75bdf..d90d593a75bdf 100644 --- a/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.nonmembers/swap.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp b/test/std/thread/futures/futures.task/futures.task.nonmembers/uses_allocator.pass.cpp index bbe75de7f8a9c..bbe75de7f8a9c 100644 --- a/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.nonmembers/uses_allocator.pass.cpp diff --git a/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp b/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp index 781c9c9d61991..d20f0c38071f4 100644 --- a/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp +++ b/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp @@ -6,6 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads // <future> diff --git a/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp b/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp index 0d7b5f5074d39..e1d85ac2cfdde 100644 --- a/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp +++ b/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp @@ -6,6 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads // <future> diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp index 246eb935c995d..520c9730bdf7a 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcpp-has-no-threads + // <mutex> // template <class Mutex> class lock_guard; @@ -14,35 +16,9 @@ // explicit lock_guard(mutex_type& m); #include <mutex> -#include <thread> -#include <cstdlib> -#include <cassert> - -std::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(); - time_point t1; - { - std::lock_guard<std::mutex> lg = m; - t1 = Clock::now(); - } - ns d = t1 - t0 - ms(250); - assert(d < ns(2500000)); // within 2.5ms -} int main() { - m.lock(); - std::thread t(f); - std::this_thread::sleep_for(ms(250)); - m.unlock(); - t.join(); + std::mutex m; + std::lock_guard<std::mutex> lg = m; // expected-error{{no viable conversion}} } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp new file mode 100644 index 0000000000000..840af6788d04f --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class ...Mutex> class lock_guard; + +// lock_guard(Mutex&..., adopt_lock_t); + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include <mutex> +#include <cassert> + +struct TestMutex { + bool locked = false; + TestMutex() = default; + + void lock() { assert(!locked); locked = true; } + bool try_lock() { if (locked) return false; locked = true; return true; } + void unlock() { assert(locked); locked = false; } + + TestMutex(TestMutex const&) = delete; + TestMutex& operator=(TestMutex const&) = delete; +}; + +int main() +{ + { + using LG = std::lock_guard<>; + LG lg(std::adopt_lock); + } + { + TestMutex m1, m2; + using LG = std::lock_guard<TestMutex, TestMutex>; + m1.lock(); m2.lock(); + { + LG lg(m1, m2, std::adopt_lock); + assert(m1.locked && m2.locked); + } + assert(!m1.locked && !m2.locked); + } + { + TestMutex m1, m2, m3; + using LG = std::lock_guard<TestMutex, TestMutex, TestMutex>; + m1.lock(); m2.lock(); m3.lock(); + { + LG lg(m1, m2, m3, std::adopt_lock); + assert(m1.locked && m2.locked && m3.locked); + } + assert(!m1.locked && !m2.locked && !m3.locked); + } + +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp new file mode 100644 index 0000000000000..18193e000edc7 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class ...Mutex> class lock_guard; + +// lock_guard& operator=(lock_guard const&) = delete; + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include <mutex> + +int main() +{ + using M = std::mutex; + M m0, m1, m2; + M om0, om1, om2; + { + using LG = std::lock_guard<>; + LG lg1, lg2; + lg1 = lg2; // expected-error{{overload resolution selected deleted operator '='}} + } + { + using LG = std::lock_guard<M, M>; + LG lg1(m0, m1); + LG lg2(om0, om1); + lg1 = lg2; // expected-error{{overload resolution selected deleted operator '='}} + } + { + using LG = std::lock_guard<M, M, M>; + LG lg1(m0, m1, m2); + LG lg2(om0, om1, om2); + lg1 = lg2; // expected-error{{overload resolution selected deleted operator '='}} + } +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp new file mode 100644 index 0000000000000..6dc37e970fb60 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.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: libcpp-has-no-threads +// UNSUPPORTED: c++98, c++03 + +// <mutex> + +// template <class ...Mutex> class lock_guard; + +// lock_guard(lock_guard const&) = delete; + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include <mutex> + +int main() +{ + using M = std::mutex; + M m0, m1, m2; + { + using LG = std::lock_guard<>; + const LG Orig; + LG Copy(Orig); // expected-error{{call to deleted constructor of 'LG'}} + } + { + using LG = std::lock_guard<M, M>; + const LG Orig(m0, m1); + LG Copy(Orig); // expected-error{{call to deleted constructor of 'LG'}} + } + { + using LG = std::lock_guard<M, M, M>; + const LG Orig(m0, m1, m2); + LG Copy(Orig); // expected-error{{call to deleted constructor of 'LG'}} + } +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp new file mode 100644 index 0000000000000..866538a2834f5 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class ...Mutex> class lock_guard; + +// explicit lock_guard(Mutex&...); + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include <mutex> + +template <class LG> +void test_conversion(LG) {} + +int main() +{ + using M = std::mutex; + M m0, m1, m2; + M n0, n1, n2; + { + using LG = std::lock_guard<>; + LG lg = {}; // expected-error{{chosen constructor is explicit in copy-initialization}} + test_conversion<LG>({}); // expected-error{{no matching function for call}} + ((void)lg); + } + { + using LG = std::lock_guard<M, M>; + LG lg = {m0, m1}; // expected-error{{chosen constructor is explicit in copy-initialization}} + test_conversion<LG>({n0, n1}); // expected-error{{no matching function for call}} + ((void)lg); + } + { + using LG = std::lock_guard<M, M, M>; + LG lg = {m0, m1, m2}; // expected-error{{chosen constructor is explicit in copy-initialization}} + test_conversion<LG>({n0, n1, n2}); // expected-error{{no matching function for call}} + } +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp new file mode 100644 index 0000000000000..4910d837cae32 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class ...Mutex> class lock_guard; + +// explicit lock_guard(mutex_type& m); + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include <mutex> +#include <cassert> + +#include "test_macros.h" + +struct TestMutex { + bool locked = false; + TestMutex() = default; + ~TestMutex() { assert(!locked); } + + void lock() { assert(!locked); locked = true; } + bool try_lock() { if (locked) return false; locked = true; return true; } + void unlock() { assert(locked); locked = false; } + + TestMutex(TestMutex const&) = delete; + TestMutex& operator=(TestMutex const&) = delete; +}; + +#if !defined(TEST_HAS_NO_EXCEPTIONS) +struct TestMutexThrows { + bool locked = false; + bool throws_on_lock = false; + + TestMutexThrows() = default; + ~TestMutexThrows() { assert(!locked); } + + void lock() { + assert(!locked); + if (throws_on_lock) { + throw 42; + } + locked = true; + } + + bool try_lock() { + if (locked) return false; + lock(); + return true; + } + + void unlock() { assert(locked); locked = false; } + + TestMutexThrows(TestMutexThrows const&) = delete; + TestMutexThrows& operator=(TestMutexThrows const&) = delete; +}; +#endif // !defined(TEST_HAS_NO_EXCEPTIONS) + +int main() +{ + { + using LG = std::lock_guard<>; + LG lg; + } + { + using LG = std::lock_guard<TestMutex, TestMutex>; + TestMutex m1, m2; + { + LG lg(m1, m2); + assert(m1.locked && m2.locked); + } + assert(!m1.locked && !m2.locked); + } + { + using LG = std::lock_guard<TestMutex, TestMutex, TestMutex>; + TestMutex m1, m2, m3; + { + LG lg(m1, m2, m3); + assert(m1.locked && m2.locked && m3.locked); + } + assert(!m1.locked && !m2.locked && !m3.locked); + } +#if !defined(TEST_HAS_NO_EXCEPTIONS) + { + using MT = TestMutexThrows; + using LG = std::lock_guard<MT, MT>; + MT m1, m2; + m1.throws_on_lock = true; + try { + LG lg(m1, m2); + assert(false); + } catch (int) {} + assert(!m1.locked && !m2.locked); + } + { + using MT = TestMutexThrows; + using LG = std::lock_guard<MT, MT, MT>; + MT m1, m2, m3; + m2.throws_on_lock = true; + try { + LG lg(m1, m2, m3); + assert(false); + } catch (int) {} + assert(!m1.locked && !m2.locked && !m3.locked); + } +#endif +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp new file mode 100644 index 0000000000000..3c134e0b88615 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <mutex> + +// template <class ...Mutex> class lock_guard; + +// Test that the variadic lock guard implementation compiles in all standard +// dialects, including C++03, even though it is forward declared using +// variadic templates. + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include "mutex.pass.cpp" // Use the existing non-variadic test diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp new file mode 100644 index 0000000000000..2b06742a673e6 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.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. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: c++98, c++03 + +// <mutex> + +// template <class Mutex> +// class lock_guard +// { +// public: +// typedef Mutex mutex_type; +// ... +// }; + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include <mutex> +#include <type_traits> + +struct NAT {}; + +template <class LG> +auto test_typedef(int) -> typename LG::mutex_type; + +template <class LG> +auto test_typedef(...) -> NAT; + +template <class LG> +constexpr bool has_mutex_type() { + return !std::is_same<decltype(test_typedef<LG>(0)), NAT>::value; +} + +int main() +{ + { + using T = std::lock_guard<>; + static_assert(!has_mutex_type<T>(), ""); + } + { + using M1 = std::mutex; + using T = std::lock_guard<M1>; + static_assert(std::is_same<T::mutex_type, M1>::value, ""); + } + { + using M1 = std::recursive_mutex; + using T = std::lock_guard<M1>; + static_assert(std::is_same<T::mutex_type, M1>::value, ""); + } + { + using M1 = std::mutex; + using M2 = std::recursive_mutex; + using T = std::lock_guard<M1, M2>; + static_assert(!has_mutex_type<T>(), ""); + } + { + using M1 = std::mutex; + using M2 = std::recursive_mutex; + using T = std::lock_guard<M1, M1, M2>; + static_assert(!has_mutex_type<T>(), ""); + } + { + using M1 = std::mutex; + using T = std::lock_guard<M1, M1>; + static_assert(!has_mutex_type<T>(), ""); + } + { + using M1 = std::recursive_mutex; + using T = std::lock_guard<M1, M1, M1>; + static_assert(!has_mutex_type<T>(), ""); + } +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp index 446807f3f3335..79f43e860ca2f 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <shared_mutex> // template <class Mutex> class shared_lock; @@ -15,20 +16,12 @@ #include <shared_mutex> -#if _LIBCPP_STD_VER > 11 - std::shared_timed_mutex m0; std::shared_timed_mutex m1; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 std::shared_lock<std::shared_timed_mutex> lk0(m0); std::shared_lock<std::shared_timed_mutex> lk1(m1); lk1 = lk0; -#else -# error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp index 370c1fa4e3361..d6bf57947afe0 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <shared_mutex> // template <class Mutex> class shared_lock; @@ -15,16 +16,10 @@ #include <shared_mutex> -#if _LIBCPP_STD_VER > 11 std::shared_timed_mutex m; -#endif // _LIBCPP_STD_VER > 11 int main() { -#if _LIBCPP_STD_VER > 11 std::shared_lock<std::shared_timed_mutex> lk0(m); std::shared_lock<std::shared_timed_mutex> lk = lk0; -#else -# error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp index 15c193c60b5d3..bd707bb90ce10 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp @@ -18,17 +18,33 @@ #include <shared_mutex> #include <cassert> +#include "nasty_containers.hpp" -std::shared_timed_mutex m0; -std::shared_timed_mutex m1; int main() { - std::shared_lock<std::shared_timed_mutex> lk0(m0); - std::shared_lock<std::shared_timed_mutex> lk1(m1); + { + typedef std::shared_timed_mutex M; + M m0; + M m1; + std::shared_lock<M> lk0(m0); + std::shared_lock<M> lk1(m1); lk1 = std::move(lk0); - assert(lk1.mutex() == &m0); + assert(lk1.mutex() == std::addressof(m0)); assert(lk1.owns_lock() == true); assert(lk0.mutex() == nullptr); assert(lk0.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m0; + M m1; + std::shared_lock<M> lk0(m0); + std::shared_lock<M> lk1(m1); + lk1 = std::move(lk0); + assert(lk1.mutex() == std::addressof(m0)); + assert(lk1.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); + } } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp index 4f4f6a5e9fbdb..c29a3fb04d0ff 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp @@ -18,14 +18,28 @@ #include <shared_mutex> #include <cassert> +#include "nasty_containers.hpp" int main() { - std::shared_timed_mutex m; - std::shared_lock<std::shared_timed_mutex> lk0(m); - std::shared_lock<std::shared_timed_mutex> lk = std::move(lk0); - assert(lk.mutex() == &m); + { + typedef std::shared_timed_mutex M; + M m; + std::shared_lock<M> lk0(m); + std::shared_lock<M> lk = std::move(lk0); + assert(lk.mutex() == std::addressof(m)); assert(lk.owns_lock() == true); assert(lk0.mutex() == nullptr); assert(lk0.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m; + std::shared_lock<M> lk0(m); + std::shared_lock<M> lk = std::move(lk0); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); + } } 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 995210221065e..341f0ce7efd2c 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 @@ -18,12 +18,24 @@ #include <shared_mutex> #include <cassert> +#include "nasty_containers.hpp" int main() { - std::shared_timed_mutex m; - m.lock_shared(); - std::shared_lock<std::shared_timed_mutex> lk(m, std::adopt_lock); - assert(lk.mutex() == &m); + { + typedef std::shared_timed_mutex M; + M m; + m.lock(); + std::unique_lock<M> lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m)); assert(lk.owns_lock() == true); + } + { + typedef nasty_mutex M; + M m; + m.lock(); + std::unique_lock<M> lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + } } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp index d81796b95bf3c..5fbb7244ef8ef 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp @@ -18,11 +18,22 @@ #include <shared_mutex> #include <cassert> +#include "nasty_containers.hpp" int main() { - std::shared_timed_mutex m; - std::shared_lock<std::shared_timed_mutex> lk(m, std::defer_lock); - assert(lk.mutex() == &m); + { + typedef std::shared_timed_mutex M; + M m; + std::unique_lock<M> lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m)); assert(lk.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m; + std::unique_lock<M> lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == false); + } } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp index 4f477449d6a28..8d864ea8e7da6 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp @@ -16,16 +16,18 @@ #include <mutex> #include <cassert> -std::mutex m0; -std::mutex m1; - int main() { - std::unique_lock<std::mutex> lk0(m0); - std::unique_lock<std::mutex> lk1(m1); + { + typedef std::mutex M; + M m0; + M m1; + std::unique_lock<M> lk0(m0); + std::unique_lock<M> lk1(m1); lk1 = lk0; assert(lk1.mutex() == &m0); assert(lk1.owns_lock() == true); assert(lk0.mutex() == nullptr); assert(lk0.owns_lock() == false); + } } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp index 4888fe90d92c6..067302127cadf 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp @@ -16,14 +16,16 @@ #include <mutex> #include <cassert> -std::mutex m; - int main() { - std::unique_lock<std::mutex> lk0(m); - std::unique_lock<std::mutex> lk = lk0; + { + typedef std::mutex M; + M m; + std::unique_lock<M> lk0(m); + std::unique_lock<M> lk = lk0; assert(lk.mutex() == &m); assert(lk.owns_lock() == true); assert(lk0.mutex() == nullptr); assert(lk0.owns_lock() == false); + } } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp index 4dff853088ac7..e5db685e46e75 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp @@ -17,19 +17,34 @@ #include <mutex> #include <cassert> - -std::mutex m0; -std::mutex m1; +#include "nasty_containers.hpp" int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - std::unique_lock<std::mutex> lk0(m0); - std::unique_lock<std::mutex> lk1(m1); + { + typedef std::mutex M; + M m0; + M m1; + std::unique_lock<M> lk0(m0); + std::unique_lock<M> lk1(m1); + lk1 = std::move(lk0); + assert(lk1.mutex() == std::addressof(m0)); + assert(lk1.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m0; + M m1; + std::unique_lock<M> lk0(m0); + std::unique_lock<M> lk1(m1); lk1 = std::move(lk0); - assert(lk1.mutex() == &m0); + assert(lk1.mutex() == std::addressof(m0)); assert(lk1.owns_lock() == true); assert(lk0.mutex() == nullptr); assert(lk0.owns_lock() == false); + } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp index aa640ee6d746f..427deabc5a59d 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp @@ -17,17 +17,30 @@ #include <mutex> #include <cassert> - -std::mutex m; +#include "nasty_containers.hpp" int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - std::unique_lock<std::mutex> lk0(m); - std::unique_lock<std::mutex> lk = std::move(lk0); - assert(lk.mutex() == &m); + { + typedef std::mutex M; + M m; + std::unique_lock<M> lk0(m); + std::unique_lock<M> lk = std::move(lk0); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m; + std::unique_lock<M> lk0(m); + std::unique_lock<M> lk = std::move(lk0); + assert(lk.mutex() == std::addressof(m)); assert(lk.owns_lock() == true); assert(lk0.mutex() == nullptr); assert(lk0.owns_lock() == false); + } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp index 9c3a7b6505a46..20f7d249b6f49 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp @@ -17,12 +17,24 @@ #include <mutex> #include <cassert> +#include "nasty_containers.hpp" int main() { - std::mutex m; + { + typedef std::mutex M; + M m; m.lock(); - std::unique_lock<std::mutex> lk(m, std::adopt_lock); - assert(lk.mutex() == &m); + std::unique_lock<M> lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m)); assert(lk.owns_lock() == true); + } + { + typedef nasty_mutex M; + M m; + m.lock(); + std::unique_lock<M> lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + } } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp index bf622311f0132..242dacb1eb922 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp @@ -17,11 +17,22 @@ #include <mutex> #include <cassert> +#include "nasty_containers.hpp" int main() { - std::mutex m; - std::unique_lock<std::mutex> lk(m, std::defer_lock); - assert(lk.mutex() == &m); + { + typedef std::mutex M; + M m; + std::unique_lock<M> lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m)); assert(lk.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m; + std::unique_lock<M> lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == false); + } } 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 index 5c67a34ab52bb..81995f6c88883 100644 --- 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 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// // +// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03, c++11, c++14 // <shared_mutex> diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp index c7cac6041c824..e4bee4bb7ad13 100644 --- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// // +// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03, c++11, c++14 // <shared_mutex> diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp index 528aaca6d9e14..0c5bfa804bea2 100644 --- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <shared_mutex> // class shared_timed_mutex; @@ -17,11 +18,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 std::shared_timed_mutex m0; std::shared_timed_mutex m1; m1 = m0; -#else -# error -#endif } diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp index dbf01002e6912..3656ec62ec17a 100644 --- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <shared_mutex> // class shared_timed_mutex; @@ -17,10 +18,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 std::shared_timed_mutex m0; std::shared_timed_mutex m1(m0); -#else -# error -#endif } 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 afc318cc3d7a5..71b054fced886 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 @@ -21,6 +21,8 @@ #include <thread> #include <cassert> +#include "test_macros.h" + typedef std::chrono::milliseconds ms; std::once_flag flg0; @@ -171,7 +173,7 @@ public: void operator()(int&) {} }; -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 // reference qualifiers on functions are a C++11 extension struct RefQual { @@ -240,7 +242,7 @@ int main() int i = 0; std::call_once(f, NonCopyable(), i); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 // reference qualifiers on functions are a C++11 extension { std::once_flag f1, f2; 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 3de15af8929bf..5dd6a40a0eb7a 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 @@ -20,23 +20,30 @@ #include <thread> #include <new> +#include <atomic> #include <cstdlib> #include <cassert> #include "test_macros.h" -unsigned throw_one = 0xFFFF; +std::atomic<unsigned> throw_one(0xFFFF); +std::atomic<unsigned> outstanding_new(0); + void* operator new(std::size_t s) throw(std::bad_alloc) { if (throw_one == 0) throw std::bad_alloc(); --throw_one; - return std::malloc(s); + ++outstanding_new; + void* ret = std::malloc(s); + if (!ret) std::abort(); // placate MSVC's unchecked malloc warning + return ret; } void operator delete(void* p) throw() { + --outstanding_new; std::free(p); } @@ -94,27 +101,58 @@ public: #endif -int main() -{ +// Test throwing std::bad_alloc +//----------------------------- +// Concerns: +// A Each allocation performed during thread construction should be performed +// in the parent thread so that std::terminate is not called if +// std::bad_alloc is thrown by new. +// B std::threads constructor should properly handle exceptions and not leak +// memory. +// Plan: +// 1 Create a thread and count the number of allocations, 'N', it performs. +// 2 For each allocation performed run a test where that allocation throws. +// 2.1 check that the exception can be caught in the parent thread. +// 2.2 Check that the functor has not been called. +// 2.3 Check that no memory allocated by the creation of the thread is leaked. +// 3 Finally check that a thread runs successfully if we throw after 'N+1' +// allocations. +void test_throwing_new_during_thread_creation() { + throw_one = 0xFFF; { std::thread t(f); t.join(); - assert(f_run == true); } - f_run = false; - { - try - { - throw_one = 0; + const int numAllocs = 0xFFF - throw_one; + // i <= numAllocs means the last iteration is expected not to throw. + for (int i=0; i <= numAllocs; ++i) { + throw_one = i; + f_run = false; + unsigned old_outstanding = outstanding_new; + try { std::thread t(f); - assert(false); - } - catch (...) - { - throw_one = 0xFFFF; - assert(!f_run); + assert(i == numAllocs); // Only final iteration will not throw. + t.join(); + assert(f_run); + } catch (std::bad_alloc const&) { + assert(i < numAllocs); + assert(!f_run); // (2.2) } + assert(old_outstanding == outstanding_new); // (2.3) + } + f_run = false; + throw_one = 0xFFF; +} + +int main() +{ + test_throwing_new_during_thread_creation(); + { + std::thread t(f); + t.join(); + assert(f_run == true); } + { assert(G::n_alive == 0); assert(!G::op_run); diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp index a331add962635..54fc0b80280c8 100644 --- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp @@ -12,7 +12,7 @@ // class thread // template <class _Fp, class ..._Args, // explicit thread(_Fp&& __f, _Args&&... __args); -// This constructor shall not participate in overload resolution +// This constructor shall not participate in overload resolution // if decay<F>::type is the same type as std::thread. 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 726395d990440..3dd7c6a6014c6 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 @@ -17,8 +17,11 @@ #include <thread> #include <atomic> +#include <system_error> #include <cassert> +#include "test_macros.h" + std::atomic_bool done(false); class G @@ -57,6 +60,8 @@ public: int G::n_alive = 0; bool G::op_run = false; +void foo() {} + int main() { { @@ -70,4 +75,16 @@ int main() assert(G::n_alive == 1); } assert(G::n_alive == 0); +#ifndef TEST_HAS_NO_EXCEPTIONS + { + std::thread t0(foo); + assert(t0.joinable()); + t0.detach(); + assert(!t0.joinable()); + try { + t0.detach(); + } catch (std::system_error const&) { + } + } +#endif } 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 0512e49dcb336..f0c3ef74c9abb 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 @@ -19,6 +19,9 @@ #include <new> #include <cstdlib> #include <cassert> +#include <system_error> + +#include "test_macros.h" class G { @@ -42,6 +45,8 @@ public: int G::n_alive = 0; bool G::op_run = false; +void foo() {} + int main() { { @@ -50,5 +55,23 @@ int main() assert(t0.joinable()); t0.join(); assert(!t0.joinable()); +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + t0.join(); + assert(false); + } catch (std::system_error const&) { + } +#endif + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + std::thread t0(foo); + t0.detach(); + try { + t0.join(); + assert(false); + } catch (std::system_error const&) { + } } +#endif } diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/allocator_pointers.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/allocator_pointers.pass.cpp index e165d9836db00..81c366e0668f4 100644 --- a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/allocator_pointers.pass.cpp +++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/allocator_pointers.pass.cpp @@ -11,7 +11,9 @@ #include <memory> #include <cassert> -#if __cplusplus >= 201103L +#include "test_macros.h" + +#if TEST_STD_VER >= 11 // #include <memory> // // template <class Alloc> @@ -20,7 +22,7 @@ // typedef Alloc allocator_type; // typedef typename allocator_type::value_type // value_type; -// +// // typedef Alloc::pointer | value_type* pointer; // typedef Alloc::const_pointer // | pointer_traits<pointer>::rebind<const value_type> @@ -37,7 +39,10 @@ void test_pointer() { typename std::allocator_traits<Alloc>::pointer vp; typename std::allocator_traits<Alloc>::const_pointer cvp; - + + ((void)vp); // Prevent unused warning + ((void)cvp); // Prevent unused warning + static_assert(std::is_same<bool, decltype( vp == vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp != vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp > vp)>::value, ""); @@ -71,7 +76,10 @@ void test_void_pointer() { typename std::allocator_traits<Alloc>::void_pointer vp; typename std::allocator_traits<Alloc>::const_void_pointer cvp; - + + ((void)vp); // Prevent unused warning + ((void)cvp); // Prevent unused warning + static_assert(std::is_same<bool, decltype( vp == vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp != vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp > vp)>::value, ""); @@ -110,7 +118,7 @@ int main() test_void_pointer<std::scoped_allocator_adaptor<std::allocator<char>>> (); test_void_pointer<std::scoped_allocator_adaptor<std::allocator<int>>> (); - test_void_pointer<std::scoped_allocator_adaptor<std::allocator<Foo>>> (); + test_void_pointer<std::scoped_allocator_adaptor<std::allocator<Foo>>> (); } #else int main() {} 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 index e19e731f6cf2b..90fe944125b5f 100644 --- 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 @@ -32,7 +32,7 @@ int main() 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< @@ -51,14 +51,14 @@ int main() 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) + 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) + std::allocator_traits<min_allocator<int>>::is_always_equal::value) ), ""); @@ -66,8 +66,8 @@ int main() 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) + std::allocator_traits<A2<int>>::is_always_equal::value && + std::allocator_traits<A3<int>>::is_always_equal::value) ), ""); diff --git a/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/eq.pass.cpp b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/eq.pass.cpp index 8d4cb6abe84a0..51dd67f9ffdc9 100644 --- a/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/eq.pass.cpp +++ b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/eq.pass.cpp @@ -16,7 +16,7 @@ // bool // operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, // const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b); -// +// // template <class OuterA1, class OuterA2, class... InnerAllocs> // bool // operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, diff --git a/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp index 3c093fc093c32..ce544c78b6768 100644 --- a/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp +++ b/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp @@ -29,7 +29,7 @@ int main() assert(f2(3,2) == 5); assert(f2(3.0, 2) == 5); assert(f2(3, 2.5) == 5.5); - + constexpr int foo = std::plus<int> () (3, 2); static_assert ( foo == 5, "" ); diff --git a/test/std/utilities/function.objects/arithmetic.operations/transparent.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/transparent.pass.cpp index 72b4b4a0a1fe7..b85f439ba7a02 100644 --- a/test/std/utilities/function.objects/arithmetic.operations/transparent.pass.cpp +++ b/test/std/utilities/function.objects/arithmetic.operations/transparent.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <functional> #include <string> @@ -22,9 +23,8 @@ public: }; -int main () { -#if _LIBCPP_STD_VER > 11 - +int main () +{ static_assert ( !is_transparent<std::plus<int>>::value, "" ); static_assert ( !is_transparent<std::plus<std::string>>::value, "" ); static_assert ( is_transparent<std::plus<void>>::value, "" ); @@ -54,8 +54,6 @@ int main () { static_assert ( !is_transparent<std::negate<std::string>>::value, "" ); static_assert ( is_transparent<std::negate<void>>::value, "" ); static_assert ( is_transparent<std::negate<>>::value, "" ); - -#endif return 0; - } +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/PR23141_invoke_not_constexpr.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/PR23141_invoke_not_constexpr.pass.cpp new file mode 100644 index 0000000000000..5e347c4c57156 --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/PR23141_invoke_not_constexpr.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// template<CopyConstructible Fn, CopyConstructible... Types> +// unspecified bind(Fn, Types...); +// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types> +// unspecified bind(Fn, Types...); + +// https://llvm.org/bugs/show_bug.cgi?id=23141 +#include <functional> +#include <type_traits> + +struct Fun +{ + template<typename T, typename U> + void operator()(T &&, U &&) const + { + static_assert(std::is_same<U, int &>::value, ""); + } +}; + +int main() +{ + std::bind(Fun{}, std::placeholders::_1, 42)("hello"); +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp new file mode 100644 index 0000000000000..63d3c9b0de923 --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp @@ -0,0 +1,131 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// template<CopyConstructible Fn, CopyConstructible... Types> +// unspecified bind(Fn, Types...); +// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types> +// unspecified bind(Fn, Types...); + +// Check that the call operators have the proper return type and that they +// only SFINAE away when too few arguments are provided. Otherwise they should +// be well formed and should ignore any additional arguments. + +#include <functional> +#include <type_traits> +#include <cassert> + +int dummy = 42; + +int return_value(int) { return dummy; } +int& return_lvalue(int) { return dummy; } +const int& return_const_lvalue(int) { return dummy; } +int&& return_rvalue(int) { return std::move(dummy); } +const int&& return_const_rvalue(int) { return std::move(dummy); } + +template <class Bind, class ...Args> +auto CheckCallImp(int) + -> decltype((std::declval<Bind>()(std::declval<Args>()...)), std::true_type{}); + +template <class Bind, class ...> +auto CheckCallImp(long) -> std::false_type; + +template <class ...Args> +constexpr bool CheckCall() { + return decltype(CheckCallImp<Args...>(0))::value; +} + +template <class Expect, class Fn> +void do_test(Fn* func) { + using namespace std::placeholders; + auto ret = std::bind(func, _1); + auto ret_r = std::bind<Expect>(func, _1); + using Bind = decltype(ret); + using BindR = decltype(ret_r); + + using Ret = decltype(ret(42)); + using Ret2 = decltype(ret(42, 43)); // Test that the extra argument is discarded. + using RetR = decltype(ret_r(42)); + using RetR2 = decltype(ret_r(42, 43)); + + static_assert(std::is_same<Ret, Expect>::value, ""); + static_assert(std::is_same<Ret2, Expect>::value, ""); + static_assert(std::is_same<RetR, Expect>::value, ""); + static_assert(std::is_same<RetR2, Expect>::value, ""); + + Expect exp = ret(100); // the input value is ignored. dummy is returned. + Expect exp2 = ret(101, 102); + Expect exp_r = ret_r(100); + Expect exp_r2 = ret_r(101, 102); + + assert(exp == 42); + assert(exp2 == 42); + assert(exp_r == 42); + assert(exp_r2 == 42); + + if ((std::is_reference<Expect>::value)) { + assert(&exp == &dummy); + assert(&exp2 == &dummy); + assert(&exp_r == &dummy); + assert(&exp_r2 == &dummy); + } + // Check that the call operator SFINAE's away when too few arguments + // are provided but is well-formed otherwise. + { + static_assert(!CheckCall<Bind>(), ""); + static_assert(CheckCall<Bind, int>(), ""); + static_assert(CheckCall<Bind, int, int>(), ""); + static_assert(!CheckCall<BindR>(), ""); + static_assert(CheckCall<BindR, int>(), ""); + static_assert(CheckCall<BindR, int, int>(), ""); + } +} + + +// Test but with an explicit return type which differs from the real one. +template <class Expect, class Fn> +void do_test_r(Fn* func) { + using namespace std::placeholders; + auto ret = std::bind<Expect>(func, _1); + using Bind = decltype(ret); + using Ret = decltype(ret(42)); + using Ret2 = decltype(ret(42, 43)); // Test that the extra argument is discarded. + static_assert(std::is_same<Ret, Expect>::value, ""); + static_assert(std::is_same<Ret2, Expect>::value, ""); + Expect exp = ret(100); // the input value is ignored + Expect exp2 = ret(101, 102); + assert(exp == 42); + assert(exp2 == 42); + // Check that the call operator SFINAE's away when too few arguments + // are provided but is well-formed otherwise. + { + static_assert(!CheckCall<Bind>(), ""); + static_assert(CheckCall<Bind, int>(), ""); + static_assert(CheckCall<Bind, int, int>(), ""); + } +} + +int main() +{ + do_test<int>(return_value); + do_test<int&>(return_lvalue); + do_test<const int&>(return_const_lvalue); + do_test<int&&>(return_rvalue); + do_test<const int&&>(return_const_rvalue); + + do_test_r<long>(return_value); + do_test_r<long>(return_lvalue); + do_test_r<long>(return_const_lvalue); + do_test_r<long>(return_rvalue); + do_test_r<long>(return_const_rvalue); + +} 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 4577d0bf4d54d..a0c686de77ba4 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 @@ -23,7 +23,7 @@ struct DummyUnaryFunction { template <typename S> - int operator()(S const & s) const { return 0; } + int operator()(S const &) const { return 0; } }; struct BadUnaryFunction @@ -39,7 +39,7 @@ struct BadUnaryFunction } }; -int main(int argc, char* argv[]) +int main() { // Check that BadUnaryFunction::operator()(S const &) is not // instantiated when checking if BadUnaryFunction is a nested bind 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 f69afbf576673..dbbd184c7833a 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 @@ -286,4 +286,5 @@ int main() test_void_1(); test_int_1(); test_void_2(); + test3(); } diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp index 246186040c56e..68986ac1aeb34 100644 --- a/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp @@ -10,10 +10,14 @@ // <functional> // placeholders +// The placeholders are constexpr in C++17 and beyond. +// libc++ provides constexpr placeholders in C++11 and beyond. #include <functional> #include <type_traits> +#include "test_macros.h" + template <class T> void test(const T& t) @@ -28,6 +32,30 @@ test(const T& t) static_assert(std::is_nothrow_move_constructible<T>::value, ""); } +#if TEST_STD_VER >= 11 +constexpr decltype(std::placeholders::_1) default1{}; +constexpr decltype(std::placeholders::_2) default2{}; +constexpr decltype(std::placeholders::_3) default3{}; +constexpr decltype(std::placeholders::_4) default4{}; +constexpr decltype(std::placeholders::_5) default5{}; +constexpr decltype(std::placeholders::_6) default6{}; +constexpr decltype(std::placeholders::_7) default7{}; +constexpr decltype(std::placeholders::_8) default8{}; +constexpr decltype(std::placeholders::_9) default9{}; +constexpr decltype(std::placeholders::_10) default10{}; + +constexpr decltype(std::placeholders::_1) cp1 = std::placeholders::_1; +constexpr decltype(std::placeholders::_2) cp2 = std::placeholders::_2; +constexpr decltype(std::placeholders::_3) cp3 = std::placeholders::_3; +constexpr decltype(std::placeholders::_4) cp4 = std::placeholders::_4; +constexpr decltype(std::placeholders::_5) cp5 = std::placeholders::_5; +constexpr decltype(std::placeholders::_6) cp6 = std::placeholders::_6; +constexpr decltype(std::placeholders::_7) cp7 = std::placeholders::_7; +constexpr decltype(std::placeholders::_8) cp8 = std::placeholders::_8; +constexpr decltype(std::placeholders::_9) cp9 = std::placeholders::_9; +constexpr decltype(std::placeholders::_10) cp10 = std::placeholders::_10; +#endif // TEST_STD_VER >= 11 + int main() { test(std::placeholders::_1); diff --git a/test/std/utilities/function.objects/bitwise.operations/bit_not.pass.cpp b/test/std/utilities/function.objects/bitwise.operations/bit_not.pass.cpp index 48800a366a81c..d5788986dd25b 100644 --- a/test/std/utilities/function.objects/bitwise.operations/bit_not.pass.cpp +++ b/test/std/utilities/function.objects/bitwise.operations/bit_not.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <functional> // bit_not @@ -17,7 +18,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 typedef std::bit_not<int> F; const F f = F(); static_assert((std::is_same<F::argument_type, int>::value), "" ); @@ -43,5 +43,4 @@ int main() constexpr int bar = std::bit_not<> () (0xEA95) & 0xFFFF; static_assert ( bar == 0x156A, "" ); -#endif } diff --git a/test/std/utilities/function.objects/bitwise.operations/transparent.pass.cpp b/test/std/utilities/function.objects/bitwise.operations/transparent.pass.cpp index 9f8e15dd55fe0..db7168c44f8be 100644 --- a/test/std/utilities/function.objects/bitwise.operations/transparent.pass.cpp +++ b/test/std/utilities/function.objects/bitwise.operations/transparent.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <functional> #include <string> @@ -23,8 +24,6 @@ public: int main () { -#if _LIBCPP_STD_VER > 11 - static_assert ( !is_transparent<std::bit_and<int>>::value, "" ); static_assert ( !is_transparent<std::bit_and<std::string>>::value, "" ); static_assert ( is_transparent<std::bit_and<void>>::value, "" ); @@ -44,8 +43,6 @@ int main () { static_assert ( !is_transparent<std::bit_not<std::string>>::value, "" ); static_assert ( is_transparent<std::bit_not<void>>::value, "" ); static_assert ( is_transparent<std::bit_not<>>::value, "" ); - -#endif return 0; - } +} diff --git a/test/std/utilities/function.objects/comparisons/equal_to.pass.cpp b/test/std/utilities/function.objects/comparisons/equal_to.pass.cpp index 60415ec75d60f..d4d99756fecc2 100644 --- a/test/std/utilities/function.objects/comparisons/equal_to.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/equal_to.pass.cpp @@ -15,6 +15,8 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" + int main() { typedef std::equal_to<int> F; @@ -24,7 +26,7 @@ int main() static_assert((std::is_same<bool, F::result_type>::value), "" ); assert(f(36, 36)); assert(!f(36, 6)); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 typedef std::equal_to<> F2; const F2 f2 = F2(); assert(f2(36, 36)); diff --git a/test/std/utilities/function.objects/comparisons/greater.pass.cpp b/test/std/utilities/function.objects/comparisons/greater.pass.cpp index 164f09aa605cc..50bdcceee1c98 100644 --- a/test/std/utilities/function.objects/comparisons/greater.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/greater.pass.cpp @@ -15,6 +15,9 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" +#include "pointer_comparison_test_helper.hpp" + int main() { typedef std::greater<int> F; @@ -25,7 +28,12 @@ int main() assert(!f(36, 36)); assert(f(36, 6)); assert(!f(6, 36)); -#if _LIBCPP_STD_VER > 11 + { + // test total ordering of int* for greater<int*> and + // greater<void>. + do_pointer_comparison_test<int, std::greater>(); + } +#if TEST_STD_VER > 11 typedef std::greater<> F2; const F2 f2 = F2(); assert(!f2(36, 36)); diff --git a/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp b/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp index e89c14e246259..0aacb81e9cb47 100644 --- a/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp @@ -15,6 +15,9 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" +#include "pointer_comparison_test_helper.hpp" + int main() { typedef std::greater_equal<int> F; @@ -25,7 +28,12 @@ int main() assert(f(36, 36)); assert(f(36, 6)); assert(!f(6, 36)); -#if _LIBCPP_STD_VER > 11 + { + // test total ordering of int* for greater_equal<int*> and + // greater_equal<void>. + do_pointer_comparison_test<int, std::greater_equal>(); + } +#if TEST_STD_VER > 11 typedef std::greater_equal<> F2; const F2 f2 = F2(); assert(f2(36, 36)); diff --git a/test/std/utilities/function.objects/comparisons/less.pass.cpp b/test/std/utilities/function.objects/comparisons/less.pass.cpp index 74fe166a0cd96..191d58d6e544c 100644 --- a/test/std/utilities/function.objects/comparisons/less.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/less.pass.cpp @@ -15,6 +15,9 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" +#include "pointer_comparison_test_helper.hpp" + int main() { typedef std::less<int> F; @@ -25,7 +28,11 @@ int main() assert(!f(36, 36)); assert(!f(36, 6)); assert(f(6, 36)); -#if _LIBCPP_STD_VER > 11 + { + // test total ordering of int* for less<int*> and less<void>. + do_pointer_comparison_test<int, std::less>(); + } +#if TEST_STD_VER > 11 typedef std::less<> F2; const F2 f2 = F2(); assert(!f2(36, 36)); diff --git a/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp b/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp index e6ba1f7f8a212..a6aca5d195697 100644 --- a/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp @@ -15,6 +15,9 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" +#include "pointer_comparison_test_helper.hpp" + int main() { typedef std::less_equal<int> F; @@ -25,7 +28,12 @@ int main() assert(f(36, 36)); assert(!f(36, 6)); assert(f(6, 36)); -#if _LIBCPP_STD_VER > 11 + { + // test total ordering of int* for less_equal<int*> and + // less_equal<void>. + do_pointer_comparison_test<int, std::less_equal>(); + } +#if TEST_STD_VER > 11 typedef std::less_equal<> F2; const F2 f2 = F2(); assert( f2(36, 36)); diff --git a/test/std/utilities/function.objects/comparisons/not_equal_to.pass.cpp b/test/std/utilities/function.objects/comparisons/not_equal_to.pass.cpp index 3e710b3e0c70b..777c25d520a99 100644 --- a/test/std/utilities/function.objects/comparisons/not_equal_to.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/not_equal_to.pass.cpp @@ -15,6 +15,8 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" + int main() { typedef std::not_equal_to<int> F; @@ -24,7 +26,7 @@ int main() static_assert((std::is_same<bool, F::result_type>::value), "" ); assert(!f(36, 36)); assert(f(36, 6)); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 typedef std::not_equal_to<> F2; const F2 f2 = F2(); assert(!f2(36, 36)); diff --git a/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.hpp b/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.hpp new file mode 100644 index 0000000000000..66d783a6e3577 --- /dev/null +++ b/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.hpp @@ -0,0 +1,39 @@ +#ifndef POINTER_COMPARISON_TEST_HELPER_HPP +#define POINTER_COMPARISON_TEST_HELPER_HPP + +#include <vector> +#include <memory> +#include <cstdint> +#include <cassert> + +#include "test_macros.h" + +template <class T, template<class> class CompareTemplate> +void do_pointer_comparison_test() { + typedef CompareTemplate<T*> Compare; + typedef CompareTemplate<std::uintptr_t> UIntCompare; +#if TEST_STD_VER > 11 + typedef CompareTemplate<void> VoidCompare; +#else + typedef Compare VoidCompare; +#endif + std::vector<std::shared_ptr<T> > pointers; + const std::size_t test_size = 100; + for (int i=0; i < test_size; ++i) + pointers.push_back(std::shared_ptr<T>(new T())); + Compare comp; + UIntCompare ucomp; + VoidCompare vcomp; + for (int i=0; i < test_size; ++i) { + for (int j=0; j < test_size; ++j) { + T* lhs = pointers[i].get(); + T* rhs = pointers[j].get(); + std::uintptr_t lhs_uint = reinterpret_cast<std::uintptr_t>(lhs); + std::uintptr_t rhs_uint = reinterpret_cast<std::uintptr_t>(rhs); + assert(comp(lhs, rhs) == ucomp(lhs_uint, rhs_uint)); + assert(vcomp(lhs, rhs) == ucomp(lhs_uint, rhs_uint)); + } + } +} + +#endif // POINTER_COMPARISON_TEST_HELPER_HPP diff --git a/test/std/utilities/function.objects/comparisons/transparent.pass.cpp b/test/std/utilities/function.objects/comparisons/transparent.pass.cpp index 41ce4bcae65fd..f353fe7a72a6a 100644 --- a/test/std/utilities/function.objects/comparisons/transparent.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/transparent.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <functional> #include <string> @@ -22,9 +23,8 @@ public: }; -int main () { -#if _LIBCPP_STD_VER > 11 - +int main () +{ static_assert ( !is_transparent<std::less<int>>::value, "" ); static_assert ( !is_transparent<std::less<std::string>>::value, "" ); static_assert ( is_transparent<std::less<void>>::value, "" ); @@ -55,7 +55,5 @@ int main () { static_assert ( is_transparent<std::greater_equal<void>>::value, "" ); static_assert ( is_transparent<std::greater_equal<>>::value, "" ); -#endif - return 0; - } +} diff --git a/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp b/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp index 97b0b4d158a0c..d1ae6b7809ce8 100644 --- a/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp +++ b/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp @@ -174,6 +174,32 @@ void bullet_one_two_tests() { } { TestClass cl_obj(42); + std::reference_wrapper<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); + + 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_obj(42); + std::reference_wrapper<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); + + 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); @@ -219,6 +245,22 @@ void bullet_three_four_tests() { } { typedef TestClass Fn; + Fn cl(42); + test_b34<int&>(std::reference_wrapper<Fn>(cl)); + test_b34<int const&>(std::reference_wrapper<Fn const>(cl)); + test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl)); + test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl)); + } + { + typedef DerivedFromTestClass Fn; + Fn cl(42); + test_b34<int&>(std::reference_wrapper<Fn>(cl)); + test_b34<int const&>(std::reference_wrapper<Fn const>(cl)); + test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl)); + test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl)); + } + { + typedef TestClass Fn; Fn cl_obj(42); Fn* cl = &cl_obj; test_b34<int&>(cl); @@ -262,8 +304,46 @@ void bullet_five_tests() { } } +struct CopyThrows { + CopyThrows() {} + CopyThrows(CopyThrows const&) {} + CopyThrows(CopyThrows&&) noexcept {} +}; + +struct NoThrowCallable { + void operator()() noexcept {} + void operator()(CopyThrows) noexcept {} +}; + +struct ThrowsCallable { + void operator()() {} +}; + +struct MemberObj { + int x; +}; + +void noexcept_test() { + { + NoThrowCallable obj; ((void)obj); // suppress unused warning + CopyThrows arg; ((void)arg); // suppress unused warning + static_assert(noexcept(std::invoke(obj)), ""); + static_assert(!noexcept(std::invoke(obj, arg)), ""); + static_assert(noexcept(std::invoke(obj, std::move(arg))), ""); + } + { + ThrowsCallable obj; ((void)obj); // suppress unused warning + static_assert(!noexcept(std::invoke(obj)), ""); + } + { + MemberObj obj{42}; ((void)obj); // suppress unused warning. + static_assert(noexcept(std::invoke(&MemberObj::x, obj)), ""); + } +} + int main() { bullet_one_two_tests(); bullet_three_four_tests(); bullet_five_tests(); + noexcept_test(); } diff --git a/test/std/utilities/function.objects/func.memfn/member_function.pass.cpp b/test/std/utilities/function.objects/func.memfn/member_function.pass.cpp index f371223ee84c7..465e001c3debc 100644 --- a/test/std/utilities/function.objects/func.memfn/member_function.pass.cpp +++ b/test/std/utilities/function.objects/func.memfn/member_function.pass.cpp @@ -15,6 +15,8 @@ #include <functional> #include <cassert> +#include "test_macros.h" + struct A { char test0() {return 'a';} @@ -69,7 +71,7 @@ int main() test0(std::mem_fn(&A::test0)); test1(std::mem_fn(&A::test1)); test2(std::mem_fn(&A::test2)); -#if __has_feature(cxx_noexcept) +#if TEST_STD_VER >= 11 static_assert((noexcept(std::mem_fn(&A::test0))), ""); // LWG#2489 #endif } diff --git a/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp b/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp new file mode 100644 index 0000000000000..c12fa7920974c --- /dev/null +++ b/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp @@ -0,0 +1,589 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template <class F> unspecified not_fn(F&& f); + +#include <functional> +#include <type_traits> +#include <string> +#include <cassert> + +#include "test_macros.h" +#include "type_id.h" + + +/////////////////////////////////////////////////////////////////////////////// +// CALLABLE TEST TYPES +/////////////////////////////////////////////////////////////////////////////// + +bool returns_true() { return true; } + +template <class Ret = bool> +struct MoveOnlyCallable { + MoveOnlyCallable(MoveOnlyCallable const&) = delete; + MoveOnlyCallable(MoveOnlyCallable&& other) + : value(other.value) + { other.value = !other.value; } + + template <class ...Args> + Ret operator()(Args&&...) { return Ret{value}; } + + explicit MoveOnlyCallable(bool x) : value(x) {} + Ret value; +}; + +template <class Ret = bool> +struct CopyCallable { + CopyCallable(CopyCallable const& other) + : value(other.value) {} + + CopyCallable(CopyCallable&& other) + : value(other.value) { other.value = !other.value; } + + template <class ...Args> + Ret operator()(Args&&...) { return Ret{value}; } + + explicit CopyCallable(bool x) : value(x) {} + Ret value; +}; + + +template <class Ret = bool> +struct ConstCallable { + ConstCallable(ConstCallable const& other) + : value(other.value) {} + + ConstCallable(ConstCallable&& other) + : value(other.value) { other.value = !other.value; } + + template <class ...Args> + Ret operator()(Args&&...) const { return Ret{value}; } + + explicit ConstCallable(bool x) : value(x) {} + Ret value; +}; + + + +template <class Ret = bool> +struct NoExceptCallable { + NoExceptCallable(NoExceptCallable const& other) + : value(other.value) {} + + template <class ...Args> + Ret operator()(Args&&...) noexcept { return Ret{value}; } + + template <class ...Args> + Ret operator()(Args&&...) const noexcept { return Ret{value}; } + + explicit NoExceptCallable(bool x) : value(x) {} + Ret value; +}; + +struct CopyAssignableWrapper { + CopyAssignableWrapper(CopyAssignableWrapper const&) = default; + CopyAssignableWrapper(CopyAssignableWrapper&&) = default; + CopyAssignableWrapper& operator=(CopyAssignableWrapper const&) = default; + CopyAssignableWrapper& operator=(CopyAssignableWrapper &&) = default; + + template <class ...Args> + bool operator()(Args&&...) { return value; } + + explicit CopyAssignableWrapper(bool x) : value(x) {} + bool value; +}; + + +struct MoveAssignableWrapper { + MoveAssignableWrapper(MoveAssignableWrapper const&) = delete; + MoveAssignableWrapper(MoveAssignableWrapper&&) = default; + MoveAssignableWrapper& operator=(MoveAssignableWrapper const&) = delete; + MoveAssignableWrapper& operator=(MoveAssignableWrapper &&) = default; + + template <class ...Args> + bool operator()(Args&&...) { return value; } + + explicit MoveAssignableWrapper(bool x) : value(x) {} + bool value; +}; + +struct MemFunCallable { + explicit MemFunCallable(bool x) : value(x) {} + + bool return_value() const { return value; } + bool return_value_nc() { return value; } + bool value; +}; + +enum CallType : unsigned { + CT_None, + CT_NonConst = 1, + CT_Const = 2, + CT_LValue = 4, + CT_RValue = 8 +}; + +inline constexpr CallType operator|(CallType LHS, CallType RHS) { + return static_cast<CallType>(static_cast<unsigned>(LHS) | static_cast<unsigned>(RHS)); +} + +struct ForwardingCallObject { + + template <class ...Args> + bool operator()(Args&&... args) & { + set_call<Args&&...>(CT_NonConst | CT_LValue); + return true; + } + + template <class ...Args> + bool operator()(Args&&... args) const & { + set_call<Args&&...>(CT_Const | CT_LValue); + return true; + } + + // Don't allow the call operator to be invoked as an rvalue. + template <class ...Args> + bool operator()(Args&&... args) && { + set_call<Args&&...>(CT_NonConst | CT_RValue); + return true; + } + + template <class ...Args> + bool operator()(Args&&... args) const && { + set_call<Args&&...>(CT_Const | CT_RValue); + return true; + } + + template <class ...Args> + static void set_call(CallType type) { + assert(last_call_type == CT_None); + assert(last_call_args == nullptr); + last_call_type = type; + last_call_args = &makeArgumentID<Args...>(); + } + + template <class ...Args> + static bool check_call(CallType type) { + bool result = + last_call_type == type + && last_call_args + && *last_call_args == makeArgumentID<Args...>(); + last_call_type = CT_None; + last_call_args = nullptr; + return result; + } + + static CallType last_call_type; + static TypeID const* last_call_args; +}; + +CallType ForwardingCallObject::last_call_type = CT_None; +TypeID const* ForwardingCallObject::last_call_args = nullptr; + + + +/////////////////////////////////////////////////////////////////////////////// +// BOOL TEST TYPES +/////////////////////////////////////////////////////////////////////////////// + +struct EvilBool { + static int bang_called; + + EvilBool(EvilBool const&) = default; + EvilBool(EvilBool&&) = default; + + friend EvilBool operator!(EvilBool const& other) { + ++bang_called; + return EvilBool{!other.value}; + } + +private: + friend struct MoveOnlyCallable<EvilBool>; + friend struct CopyCallable<EvilBool>; + friend struct NoExceptCallable<EvilBool>; + + explicit EvilBool(bool x) : value(x) {} + EvilBool& operator=(EvilBool const& other) = default; + +public: + bool value; +}; + +int EvilBool::bang_called = 0; + +struct ExplicitBool { + ExplicitBool(ExplicitBool const&) = default; + ExplicitBool(ExplicitBool&&) = default; + + explicit operator bool() const { return value; } + +private: + friend struct MoveOnlyCallable<ExplicitBool>; + friend struct CopyCallable<ExplicitBool>; + + explicit ExplicitBool(bool x) : value(x) {} + ExplicitBool& operator=(bool x) { + value = x; + return *this; + } + + bool value; +}; + + +struct NoExceptEvilBool { + NoExceptEvilBool(NoExceptEvilBool const&) = default; + NoExceptEvilBool(NoExceptEvilBool&&) = default; + NoExceptEvilBool& operator=(NoExceptEvilBool const& other) = default; + + explicit NoExceptEvilBool(bool x) : value(x) {} + + friend NoExceptEvilBool operator!(NoExceptEvilBool const& other) noexcept { + return NoExceptEvilBool{!other.value}; + } + + bool value; +}; + + + +void constructor_tests() +{ + { + using T = MoveOnlyCallable<bool>; + T value(true); + using RetT = decltype(std::not_fn(std::move(value))); + static_assert(std::is_move_constructible<RetT>::value, ""); + static_assert(!std::is_copy_constructible<RetT>::value, ""); + static_assert(!std::is_move_assignable<RetT>::value, ""); + static_assert(!std::is_copy_assignable<RetT>::value, ""); + auto ret = std::not_fn(std::move(value)); + // test it was moved from + assert(value.value == false); + // test that ret() negates the original value 'true' + assert(ret() == false); + assert(ret(0, 0.0, "blah") == false); + // Move ret and test that it was moved from and that ret2 got the + // original value. + auto ret2 = std::move(ret); + assert(ret() == true); + assert(ret2() == false); + assert(ret2(42) == false); + } + { + using T = CopyCallable<bool>; + T value(false); + using RetT = decltype(std::not_fn(value)); + static_assert(std::is_move_constructible<RetT>::value, ""); + static_assert(std::is_copy_constructible<RetT>::value, ""); + static_assert(!std::is_move_assignable<RetT>::value, ""); + static_assert(!std::is_copy_assignable<RetT>::value, ""); + auto ret = std::not_fn(value); + // test that value is unchanged (copied not moved) + assert(value.value == false); + // test 'ret' has the original value + assert(ret() == true); + assert(ret(42, 100) == true); + // move from 'ret' and check that 'ret2' has the original value. + auto ret2 = std::move(ret); + assert(ret() == false); + assert(ret2() == true); + assert(ret2("abc") == true); + } + { + using T = CopyAssignableWrapper; + T value(true); + T value2(false); + using RetT = decltype(std::not_fn(value)); + static_assert(std::is_move_constructible<RetT>::value, ""); + static_assert(std::is_copy_constructible<RetT>::value, ""); + static_assert(std::is_move_assignable<RetT>::value, ""); + static_assert(std::is_copy_assignable<RetT>::value, ""); + auto ret = std::not_fn(value); + assert(ret() == false); + auto ret2 = std::not_fn(value2); + assert(ret2() == true); + ret = ret2; + assert(ret() == true); + assert(ret2() == true); + } + { + using T = MoveAssignableWrapper; + T value(true); + T value2(false); + using RetT = decltype(std::not_fn(std::move(value))); + static_assert(std::is_move_constructible<RetT>::value, ""); + static_assert(!std::is_copy_constructible<RetT>::value, ""); + static_assert(std::is_move_assignable<RetT>::value, ""); + static_assert(!std::is_copy_assignable<RetT>::value, ""); + auto ret = std::not_fn(std::move(value)); + assert(ret() == false); + auto ret2 = std::not_fn(std::move(value2)); + assert(ret2() == true); + ret = std::move(ret2); + assert(ret() == true); + } +} + +void return_type_tests() +{ + using std::is_same; + { + using T = CopyCallable<bool>; + auto ret = std::not_fn(T{false}); + static_assert(is_same<decltype(ret()), bool>::value, ""); + static_assert(is_same<decltype(ret("abc")), bool>::value, ""); + assert(ret() == true); + } + { + using T = CopyCallable<ExplicitBool>; + auto ret = std::not_fn(T{true}); + static_assert(is_same<decltype(ret()), bool>::value, ""); + static_assert(is_same<decltype(ret(std::string("abc"))), bool>::value, ""); + assert(ret() == false); + } + { + using T = CopyCallable<EvilBool>; + auto ret = std::not_fn(T{false}); + static_assert(is_same<decltype(ret()), EvilBool>::value, ""); + EvilBool::bang_called = 0; + auto value_ret = ret(); + assert(EvilBool::bang_called == 1); + assert(value_ret.value == true); + ret(); + assert(EvilBool::bang_called == 2); + } +} + +// Other tests only test using objects with call operators. Test various +// other callable types here. +void other_callable_types_test() +{ + { // test with function pointer + auto ret = std::not_fn(returns_true); + assert(ret() == false); + } + { // test with lambda + auto returns_value = [](bool value) { return value; }; + auto ret = std::not_fn(returns_value); + assert(ret(true) == false); + assert(ret(false) == true); + } + { // test with pointer to member function + MemFunCallable mt(true); + const MemFunCallable mf(false); + auto ret = std::not_fn(&MemFunCallable::return_value); + assert(ret(mt) == false); + assert(ret(mf) == true); + assert(ret(&mt) == false); + assert(ret(&mf) == true); + } + { // test with pointer to member function + MemFunCallable mt(true); + MemFunCallable mf(false); + auto ret = std::not_fn(&MemFunCallable::return_value_nc); + assert(ret(mt) == false); + assert(ret(mf) == true); + assert(ret(&mt) == false); + assert(ret(&mf) == true); + } + { // test with pointer to member data + MemFunCallable mt(true); + const MemFunCallable mf(false); + auto ret = std::not_fn(&MemFunCallable::value); + assert(ret(mt) == false); + assert(ret(mf) == true); + assert(ret(&mt) == false); + assert(ret(&mf) == true); + } +} + +void throws_in_constructor_test() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + struct ThrowsOnCopy { + ThrowsOnCopy(ThrowsOnCopy const&) { + throw 42; + } + ThrowsOnCopy() = default; + bool operator()() const { assert(false); } + }; + { + ThrowsOnCopy cp; + try { + std::not_fn(cp); + assert(false); + } catch (int const& value) { + assert(value == 42); + } + } +#endif +} + +void call_operator_sfinae_test() { + { // wrong number of arguments + using T = decltype(std::not_fn(returns_true)); + static_assert(std::is_callable<T()>::value, ""); // callable only with no args + static_assert(!std::is_callable<T(bool)>::value, ""); + } + { // violates const correctness (member function pointer) + using T = decltype(std::not_fn(&MemFunCallable::return_value_nc)); + static_assert(std::is_callable<T(MemFunCallable&)>::value, ""); + static_assert(!std::is_callable<T(const MemFunCallable&)>::value, ""); + } + { // violates const correctness (call object) + using Obj = CopyCallable<bool>; + using NCT = decltype(std::not_fn(Obj{true})); + using CT = const NCT; + static_assert(std::is_callable<NCT()>::value, ""); + static_assert(!std::is_callable<CT()>::value, ""); + } + { // returns bad type with no operator! + auto fn = [](auto x) { return x; }; + using T = decltype(std::not_fn(fn)); + static_assert(std::is_callable<T(bool)>::value, ""); + static_assert(!std::is_callable<T(std::string)>::value, ""); + } +} + +void call_operator_forwarding_test() +{ + using Fn = ForwardingCallObject; + auto obj = std::not_fn(Fn{}); + const auto& c_obj = obj; + { // test zero args + obj(); + assert(Fn::check_call<>(CT_NonConst | CT_LValue)); + std::move(obj)(); + assert(Fn::check_call<>(CT_NonConst | CT_RValue)); + c_obj(); + assert(Fn::check_call<>(CT_Const | CT_LValue)); + std::move(c_obj)(); + assert(Fn::check_call<>(CT_Const | CT_RValue)); + } + { // test value categories + int x = 42; + const int cx = 42; + obj(x); + assert(Fn::check_call<int&>(CT_NonConst | CT_LValue)); + obj(cx); + assert(Fn::check_call<const int&>(CT_NonConst | CT_LValue)); + obj(std::move(x)); + assert(Fn::check_call<int&&>(CT_NonConst | CT_LValue)); + obj(std::move(cx)); + assert(Fn::check_call<const int&&>(CT_NonConst | CT_LValue)); + obj(42); + assert(Fn::check_call<int&&>(CT_NonConst | CT_LValue)); + } + { // test value categories - rvalue + int x = 42; + const int cx = 42; + std::move(obj)(x); + assert(Fn::check_call<int&>(CT_NonConst | CT_RValue)); + std::move(obj)(cx); + assert(Fn::check_call<const int&>(CT_NonConst | CT_RValue)); + std::move(obj)(std::move(x)); + assert(Fn::check_call<int&&>(CT_NonConst | CT_RValue)); + std::move(obj)(std::move(cx)); + assert(Fn::check_call<const int&&>(CT_NonConst | CT_RValue)); + std::move(obj)(42); + assert(Fn::check_call<int&&>(CT_NonConst | CT_RValue)); + } + { // test value categories - const call + int x = 42; + const int cx = 42; + c_obj(x); + assert(Fn::check_call<int&>(CT_Const | CT_LValue)); + c_obj(cx); + assert(Fn::check_call<const int&>(CT_Const | CT_LValue)); + c_obj(std::move(x)); + assert(Fn::check_call<int&&>(CT_Const | CT_LValue)); + c_obj(std::move(cx)); + assert(Fn::check_call<const int&&>(CT_Const | CT_LValue)); + c_obj(42); + assert(Fn::check_call<int&&>(CT_Const | CT_LValue)); + } + { // test value categories - const call rvalue + int x = 42; + const int cx = 42; + std::move(c_obj)(x); + assert(Fn::check_call<int&>(CT_Const | CT_RValue)); + std::move(c_obj)(cx); + assert(Fn::check_call<const int&>(CT_Const | CT_RValue)); + std::move(c_obj)(std::move(x)); + assert(Fn::check_call<int&&>(CT_Const | CT_RValue)); + std::move(c_obj)(std::move(cx)); + assert(Fn::check_call<const int&&>(CT_Const | CT_RValue)); + std::move(c_obj)(42); + assert(Fn::check_call<int&&>(CT_Const | CT_RValue)); + } + { // test multi arg + int x = 42; + const double y = 3.14; + std::string s = "abc"; + obj(42, std::move(y), s, std::string{"foo"}); + Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_NonConst | CT_LValue); + std::move(obj)(42, std::move(y), s, std::string{"foo"}); + Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_NonConst | CT_RValue); + c_obj(42, std::move(y), s, std::string{"foo"}); + Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_Const | CT_LValue); + std::move(c_obj)(42, std::move(y), s, std::string{"foo"}); + Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_Const | CT_RValue); + } +} + +void call_operator_noexcept_test() +{ + { + using T = ConstCallable<bool>; + T value(true); + auto ret = std::not_fn(value); + static_assert(!noexcept(ret()), "call should not be noexcept"); + auto const& cret = ret; + static_assert(!noexcept(cret()), "call should not be noexcept"); + } + { + using T = NoExceptCallable<bool>; + T value(true); + auto ret = std::not_fn(value); + static_assert(noexcept(!_VSTD::__invoke(value)), ""); + static_assert(noexcept(ret()), "call should be noexcept"); + auto const& cret = ret; + static_assert(noexcept(cret()), "call should be noexcept"); + } + { + using T = NoExceptCallable<NoExceptEvilBool>; + T value(true); + auto ret = std::not_fn(value); + static_assert(noexcept(ret()), "call should not be noexcept"); + auto const& cret = ret; + static_assert(noexcept(cret()), "call should not be noexcept"); + } + { + using T = NoExceptCallable<EvilBool>; + T value(true); + auto ret = std::not_fn(value); + static_assert(!noexcept(ret()), "call should not be noexcept"); + auto const& cret = ret; + static_assert(!noexcept(cret()), "call should not be noexcept"); + } +} + +int main() +{ + constructor_tests(); + return_type_tests(); + other_callable_types_test(); + throws_in_constructor_test(); + call_operator_sfinae_test(); // somewhat of an extension + call_operator_forwarding_test(); + call_operator_noexcept_test(); +} diff --git a/test/std/utilities/function.objects/func.require/INVOKE_tested_elsewhere.pass.cpp b/test/std/utilities/function.objects/func.require/INVOKE_tested_elsewhere.pass.cpp new file mode 100644 index 0000000000000..d61c3773e5396 --- /dev/null +++ b/test/std/utilities/function.objects/func.require/INVOKE_tested_elsewhere.pass.cpp @@ -0,0 +1,16 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// INVOKE (f, t1, t2, ..., tN) + +// The tests for INVOKE (f, t1, t2, ..., tN) live in the "test/libcxx" tree +// since they require calling the implementation specific "__invoke" and +// "__invoke_constexpr" functions. + +int main() {} 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 aa6b743b5236b..403d646f4216e 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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <functional> // class function<R(ArgTypes...)> @@ -14,8 +16,10 @@ // template<class A> function(allocator_arg_t, const A&, function&&); #include <functional> +#include <memory> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" #include "count_new.hpp" @@ -46,23 +50,57 @@ public: int A::count = 0; +int g(int) { return 0; } + int main() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 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, bare_allocator<A>(), std::move(f)); - assert(A::count == 1); - assert(globalMemCounter.checkOutstandingNewEq(1)); - assert(f2.target<A>()); - assert(f2.target<int(*)(int)>() == 0); - assert(f.target<A>() == 0); - assert(f.target<int(*)(int)>() == 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, bare_allocator<A>(), std::move(f)); + assert(A::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(f2.target<A>()); + assert(f2.target<int(*)(int)>() == 0); + assert(f.target<A>() == 0); + assert(f.target<int(*)(int)>() == 0); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + { + // Test that moving a function constructed from a reference wrapper + // is done without allocating. + DisableAllocationGuard g; + using Ref = std::reference_wrapper<A>; + A a; + Ref aref(a); + std::function<int(int)> f(aref); + assert(A::count == 1); + assert(f.target<A>() == nullptr); + assert(f.target<Ref>()); + std::function<int(int)> f2(std::allocator_arg, std::allocator<void>{}, + std::move(f)); + assert(A::count == 1); + assert(f2.target<A>() == nullptr); + assert(f2.target<Ref>()); + assert(f.target<Ref>()); // f is unchanged because the target is small + } + { + // Test that moving a function constructed from a function pointer + // is done without allocating + DisableAllocationGuard guard; + using Ptr = int(*)(int); + Ptr p = g; + std::function<int(int)> f(p); + assert(f.target<A>() == nullptr); + assert(f.target<Ptr>()); + std::function<int(int)> f2(std::allocator_arg, std::allocator<void>(), + std::move(f)); + assert(f2.target<A>() == nullptr); + assert(f2.target<Ptr>()); + assert(f.target<Ptr>()); // f is unchanged because the target is small } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_move.pass.cpp index f603da9dd1319..387b371a93311 100644 --- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_move.pass.cpp @@ -14,9 +14,11 @@ // function(const function& f); #include <functional> +#include <memory> #include <cstdlib> #include <cassert> +#include "test_macros.h" #include "count_new.hpp" class A @@ -98,21 +100,53 @@ int main() assert(g.target<A>() == 0); assert(!g); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if TEST_STD_VER >= 11 + assert(globalMemCounter.checkOutstandingNewEq(0)); + { // Test rvalue references + 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::move(f); + assert(A::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(f2.target<A>()); + assert(f2.target<int(*)(int)>() == 0); + assert(f.target<A>() == 0); + assert(f.target<int(*)(int)>() == 0); + } 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::move(f); - assert(A::count == 1); - assert(globalMemCounter.checkOutstandingNewEq(1)); - assert(f2.target<A>()); - assert(f2.target<int(*)(int)>() == 0); - assert(f.target<A>() == 0); - assert(f.target<int(*)(int)>() == 0); + // Test that moving a function constructed from a reference wrapper + // is done without allocating. + DisableAllocationGuard g; + using Ref = std::reference_wrapper<A>; + A a; + Ref aref(a); + std::function<int(int)> f(aref); + assert(A::count == 1); + assert(f.target<A>() == nullptr); + assert(f.target<Ref>()); + std::function<int(int)> f2(std::move(f)); + assert(A::count == 1); + assert(f2.target<A>() == nullptr); + assert(f2.target<Ref>()); + assert(f.target<Ref>()); // f is unchanged because the target is small + } + { + // Test that moving a function constructed from a function pointer + // is done without allocating + DisableAllocationGuard guard; + using Ptr = int(*)(int); + Ptr p = g; + std::function<int(int)> f(p); + assert(f.target<A>() == nullptr); + assert(f.target<Ptr>()); + std::function<int(int)> f2(std::move(f)); + assert(f2.target<A>() == nullptr); + assert(f2.target<Ptr>()); + assert(f.target<Ptr>()); // f is unchanged because the target is small } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // TEST_STD_VER >= 11 } diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp index e9ecfa5539ce5..cb45b30a9fd4e 100644 --- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp @@ -12,10 +12,12 @@ // class function<R(ArgTypes...)> // template<class F, class A> void assign(F&&, const A&); +// This call was removed post-C++14 #include <functional> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" class A @@ -49,6 +51,7 @@ int A::count = 0; int main() { +#if TEST_STD_VER <= 14 { std::function<int(int)> f; f.assign(A(), test_allocator<A>()); @@ -57,4 +60,5 @@ int main() assert(f.target<int(*)(int)>() == 0); } assert(A::count == 0); +#endif } diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/types.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/types.pass.cpp index eb4eac65cd2cb..e48b8f986916e 100644 --- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/types.pass.cpp +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/types.pass.cpp @@ -14,7 +14,7 @@ // public: // typedef R result_type; // typedef T1 argument_type; // iff sizeof...(ArgTypes) == 1 and -// // the type in ArgTypes is T1 +// // the type in ArgTypes is T1 // typedef T1 first_argument_type; // iff sizeof...(ArgTypes) == 2 and // // ArgTypes contains T1 and T2 // typedef T2 second_argument_type; // iff sizeof...(ArgTypes) == 2 and diff --git a/test/std/utilities/function.objects/logical.operations/transparent.pass.cpp b/test/std/utilities/function.objects/logical.operations/transparent.pass.cpp index 6e3b7a2eee246..00e513ec546f9 100644 --- a/test/std/utilities/function.objects/logical.operations/transparent.pass.cpp +++ b/test/std/utilities/function.objects/logical.operations/transparent.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <functional> #include <string> @@ -22,9 +23,8 @@ public: }; -int main () { -#if _LIBCPP_STD_VER > 11 - +int main () +{ static_assert ( !is_transparent<std::logical_and<int>>::value, "" ); static_assert ( !is_transparent<std::logical_and<std::string>>::value, "" ); static_assert ( is_transparent<std::logical_and<void>>::value, "" ); @@ -39,8 +39,6 @@ int main () { static_assert ( !is_transparent<std::logical_not<std::string>>::value, "" ); static_assert ( is_transparent<std::logical_not<void>>::value, "" ); static_assert ( is_transparent<std::logical_not<>>::value, "" ); - -#endif return 0; - } +} diff --git a/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp b/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp index 61e0bfa162d89..3c00bd20ac648 100644 --- a/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp +++ b/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp @@ -14,6 +14,9 @@ // Test that reference wrapper meets the requirements of TriviallyCopyable, // CopyConstructible and CopyAssignable. +// Test fails due to use of is_trivially_* trait. +// XFAIL: gcc-4.9 + #include <functional> #include <type_traits> #include <string> @@ -51,8 +54,8 @@ int main() { test<int>(); test<double>(); - test<std::string>(); + test<std::string>(); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - test<MoveOnly>(); + test<MoveOnly>(); #endif } diff --git a/test/std/utilities/function.objects/unord.hash/enum.pass.cpp b/test/std/utilities/function.objects/unord.hash/enum.pass.cpp index bd92a4ac4d2e1..8aa2c1df89358 100644 --- a/test/std/utilities/function.objects/unord.hash/enum.pass.cpp +++ b/test/std/utilities/function.objects/unord.hash/enum.pass.cpp @@ -12,7 +12,9 @@ // make sure that we can hash enumeration values // Not very portable -#if __cplusplus >= 201402L +#include "test_macros.h" + +#if TEST_STD_VER >= 14 #include <functional> #include <cassert> @@ -35,7 +37,7 @@ test() static_assert((std::is_same<typename H::argument_type, T>::value), "" ); static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" ); typedef typename std::underlying_type<T>::type under_type; - + H h1; std::hash<under_type> h2; for (int i = 0; i <= 5; ++i) diff --git a/test/std/utilities/function.objects/unord.hash/floating.pass.cpp b/test/std/utilities/function.objects/unord.hash/floating.pass.cpp index f1f198f235996..643e2d8c5d860 100644 --- a/test/std/utilities/function.objects/unord.hash/floating.pass.cpp +++ b/test/std/utilities/function.objects/unord.hash/floating.pass.cpp @@ -35,7 +35,7 @@ test() std::size_t t0 = h(0.); std::size_t tn0 = h(-0.); - std::size_t tp1 = h(0.1); + std::size_t tp1 = h(static_cast<T>(0.1)); std::size_t t1 = h(1); std::size_t tn1 = h(-1); std::size_t pinf = h(INFINITY); diff --git a/test/std/utilities/function.objects/unord.hash/integral.pass.cpp b/test/std/utilities/function.objects/unord.hash/integral.pass.cpp index c20f31ff2c996..8954f4f3664b7 100644 --- a/test/std/utilities/function.objects/unord.hash/integral.pass.cpp +++ b/test/std/utilities/function.objects/unord.hash/integral.pass.cpp @@ -16,14 +16,14 @@ // size_t operator()(T val) const; // }; -// Not very portable - #include <functional> #include <cassert> #include <type_traits> #include <cstddef> #include <limits> +#include "test_macros.h" + template <class T> void test() @@ -37,7 +37,11 @@ test() { T t(i); if (sizeof(T) <= sizeof(std::size_t)) - assert(h(t) == t); + { + const std::size_t result = h(t); + LIBCPP_ASSERT(result == t); + ((void)result); // Prevent unused warning + } } } @@ -67,7 +71,7 @@ int main() test<int16_t>(); test<int32_t>(); test<int64_t>(); - + test<int_fast8_t>(); test<int_fast16_t>(); test<int_fast32_t>(); @@ -80,12 +84,12 @@ int main() test<intmax_t>(); test<intptr_t>(); - + test<uint8_t>(); test<uint16_t>(); test<uint32_t>(); test<uint64_t>(); - + test<uint_fast8_t>(); test<uint_fast16_t>(); test<uint_fast32_t>(); @@ -98,4 +102,9 @@ int main() test<uintmax_t>(); test<uintptr_t>(); + +#ifndef _LIBCPP_HAS_NO_INT128 + test<__int128_t>(); + test<__uint128_t>(); +#endif } diff --git a/test/std/utilities/intseq/intseq.general/integer_seq.pass.cpp b/test/std/utilities/intseq/intseq.general/integer_seq.pass.cpp index 8ca5a96a4fac7..653fbc43d3017 100644 --- a/test/std/utilities/intseq/intseq.general/integer_seq.pass.cpp +++ b/test/std/utilities/intseq/intseq.general/integer_seq.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <utility> // class make_integer_sequence @@ -16,19 +17,13 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - template <typename AtContainer, typename T, T... I> -auto extract ( const AtContainer &t, const std::integer_sequence<T, I...> idx ) +auto extract ( const AtContainer &t, const std::integer_sequence<T, I...> ) -> decltype ( std::make_tuple ( std::get<I>(t)... )) { return std::make_tuple ( std::get<I>(t)... ); } -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 - // Make a couple of sequences using int3 = std::make_integer_sequence<int, 3>; // generates int: 0,1,2 using size7 = std::make_integer_sequence<size_t, 7>; // generates size_t: 0,1,2,3,4,5,6 @@ -36,20 +31,20 @@ int main() using size2 = std::index_sequence_for<int, size_t>; // generates size_t: 0,1 using intmix = std::integer_sequence<int, 9, 8, 7, 2>; // generates int: 9,8,7,2 using sizemix = std::index_sequence<1, 1, 2, 3, 5>; // generates size_t: 1,1,2,3,5 - + // Make sure they're what we expect static_assert ( std::is_same<int3::value_type, int>::value, "int3 type wrong" ); static_assert ( int3::size () == 3, "int3 size wrong" ); - + static_assert ( std::is_same<size7::value_type, size_t>::value, "size7 type wrong" ); static_assert ( size7::size () == 7, "size7 size wrong" ); - + static_assert ( std::is_same<size4::value_type, size_t>::value, "size4 type wrong" ); static_assert ( size4::size () == 4, "size4 size wrong" ); - + static_assert ( std::is_same<size2::value_type, size_t>::value, "size2 type wrong" ); static_assert ( size2::size () == 2, "size2 size wrong" ); - + static_assert ( std::is_same<intmix::value_type, int>::value, "intmix type wrong" ); static_assert ( intmix::size () == 4, "intmix size wrong" ); @@ -57,7 +52,7 @@ int main() static_assert ( sizemix::size () == 5, "sizemix size wrong" ); auto tup = std::make_tuple ( 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ); - + // Use them auto t3 = extract ( tup, int3() ); static_assert ( std::tuple_size<decltype(t3)>::value == int3::size (), "t3 size wrong"); @@ -82,5 +77,4 @@ int main() auto tsizemix = extract ( tup, sizemix ()); static_assert ( std::tuple_size<decltype(tsizemix)>::value == sizemix::size (), "tsizemix size wrong"); assert ( tsizemix == std::make_tuple ( 11, 11, 12, 13, 15 )); -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp b/test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp index 4b2d1acb5e6b4..b689160babaac 100644 --- a/test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp +++ b/test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp @@ -13,7 +13,7 @@ // struct integer_sequence // { // typedef T type; -// +// // static constexpr size_t size() noexcept; // }; diff --git a/test/std/utilities/intseq/intseq.intseq/integer_seq.pass.cpp b/test/std/utilities/intseq/intseq.intseq/integer_seq.pass.cpp index 5c789f5db2741..841a234334b78 100644 --- a/test/std/utilities/intseq/intseq.intseq/integer_seq.pass.cpp +++ b/test/std/utilities/intseq/intseq.intseq/integer_seq.pass.cpp @@ -7,13 +7,14 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <utility> // template<class T, T... I> // struct integer_sequence // { // typedef T type; -// +// // static constexpr size_t size() noexcept; // }; @@ -24,26 +25,22 @@ int main() { -#if _LIBCPP_STD_VER > 11 - // Make a few of sequences using int3 = std::integer_sequence<int, 3, 2, 1>; using size1 = std::integer_sequence<std::size_t, 7>; using ushort2 = std::integer_sequence<unsigned short, 4, 6>; using bool0 = std::integer_sequence<bool>; - + // Make sure they're what we expect static_assert ( std::is_same<int3::value_type, int>::value, "int3 type wrong" ); static_assert ( int3::size() == 3, "int3 size wrong" ); - + static_assert ( std::is_same<size1::value_type, std::size_t>::value, "size1 type wrong" ); static_assert ( size1::size() == 1, "size1 size wrong" ); - + static_assert ( std::is_same<ushort2::value_type, unsigned short>::value, "ushort2 type wrong" ); static_assert ( ushort2::size() == 2, "ushort2 size wrong" ); - + static_assert ( std::is_same<bool0::value_type, bool>::value, "bool0 type wrong" ); static_assert ( bool0::size() == 0, "bool0 size wrong" ); - -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp index 352c7c8d0cafd..bbc6b470174d0 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp @@ -21,6 +21,8 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" + template <class T> struct A { @@ -61,7 +63,7 @@ int main() const B<int> b = {}; assert(std::allocator_traits<B<int> >::max_size(b) == 100); } -#if __cplusplus >= 201103 +#if TEST_STD_VER >= 11 { std::allocator<int> a; static_assert(noexcept(std::allocator_traits<std::allocator<int>>::max_size(a)) == true, ""); diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_pointer.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_pointer.pass.cpp index 20348d20c10cd..10fbfe141ae55 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_pointer.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_pointer.pass.cpp @@ -20,6 +20,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct Ptr {}; @@ -47,9 +49,19 @@ struct C typedef CPtr<const T> const_pointer; }; +template <class T> +struct D { + typedef T value_type; +private: + typedef void const_pointer; +}; + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::const_pointer, Ptr<const char> >::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::const_pointer, const char*>::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::const_pointer, CPtr<const char> >::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<D<char> >::const_pointer, const char*>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_void_pointer.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_void_pointer.pass.cpp index 4b4045a51bae0..8365d22613ee0 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_void_pointer.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_void_pointer.pass.cpp @@ -21,6 +21,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct Ptr {}; @@ -47,9 +49,21 @@ struct C typedef CPtr<const void> const_void_pointer; }; + +template <class T> +struct D +{ + typedef T value_type; +private: + typedef int const_void_pointer; +}; + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::const_void_pointer, Ptr<const void> >::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::const_void_pointer, const void*>::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::const_void_pointer, CPtr<const void> >::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<D<char> >::const_void_pointer, const void*>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/difference_type.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/difference_type.pass.cpp index 085c911b07035..c728909477b52 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/difference_type.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/difference_type.pass.cpp @@ -20,6 +20,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct A { @@ -43,13 +45,24 @@ struct C struct const_void_pointer {}; }; + +template <class T> +struct D +{ + typedef T value_type; +private: + typedef void difference_type; +}; + namespace std { template <> struct pointer_traits<C<char>::pointer> { - typedef signed char difference_type; + typedef C<char>::pointer pointer; + typedef char element_type; + typedef signed char difference_type; }; } @@ -59,4 +72,7 @@ int main() static_assert((std::is_same<std::allocator_traits<A<char> >::difference_type, short>::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::difference_type, std::ptrdiff_t>::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::difference_type, signed char>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<D<char> >::difference_type, std::ptrdiff_t>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/pointer.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/pointer.pass.cpp index 60ba094993428..ff1ae2c051b65 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/pointer.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/pointer.pass.cpp @@ -19,6 +19,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct Ptr {}; @@ -35,8 +37,18 @@ struct B typedef T value_type; }; +template <class T> +struct C { + typedef T value_type; +private: + typedef void pointer; +}; + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::pointer, Ptr<char> >::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::pointer, char*>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<C<char> >::pointer, char*>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_copy_assignment.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_copy_assignment.pass.cpp index 604e890efaaee..0112ab371a836 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_copy_assignment.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_copy_assignment.pass.cpp @@ -20,6 +20,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct A { @@ -33,8 +35,20 @@ struct B typedef T value_type; }; + +template <class T> +struct C +{ + typedef T value_type; +private: + typedef std::true_type propagate_on_container_copy_assignment; +}; + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::propagate_on_container_copy_assignment, std::true_type>::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::propagate_on_container_copy_assignment, std::false_type>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<C<char> >::propagate_on_container_copy_assignment, std::false_type>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_move_assignment.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_move_assignment.pass.cpp index 1d2b18686d0f1..64de15c2cd484 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_move_assignment.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_move_assignment.pass.cpp @@ -20,6 +20,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct A { @@ -33,8 +35,21 @@ struct B typedef T value_type; }; + +template <class T> +struct C +{ + typedef T value_type; +private: + typedef std::true_type propagate_on_container_move_assignment; +}; + + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::propagate_on_container_move_assignment, std::true_type>::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::propagate_on_container_move_assignment, std::false_type>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<C<char> >::propagate_on_container_move_assignment, std::false_type>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_swap.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_swap.pass.cpp index 6730d1ae261a6..a62336fa6cb05 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_swap.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_swap.pass.cpp @@ -20,6 +20,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct A { @@ -33,8 +35,19 @@ struct B typedef T value_type; }; +template <class T> +struct C +{ + typedef T value_type; +private: + typedef std::true_type propagate_on_container_swap; +}; + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::propagate_on_container_swap, std::true_type>::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::propagate_on_container_swap, std::false_type>::value), ""); + #if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<C<char> >::propagate_on_container_swap, std::false_type>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/rebind_alloc.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/rebind_alloc.pass.cpp index 50611b99da9a8..8097a66fc9d62 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/rebind_alloc.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/rebind_alloc.pass.cpp @@ -19,6 +19,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct ReboundA {}; @@ -61,19 +63,39 @@ struct E template <class U> struct rebind {typedef ReboundA<U> otter;}; }; +template <class T> +struct F { + typedef T value_type; +private: + template <class> + struct rebind { typedef void other; }; +}; + +template <class T> +struct G { + typedef T value_type; + template <class> + struct rebind { + private: + typedef void other; + }; +}; + int main() { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#if TEST_STD_VER >= 11 static_assert((std::is_same<std::allocator_traits<A<char> >::rebind_alloc<double>, ReboundA<double> >::value), ""); static_assert((std::is_same<std::allocator_traits<B<int, char> >::rebind_alloc<double>, ReboundB<double, char> >::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::rebind_alloc<double>, C<double> >::value), ""); static_assert((std::is_same<std::allocator_traits<D<int, char> >::rebind_alloc<double>, D<double, char> >::value), ""); static_assert((std::is_same<std::allocator_traits<E<char> >::rebind_alloc<double>, E<double> >::value), ""); -#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES + static_assert((std::is_same<std::allocator_traits<F<char> >::rebind_alloc<double>, F<double> >::value), ""); + static_assert((std::is_same<std::allocator_traits<G<char> >::rebind_alloc<double>, G<double> >::value), ""); +#else static_assert((std::is_same<std::allocator_traits<A<char> >::rebind_alloc<double>::other, ReboundA<double> >::value), ""); static_assert((std::is_same<std::allocator_traits<B<int, char> >::rebind_alloc<double>::other, ReboundB<double, char> >::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::rebind_alloc<double>::other, C<double> >::value), ""); static_assert((std::is_same<std::allocator_traits<D<int, char> >::rebind_alloc<double>::other, D<double, char> >::value), ""); static_assert((std::is_same<std::allocator_traits<E<char> >::rebind_alloc<double>::other, E<double> >::value), ""); -#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/size_type.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/size_type.pass.cpp index e9c175fe86a54..00ed50727c983 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/size_type.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/size_type.pass.cpp @@ -19,6 +19,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct A { @@ -42,6 +44,14 @@ struct C struct const_void_pointer {}; }; +template <class T> +struct D { + typedef T value_type; + typedef short difference_type; +private: + typedef void size_type; +}; + namespace std { @@ -60,4 +70,7 @@ int main() std::make_unsigned<std::ptrdiff_t>::type>::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::size_type, unsigned char>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<D<char> >::size_type, unsigned short>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/void_pointer.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/void_pointer.pass.cpp index 74cd3475f6645..2c3623793db60 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/void_pointer.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/void_pointer.pass.cpp @@ -20,6 +20,7 @@ #include <memory> #include <type_traits> +#include "test_macros.h" template <class T> struct Ptr {}; @@ -47,9 +48,21 @@ struct C typedef CPtr<void> void_pointer; }; + +template <class T> +struct D +{ + typedef T value_type; +private: + typedef void void_pointer; +}; + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::void_pointer, Ptr<void> >::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::void_pointer, void*>::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::void_pointer, CPtr<void> >::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<D<char> >::void_pointer, void*>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp b/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp index 0477d9912e6ec..bd32bc34e7a0f 100644 --- a/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp +++ b/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp @@ -14,6 +14,8 @@ #include <memory> #include <vector> +#include "test_macros.h" + struct A { }; @@ -23,6 +25,19 @@ struct B typedef int allocator_type; }; +struct C { + static int allocator_type; +}; + +struct D { + static int allocator_type() { return 0; } +}; + +struct E { +private: + typedef int allocator_type; +}; + int main() { static_assert((!std::uses_allocator<int, std::allocator<int> >::value), ""); @@ -30,4 +45,9 @@ int main() static_assert((!std::uses_allocator<A, std::allocator<int> >::value), ""); static_assert((!std::uses_allocator<B, std::allocator<int> >::value), ""); static_assert(( std::uses_allocator<B, double>::value), ""); + static_assert((!std::uses_allocator<C, decltype(C::allocator_type)>::value), ""); + static_assert((!std::uses_allocator<D, decltype(D::allocator_type)>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((!std::uses_allocator<E, int>::value), ""); +#endif } diff --git a/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp b/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp new file mode 100644 index 0000000000000..dc0bdd047c61a --- /dev/null +++ b/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.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. +// +//===----------------------------------------------------------------------===// + +// XFAIL: libcpp-no-exceptions +// <memory> + +// allocator: +// pointer allocate(size_type n, allocator<void>::const_pointer hint=0); + +#include <memory> +#include <cassert> + +template <typename T> +void test_max(size_t count) +{ + std::allocator<T> a; + try { + a.allocate(count); + assert(false); + } catch (const std::exception &) { + } +} + +int main() +{ + { // Bug 26812 -- allocating too large + typedef double T; + std::allocator<T> a; + test_max<T> (a.max_size() + 1); // just barely too large + test_max<T> (a.max_size() * 2); // significantly too large + test_max<T> (((size_t) -1) / sizeof(T) + 1); // multiply will overflow + test_max<T> ((size_t) -1); // way too large + } + + { + typedef const double T; + std::allocator<T> a; + test_max<T> (a.max_size() + 1); // just barely too large + test_max<T> (a.max_size() * 2); // significantly too large + test_max<T> (((size_t) -1) / sizeof(T) + 1); // multiply will overflow + test_max<T> ((size_t) -1); // way too large + } +} diff --git a/test/std/utilities/memory/default.allocator/allocator_pointers.pass.cpp b/test/std/utilities/memory/default.allocator/allocator_pointers.pass.cpp index 5a8f7a28a042c..e1612ae054218 100644 --- a/test/std/utilities/memory/default.allocator/allocator_pointers.pass.cpp +++ b/test/std/utilities/memory/default.allocator/allocator_pointers.pass.cpp @@ -10,7 +10,9 @@ #include <memory> #include <cassert> -#if __cplusplus >= 201103L +#include "test_macros.h" + +#if TEST_STD_VER >= 11 // #include <memory> // // template <class Alloc> @@ -19,7 +21,7 @@ // typedef Alloc allocator_type; // typedef typename allocator_type::value_type // value_type; -// +// // typedef Alloc::pointer | value_type* pointer; // typedef Alloc::const_pointer // | pointer_traits<pointer>::rebind<const value_type> @@ -36,7 +38,10 @@ void test_pointer() { typename std::allocator_traits<Alloc>::pointer vp; typename std::allocator_traits<Alloc>::const_pointer cvp; - + + ((void)vp); // Prevent unused warning + ((void)cvp); // Prevent unused warning + static_assert(std::is_same<bool, decltype( vp == vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp != vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp > vp)>::value, ""); @@ -70,7 +75,10 @@ void test_void_pointer() { typename std::allocator_traits<Alloc>::void_pointer vp; typename std::allocator_traits<Alloc>::const_void_pointer cvp; - + + ((void)vp); // Prevent unused warning + ((void)cvp); // Prevent unused warning + static_assert(std::is_same<bool, decltype( vp == vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp != vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp > vp)>::value, ""); @@ -105,11 +113,11 @@ int main() { test_pointer<std::allocator<char>> (); test_pointer<std::allocator<int>> (); - test_pointer<std::allocator<Foo>> (); + test_pointer<std::allocator<Foo>> (); test_void_pointer<std::allocator<char>> (); test_void_pointer<std::allocator<int>> (); - test_void_pointer<std::allocator<Foo>> (); + test_void_pointer<std::allocator<Foo>> (); } #else int main() {} diff --git a/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.pass.cpp b/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.pass.cpp index 4efe61342420c..27b2d08b00610 100644 --- a/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.pass.cpp +++ b/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.pass.cpp @@ -19,6 +19,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + struct A { typedef short element_type; @@ -39,10 +41,26 @@ struct D typedef char difference_type; }; +template <class T> +struct E +{ + static int difference_type; +}; + +template <class T> +struct F { +private: + typedef int difference_type; +}; + int main() { static_assert((std::is_same<std::pointer_traits<A>::difference_type, char>::value), ""); static_assert((std::is_same<std::pointer_traits<B>::difference_type, std::ptrdiff_t>::value), ""); static_assert((std::is_same<std::pointer_traits<C<double> >::difference_type, std::ptrdiff_t>::value), ""); static_assert((std::is_same<std::pointer_traits<D<int> >::difference_type, char>::value), ""); + static_assert((std::is_same<std::pointer_traits<E<int> >::difference_type, std::ptrdiff_t>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::pointer_traits<F<int>>::difference_type, std::ptrdiff_t>::value), ""); +#endif } diff --git a/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.pass.cpp b/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.pass.cpp index 0ee1e8c93a674..48399d5355d67 100644 --- a/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.pass.cpp +++ b/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.pass.cpp @@ -19,6 +19,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + struct A { typedef char element_type; @@ -40,10 +42,27 @@ struct D { }; +template <class T, class U> +struct E +{ + static int element_type; +}; + +template <class T> +struct F { +private: + typedef int element_type; +}; + int main() { static_assert((std::is_same<std::pointer_traits<A>::element_type, char>::value), ""); static_assert((std::is_same<std::pointer_traits<B<int> >::element_type, char>::value), ""); static_assert((std::is_same<std::pointer_traits<C<int> >::element_type, int>::value), ""); static_assert((std::is_same<std::pointer_traits<D<double, int> >::element_type, double>::value), ""); + static_assert((std::is_same<std::pointer_traits<E<double, int> >::element_type, double>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::pointer_traits<F<double>>::element_type, double>::value), ""); +#endif + } diff --git a/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.pass.cpp b/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.pass.cpp index 4a1455c53ef6f..74c124901211c 100644 --- a/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.pass.cpp +++ b/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.pass.cpp @@ -19,6 +19,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct A { @@ -29,7 +31,7 @@ template <class T> struct B1 {}; template <class T> struct B { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#if TEST_STD_VER >= 11 template <class U> using rebind = B1<U>; #else template <class U> struct rebind {typedef B1<U> other;}; @@ -46,24 +48,58 @@ template <class T, class U> struct D1 {}; template <class T, class U> struct D { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#if TEST_STD_VER >= 11 template <class V> using rebind = D1<V, U>; #else template <class V> struct rebind {typedef D1<V, U> other;}; #endif }; +template <class T, class U> +struct E +{ + template <class> + void rebind() {} +}; + + +#if TEST_STD_VER >= 11 +template <class T, class U> +struct F { +private: + template <class> + using rebind = void; +}; +#endif + +#if TEST_STD_VER >= 14 +template <class T, class U> +struct G +{ + template <class> + static constexpr int rebind = 42; +}; +#endif + + int main() { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#if TEST_STD_VER >= 11 static_assert((std::is_same<std::pointer_traits<A<int*> >::rebind<double*>, A<double*> >::value), ""); static_assert((std::is_same<std::pointer_traits<B<int> >::rebind<double>, B1<double> >::value), ""); static_assert((std::is_same<std::pointer_traits<C<char, int> >::rebind<double>, C<double, int> >::value), ""); static_assert((std::is_same<std::pointer_traits<D<char, int> >::rebind<double>, D1<double, int> >::value), ""); -#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES + static_assert((std::is_same<std::pointer_traits<E<char, int> >::rebind<double>, E<double, int> >::value), ""); + static_assert((std::is_same<std::pointer_traits<F<char, int> >::rebind<double>, F<double, int> >::value), ""); + +#if TEST_STD_VER >= 14 + static_assert((std::is_same<std::pointer_traits<G<char, int> >::rebind<double>, G<double, int> >::value), ""); +#endif +#else // TEST_STD_VER < 11 static_assert((std::is_same<std::pointer_traits<A<int*> >::rebind<double*>::other, A<double*> >::value), ""); static_assert((std::is_same<std::pointer_traits<B<int> >::rebind<double>::other, B1<double> >::value), ""); static_assert((std::is_same<std::pointer_traits<C<char, int> >::rebind<double>::other, C<double, int> >::value), ""); static_assert((std::is_same<std::pointer_traits<D<char, int> >::rebind<double>::other, D1<double, int> >::value), ""); -#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES + static_assert((std::is_same<std::pointer_traits<E<char, int> >::rebind<double>::other, E<double, int> >::value), ""); +#endif } diff --git a/test/std/utilities/memory/specialized.algorithms/specialized.addressof/constexpr_addressof.pass.cpp b/test/std/utilities/memory/specialized.algorithms/specialized.addressof/constexpr_addressof.pass.cpp new file mode 100644 index 0000000000000..a371f8eda1a80 --- /dev/null +++ b/test/std/utilities/memory/specialized.algorithms/specialized.addressof/constexpr_addressof.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// XFAIL: gcc + +// <memory> + +// template <ObjectType T> constexpr T* addressof(T& r); + +#include <memory> +#include <cassert> + +struct Pointer { + constexpr Pointer(void* v) : value(v) {} + void* value; +}; + +struct A +{ + constexpr A() : n(42) {} + void operator&() const { } + int n; +}; + +constexpr int i = 0; +constexpr double d = 0.0; +constexpr A a{}; + +int main() +{ + static_assert(std::addressof(i) == &i, ""); + static_assert(std::addressof(d) == &d, ""); + constexpr const A* ap = std::addressof(a); + static_assert(&ap->n == &a.n, ""); +} 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 8bb818319a37a..1debd6d75ff04 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 @@ -36,7 +36,7 @@ struct Nasty Nasty() : i_ ( counter_++ ) {} Nasty * operator &() const { return NULL; } int i_; - static int counter_; + static int counter_; }; int Nasty::counter_ = 0; @@ -76,5 +76,5 @@ int main() 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 ae438ef7d5613..83aa19471adae 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 @@ -36,7 +36,7 @@ struct Nasty Nasty() : i_ ( counter_++ ) {} Nasty * operator &() const { return NULL; } int i_; - static int counter_; + static int counter_; }; int Nasty::counter_ = 0; 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 22aa8b98b8c96..5f90a37920641 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 @@ -35,7 +35,7 @@ struct Nasty Nasty() : i_ ( counter_++ ) {} Nasty * operator &() const { return NULL; } int i_; - static int counter_; + static int counter_; }; int Nasty::counter_ = 0; 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 95c45dd50541b..3816a25286883 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 @@ -36,7 +36,7 @@ struct Nasty Nasty() : i_ ( counter_++ ) {} Nasty * operator &() const { return NULL; } int i_; - static int counter_; + static int counter_; }; int Nasty::counter_ = 0; diff --git a/test/std/utilities/memory/storage.iterator/raw_storag_iterator.base.pass.cpp b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.base.pass.cpp index 27b620569b83f..62a3be80d8b60 100644 --- a/test/std/utilities/memory/storage.iterator/raw_storag_iterator.base.pass.cpp +++ b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.base.pass.cpp @@ -13,6 +13,8 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" + int A_constructed = 0; struct A @@ -29,7 +31,7 @@ public: int main() { -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 typedef std::aligned_storage<3*sizeof(A), std::alignment_of<A>::value>::type Storage; Storage buffer; diff --git a/test/std/utilities/memory/storage.iterator/raw_storag_iterator.pass.cpp b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp index 914802423ce77..914802423ce77 100644 --- a/test/std/utilities/memory/storage.iterator/raw_storag_iterator.pass.cpp +++ b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp index b2fb58f529f31..30b4ecb94e18f 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <memory> #include <string> #include <cassert> @@ -23,23 +24,21 @@ private: int main() { -#if _LIBCPP_STD_VER > 11 { auto p1 = std::make_unique<int[]>(5); for ( int i = 0; i < 5; ++i ) assert ( p1[i] == 0 ); } - + { auto p2 = std::make_unique<std::string[]>(5); for ( int i = 0; i < 5; ++i ) assert ( p2[i].size () == 0 ); } - + { auto p3 = std::make_unique<foo[]>(7); for ( int i = 0; i < 7; ++i ) assert ( p3[i].get () == 3 ); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp index 26eb59bbfd711..07aa659bd9b02 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp @@ -13,5 +13,5 @@ int main() { - auto up4 = std::make_unique<int[5]>(11, 22, 33, 44, 55); // deleted + auto up4 = std::make_unique<int[5]>(11, 22, 33, 44, 55); // deleted } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp index 7326ed226557c..ace2e4fc71370 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp @@ -7,20 +7,20 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <memory> #include <string> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 { std::unique_ptr<int> p1 = std::make_unique<int>(1); assert ( *p1 == 1 ); p1 = std::make_unique<int> (); assert ( *p1 == 0 ); } - + { std::unique_ptr<std::string> p2 = std::make_unique<std::string> ( "Meow!" ); assert ( *p2 == "Meow!" ); @@ -29,5 +29,4 @@ int main() p2 = std::make_unique<std::string> ( 6, 'z' ); assert ( *p2 == "zzzzzz" ); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp new file mode 100644 index 0000000000000..a611b1a12f050 --- /dev/null +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// default_delete[] + +// template <class U> +// default_delete(const default_delete<U[]>&); +// +// This constructor shall not participate in overload resolution unless +// U(*)[] is convertible to T(*)[]. + +#include <memory> +#include <cassert> + +int main() +{ + std::default_delete<int[]> d1; + std::default_delete<const int[]> d2 = d1; +} diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter01.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter01.pass.cpp index 2d62bccdce501..2b0b5f0d945d0 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter01.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter01.pass.cpp @@ -40,4 +40,10 @@ int main() assert(s.get_deleter().state() == 0); } assert(A::count == 0); + + { // LWG#2520 says that nullptr is a valid input as well as null + std::unique_ptr<A[], Deleter<A[]> > s1(NULL, Deleter<A[]>()); + std::unique_ptr<A[], Deleter<A[]> > s2(nullptr, Deleter<A[]>()); + } + assert(A::count == 0); } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter02.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter02.pass.cpp index 914076b50f428..a92fdbc1d2c41 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter02.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter02.pass.cpp @@ -55,4 +55,10 @@ int main() assert(s.get_deleter().state() == 5); } assert(A::count == 0); + { + Deleter d; + std::unique_ptr<A[], Deleter> s(nullptr, d); + assert(s.get() == nullptr); + assert(s.get_deleter().state() == 5); + } } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter03.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter03.pass.cpp index a6f535f38f088..dd27401731a6d 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter03.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter03.pass.cpp @@ -57,4 +57,9 @@ int main() assert(s.get_deleter().state() == 6); } assert(A::count == 0); + { + Deleter d; + std::unique_ptr<A[], Deleter&> s(nullptr, d); + assert(s.get() == nullptr); + } } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter04.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter04.pass.cpp index a4c917c1af76c..02f44d3575615 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter04.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter04.pass.cpp @@ -55,4 +55,9 @@ int main() assert(s.get_deleter().state() == 5); } assert(A::count == 0); + { + Deleter d; + std::unique_ptr<A[], const Deleter&> s(nullptr, d); + assert(s.get() == nullptr); + } } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/pointer_type.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/pointer_type.pass.cpp index 8721062c6d025..380f2e100eb6e 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/pointer_type.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/pointer_type.pass.cpp @@ -16,11 +16,22 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + struct Deleter { struct pointer {}; }; +struct D2 { +private: + typedef void pointer; +}; + +struct D3 { + static long pointer; +}; + int main() { { @@ -31,4 +42,14 @@ int main() typedef std::unique_ptr<int, Deleter> P; static_assert((std::is_same<P::pointer, Deleter::pointer>::value), ""); } +#if TEST_STD_VER >= 11 + { + typedef std::unique_ptr<int, D2> P; + static_assert(std::is_same<P::pointer, int*>::value, ""); + } + { + typedef std::unique_ptr<int, D3> P; + static_assert(std::is_same<P::pointer, int*>::value, ""); + } +#endif } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp index 44b746fbcfd86..c525137d48417 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp @@ -16,6 +16,7 @@ #include <memory> #include <cassert> +#include "test_macros.h" #include "../deleter.h" struct A @@ -34,6 +35,16 @@ struct A int A::count = 0; +template <class T> +struct NonSwappableDeleter { + explicit NonSwappableDeleter(int) {} + NonSwappableDeleter& operator=(NonSwappableDeleter const&) { return *this; } + void operator()(T*) const {} +private: + NonSwappableDeleter(NonSwappableDeleter const&); + +}; + int main() { { @@ -74,4 +85,18 @@ int main() assert(A::count == 6); } assert(A::count == 0); +#if TEST_STD_VER >= 11 + { + // test that unique_ptr's specialized swap is disabled when the deleter + // is non-swappable. Instead we should pick up the generic swap(T, T) + // and perform 3 move constructions. + typedef NonSwappableDeleter<int> D; + D d(42); + int x = 42; + int y = 43; + std::unique_ptr<int, D&> p(&x, d); + std::unique_ptr<int, D&> p2(&y, d); + std::swap(p, p2); + } +#endif } 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 77af13fa90d18..b9f8ee0746c31 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 @@ -18,11 +18,16 @@ // public: // shared_ptr<T> shared_from_this(); // shared_ptr<T const> shared_from_this() const; +// weak_ptr<T> weak_from_this() noexcept; // C++17 +// weak_ptr<T const> weak_from_this() const noexecpt; // C++17 // }; #include <memory> #include <cassert> +#include "test_macros.h" +#include "count_new.hpp" + struct T : public std::enable_shared_from_this<T> { @@ -32,12 +37,31 @@ struct Y : T {}; struct Z : Y {}; +void nullDeleter(void*) {} + +struct Foo : virtual public std::enable_shared_from_this<Foo> +{ + virtual ~Foo() {} +}; + +struct Bar : public Foo { + Bar(int) {} +}; + + 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>()); } + { // https://llvm.org/bugs/show_bug.cgi?id=27115 + int x = 42; + std::shared_ptr<Bar> t1(new Bar(42)); + assert(t1->shared_from_this() == t1); + std::shared_ptr<Bar> t2(std::make_shared<Bar>(x)); + assert(t2->shared_from_this() == t2); + } { std::shared_ptr<Y> p(new Z); std::shared_ptr<T> q = p->shared_from_this(); @@ -50,4 +74,89 @@ int main() assert(p == q); assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership } + // Test LWG issue 2529. Only reset '__weak_ptr_' when it's already expired. + // http://cplusplus.github.io/LWG/lwg-active.html#2529. + // Test two different ways: + // * Using 'weak_from_this().expired()' in C++17. + // * Using 'shared_from_this()' in all dialects. + { + assert(globalMemCounter.checkOutstandingNewEq(0)); + T* ptr = new T; + std::shared_ptr<T> s(ptr); + { + // Don't re-initialize the "enabled_shared_from_this" base + // because it already references a non-expired shared_ptr. + std::shared_ptr<T> s2(ptr, &nullDeleter); + } +#if TEST_STD_VER > 14 + // The enabled_shared_from_this base should still be referencing + // the original shared_ptr. + assert(!ptr->weak_from_this().expired()); +#endif +#ifndef TEST_HAS_NO_EXCEPTIONS + { + try { + std::shared_ptr<T> new_s = ptr->shared_from_this(); + assert(new_s == s); + } catch (std::bad_weak_ptr const&) { + assert(false); + } catch (...) { + assert(false); + } + } +#endif + s.reset(); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + // Test LWG issue 2529 again. This time check that an expired pointer + // is replaced. + { + assert(globalMemCounter.checkOutstandingNewEq(0)); + T* ptr = new T; + std::weak_ptr<T> weak; + { + std::shared_ptr<T> s(ptr, &nullDeleter); + assert(ptr->shared_from_this() == s); + weak = s; + assert(!weak.expired()); + } + assert(weak.expired()); + weak.reset(); + +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + ptr->shared_from_this(); + assert(false); + } catch (std::bad_weak_ptr const&) { + } catch (...) { assert(false); } +#endif + { + std::shared_ptr<T> s2(ptr, &nullDeleter); + assert(ptr->shared_from_this() == s2); + } + delete ptr; + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + // Test weak_from_this_methods +#if TEST_STD_VER > 14 + { + T* ptr = new T; + const T* cptr = ptr; + + static_assert(noexcept(ptr->weak_from_this()), "Operation must be noexcept"); + static_assert(noexcept(cptr->weak_from_this()), "Operation must be noexcept"); + + std::weak_ptr<T> my_weak = ptr->weak_from_this(); + assert(my_weak.expired()); + + std::weak_ptr<T const> my_const_weak = cptr->weak_from_this(); + assert(my_const_weak.expired()); + + // Enable shared_from_this with ptr. + std::shared_ptr<T> sptr(ptr); + my_weak = ptr->weak_from_this(); + assert(!my_weak.expired()); + assert(my_weak.lock().get() == ptr); + } +#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong.pass.cpp index 2d586e9c7fdd1..3bad537e34315 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong.pass.cpp @@ -23,12 +23,15 @@ // atomic_compare_exchange_strong(shared_ptr<T>* p, shared_ptr<T>* v, // shared_ptr<T> w); +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(4)); std::shared_ptr<int> v(new int(3)); @@ -49,5 +52,4 @@ int main() assert(*v == 4); assert(*w == 2); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong_explicit.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong_explicit.pass.cpp index 34da04cc18108..5cc1234ad34ee 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong_explicit.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong_explicit.pass.cpp @@ -24,12 +24,15 @@ // shared_ptr<T> w, memory_order success, // memory_order failure); +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(4)); std::shared_ptr<int> v(new int(3)); @@ -54,5 +57,4 @@ int main() assert(*v == 4); assert(*w == 2); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak.pass.cpp index 50b96e551fd3b..a89c0dbd2207c 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak.pass.cpp @@ -23,12 +23,15 @@ // atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, // shared_ptr<T> w); +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(4)); std::shared_ptr<int> v(new int(3)); @@ -49,5 +52,4 @@ int main() assert(*v == 4); assert(*w == 2); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak_explicit.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak_explicit.pass.cpp index d304319d251de..821cea6868e48 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak_explicit.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak_explicit.pass.cpp @@ -24,12 +24,15 @@ // shared_ptr<T> w, memory_order success, // memory_order failure); +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(4)); std::shared_ptr<int> v(new int(3)); @@ -54,5 +57,4 @@ int main() assert(*v == 4); assert(*w == 2); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange.pass.cpp index 3b44c8ba9b330..66be756d54fd6 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange.pass.cpp @@ -22,12 +22,15 @@ // shared_ptr<T> // atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r) +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(4)); std::shared_ptr<int> r(new int(3)); @@ -35,5 +38,4 @@ int main() assert(*p == 3); assert(*r == 4); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange_explicit.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange_explicit.pass.cpp index 598a1b8da175c..493ba7fcc94d0 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange_explicit.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange_explicit.pass.cpp @@ -22,12 +22,15 @@ // shared_ptr<T> // atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r) +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(4)); std::shared_ptr<int> r(new int(3)); @@ -35,5 +38,4 @@ int main() assert(*p == 3); assert(*r == 4); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_is_lock_free.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_is_lock_free.pass.cpp index e3ac84a4fa507..f72a0bb24285c 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_is_lock_free.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_is_lock_free.pass.cpp @@ -17,15 +17,17 @@ // bool // atomic_is_lock_free(const shared_ptr<T>* p); +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { const std::shared_ptr<int> p(new int(3)); assert(std::atomic_is_lock_free(&p) == false); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load.pass.cpp index d4a39c878ac7a..4820d05420a2f 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load.pass.cpp @@ -22,16 +22,18 @@ // shared_ptr<T> // atomic_load(const shared_ptr<T>* p) +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(3)); std::shared_ptr<int> q = std::atomic_load(&p); assert(*q == *p); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load_explicit.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load_explicit.pass.cpp index af11dc8bc2c9c..ef8dc822102ff 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load_explicit.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load_explicit.pass.cpp @@ -22,16 +22,18 @@ // shared_ptr<T> // atomic_load_explicit(const shared_ptr<T>* p, memory_order mo) +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { const std::shared_ptr<int> p(new int(3)); std::shared_ptr<int> q = std::atomic_load_explicit(&p, std::memory_order_relaxed); assert(*q == *p); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store.pass.cpp index 7a85a9934ef0a..a13a7d57ab960 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store.pass.cpp @@ -22,17 +22,19 @@ // void // atomic_store(shared_ptr<T>* p, shared_ptr<T> r) +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p; std::shared_ptr<int> r(new int(3)); std::atomic_store(&p, r); assert(*p == *r); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store_explicit.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store_explicit.pass.cpp index c81266c55fa47..6dfe3166c8c58 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store_explicit.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store_explicit.pass.cpp @@ -22,17 +22,19 @@ // void // atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo) +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p; std::shared_ptr<int> r(new int(3)); std::atomic_store_explicit(&p, r, std::memory_order_seq_cst); assert(*p == *r); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/test_deleter.h b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/test_deleter.h index 0263061b3a84a..bae1e013f571c 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/test_deleter.h +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/test_deleter.h @@ -52,7 +52,7 @@ public: void set_state(int i) {state_ = i;} void operator()(T* p) {assert(state_ >= 0); ++dealloc_count; delete p;} - + test_deleter* operator&() const DELETE_FUNCTION; }; diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp index 8175312334f66..f44c05eb7c86d 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp @@ -13,14 +13,20 @@ // { // public: // typedef T element_type; +// typedef weak_ptr<T> weak_type; // C++17 // ... // }; #include <memory> +#include "test_macros.h" + struct A; // purposefully incomplete int main() { static_assert((std::is_same<std::shared_ptr<A>::element_type, A>::value), ""); +#if TEST_STD_VER > 14 + static_assert((std::is_same<std::shared_ptr<A>::weak_type, std::weak_ptr<A>>::value), ""); +#endif } 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 f17485108b925..f8fdb7a094782 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 @@ -7,31 +7,18 @@ // //===----------------------------------------------------------------------===// -// XFAIL: libcpp-no-exceptions // <memory> // template<class Y> explicit shared_ptr(auto_ptr<Y>&& r); -// UNSUPPORTED: sanitizer-new-delete #include <memory> #include <new> #include <cstdlib> #include <cassert> -bool throw_next = false; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - if (throw_next) - throw std::bad_alloc(); - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - std::free(p); -} +#include "test_macros.h" +#include "count_new.hpp" struct B { @@ -59,47 +46,51 @@ int A::count = 0; int main() { { - std::auto_ptr<A> ptr(new A); - A* raw_ptr = ptr.get(); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - std::shared_ptr<B> p(std::move(ptr)); -#else - std::shared_ptr<B> p(ptr); -#endif - assert(A::count == 1); - assert(B::count == 1); - assert(p.use_count() == 1); - assert(p.get() == raw_ptr); - assert(ptr.get() == 0); - } - assert(A::count == 0); - { - std::auto_ptr<A> ptr(new A); - A* raw_ptr = ptr.get(); - throw_next = true; - try - { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + std::auto_ptr<A> ptr(new A); + A* raw_ptr = ptr.get(); +#if TEST_STD_VER >= 11 std::shared_ptr<B> p(std::move(ptr)); #else std::shared_ptr<B> p(ptr); #endif - assert(false); - } - catch (...) - { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES assert(A::count == 1); assert(B::count == 1); - assert(ptr.get() == raw_ptr); + assert(p.use_count() == 1); + assert(p.get() == raw_ptr); + assert(ptr.get() == 0); + } + assert(A::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +#if !defined(TEST_HAS_NO_EXCEPTIONS) && !defined(DISABLE_NEW_COUNT) + { + std::auto_ptr<A> ptr(new A); + A* raw_ptr = ptr.get(); + globalMemCounter.throw_after = 0; + try + { +#if TEST_STD_VER >= 11 + std::shared_ptr<B> p(std::move(ptr)); #else - // Without rvalue references, ptr got copied into - // the shared_ptr destructor and the copy was - // destroyed during unwinding. - assert(A::count == 0); - assert(B::count == 0); + std::shared_ptr<B> p(ptr); #endif - } + assert(false); + } + catch (...) + { +#if TEST_STD_VER >= 11 + assert(A::count == 1); + assert(B::count == 1); + assert(ptr.get() == raw_ptr); + #else + // Without rvalue references, ptr got copied into + // the shared_ptr destructor and the copy was + // destroyed during unwinding. + assert(A::count == 0); + assert(B::count == 0); +#endif + } } assert(A::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +#endif // !defined(TEST_HAS_NO_EXCEPTIONS) && !defined(DISABLE_NEW_COUNT) } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp index b67f31ee45a85..8a6cd0f352ff7 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp @@ -65,7 +65,7 @@ int main() assert(test_deleter<A>::count == 0); assert(test_deleter<A>::dealloc_count == 1); test_deleter<A>::dealloc_count = 0; -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 // Test an allocator that returns class-type pointers { std::shared_ptr<A> p(nullptr, test_deleter<A>(1), min_allocator<void>()); 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 6a79a8ef60db6..85fc5e930544b 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 @@ -8,18 +8,22 @@ //===----------------------------------------------------------------------===// // XFAIL: libcpp-no-exceptions +// UNSUPPORTED: sanitizer-new-delete + // <memory> // shared_ptr // template<class D> shared_ptr(nullptr_t, D d); -// UNSUPPORTED: sanitizer-new-delete - #include <memory> #include <cassert> #include <new> #include <cstdlib> + +#include "test_macros.h" +#include "count_new.hpp" + #include "../test_deleter.h" struct A @@ -33,23 +37,10 @@ struct A int A::count = 0; -bool throw_next = false; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - if (throw_next) - throw std::bad_alloc(); - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - std::free(p); -} int main() { - throw_next = true; + globalMemCounter.throw_after = 0; try { std::shared_ptr<A> p(nullptr, test_deleter<A>(3)); diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp index 1a9c09cdb78ce..b0facfc1a6eb5 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp @@ -68,7 +68,7 @@ int main() assert(test_deleter<A>::count == 0); assert(test_deleter<A>::dealloc_count == 1); test_deleter<A>::dealloc_count = 0; -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 // Test an allocator that returns class-type pointers { A* ptr = new A; 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 982313b074991..70af2964113d0 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 @@ -8,18 +8,20 @@ //===----------------------------------------------------------------------===// // XFAIL: libcpp-no-exceptions +// UNSUPPORTED: sanitizer-new-delete + // <memory> // shared_ptr // template<class Y, class D> shared_ptr(Y* p, D d); -// UNSUPPORTED: sanitizer-new-delete - #include <memory> #include <cassert> #include <new> #include <cstdlib> + +#include "count_new.hpp" #include "../test_deleter.h" struct A @@ -33,24 +35,10 @@ struct A int A::count = 0; -bool throw_next = false; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - if (throw_next) - throw std::bad_alloc(); - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - std::free(p); -} - int main() { A* ptr = new A; - throw_next = true; + globalMemCounter.throw_after = 0; try { std::shared_ptr<A> p(ptr, test_deleter<A>(3)); @@ -62,4 +50,5 @@ int main() assert(test_deleter<A>::count == 0); assert(test_deleter<A>::dealloc_count == 1); } + assert(globalMemCounter.checkOutstandingNewEq(0)); } 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 2e761d70bba09..2fa975eca833d 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 @@ -8,17 +8,20 @@ //===----------------------------------------------------------------------===// // XFAIL: libcpp-no-exceptions +// UNSUPPORTED: sanitizer-new-delete + // <memory> // template<class Y> explicit shared_ptr(Y* p); -// UNSUPPORTED: sanitizer-new-delete #include <memory> #include <new> #include <cstdlib> #include <cassert> +#include "count_new.hpp" + struct A { static int count; @@ -30,26 +33,12 @@ struct A int A::count = 0; -bool throw_next = false; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - if (throw_next) - throw std::bad_alloc(); - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - std::free(p); -} int main() { - { A* ptr = new A; - throw_next = true; assert(A::count == 1); + globalMemCounter.throw_after = 0; try { std::shared_ptr<A> p(ptr); @@ -59,5 +48,5 @@ int main() { assert(A::count == 0); } - } + assert(globalMemCounter.checkOutstandingNewEq(0)); } 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 c62fcd6893205..5c424f5c7428c 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 @@ -8,30 +8,19 @@ //===----------------------------------------------------------------------===// // XFAIL: libcpp-no-exceptions +// UNSUPPORTED: sanitizer-new-delete + // <memory> // template <class Y, class D> explicit shared_ptr(unique_ptr<Y, D>&&r); -// UNSUPPORTED: sanitizer-new-delete - #include <memory> #include <new> #include <cstdlib> #include <cassert> -bool throw_next = false; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - if (throw_next) - throw std::bad_alloc(); - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - std::free(p); -} +#include "test_macros.h" +#include "count_new.hpp" struct B { @@ -65,52 +54,46 @@ void assert_deleter ( T * ) { assert(false); } int main() { { - std::unique_ptr<A> ptr(new A); - A* raw_ptr = ptr.get(); - std::shared_ptr<B> p(std::move(ptr)); - assert(A::count == 1); - assert(B::count == 1); - assert(p.use_count() == 1); - assert(p.get() == raw_ptr); - assert(ptr.get() == 0); - } - assert(A::count == 0); - { - std::unique_ptr<A> ptr(new A); - A* raw_ptr = ptr.get(); - throw_next = true; - try - { + std::unique_ptr<A> ptr(new A); + A* raw_ptr = ptr.get(); std::shared_ptr<B> p(std::move(ptr)); - assert(false); - } - catch (...) - { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES assert(A::count == 1); assert(B::count == 1); - assert(ptr.get() == raw_ptr); -#else - assert(A::count == 0); - assert(B::count == 0); + assert(p.use_count() == 1); + assert(p.get() == raw_ptr); assert(ptr.get() == 0); -#endif - } } assert(A::count == 0); - - // LWG 2399 { - throw_next = false; - fn(std::unique_ptr<int>(new int)); + std::unique_ptr<A> ptr(new A); + A* raw_ptr = ptr.get(); + globalMemCounter.throw_after = 0; + try + { + std::shared_ptr<B> p(std::move(ptr)); + assert(false); + } + catch (...) + { +#if TEST_STD_VER >= 11 + assert(A::count == 1); + assert(B::count == 1); + assert(ptr.get() == raw_ptr); +#else + assert(A::count == 0); + assert(B::count == 0); + assert(ptr.get() == 0); +#endif + } } - -#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 + assert(A::count == 0); + { // LWG 2399 + fn(std::unique_ptr<int>(new int)); + } +#if TEST_STD_VER >= 14 + { // 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/allocate_shared.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp index aa77dab51515f..3e4a99e981d46 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <memory> // shared_ptr @@ -55,7 +57,6 @@ int main() } assert(A::count == 0); assert(test_allocator<A>::alloc_count == 0); -#if __cplusplus >= 201103L { int i = 67; char c = 'e'; @@ -74,5 +75,4 @@ int main() assert(p->get_char() == 'f'); } assert(A::count == 0); -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_cxx03.pass.cpp index 8dcd50e494110..527bbce1473e2 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_cxx03.pass.cpp @@ -14,7 +14,7 @@ // template<class T, class A, class... Args> // shared_ptr<T> allocate_shared(const A& a, Args&&... args); -#define _LIBCPP_HAS_NO_VARIADICS + #include <memory> #include <new> #include <cstdlib> @@ -112,7 +112,7 @@ int main() assert(test_allocator<Two>::alloc_count == 0); test<bare_allocator<void> >(); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<min_allocator<void> >(); #endif } 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 index 1045f9347b381..59cd3d248639d 100644 --- 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 @@ -34,7 +34,7 @@ void test(const T &t0) assert(*p0 == t0); assert(*p1 == t1); } - + { volatile T t1 = t0; std::shared_ptr<volatile T> p0 = std::make_shared<volatile T>(t0); @@ -50,7 +50,7 @@ void test(const T &t0) assert(*p0 == t0); assert(*p1 == t1); } - + } int main() diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerless/owner_less.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerless/owner_less.pass.cpp index bf1719c66ffa3..142eba2d96478 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerless/owner_less.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerless/owner_less.pass.cpp @@ -30,7 +30,7 @@ // bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const; // bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const; // }; -// +// // Added in C++17 // template<> struct owner_less<void> // { @@ -42,7 +42,7 @@ // bool operator()(weak_ptr<T> const&, shared_ptr<U> const&) const; // template<class T, class U> // bool operator()(weak_ptr<T> const&, weak_ptr<U> const&) const; -// +// // typedef unspecified is_transparent; // }; @@ -113,7 +113,7 @@ int main() cmp(wp1, wp1); } { - // test heterogeneous lookups + // test heterogeneous lookups std::set<std::shared_ptr<X>, std::owner_less<>> s; std::shared_ptr<void> vp; s.find(vp); diff --git a/test/std/utilities/meta/meta.hel/bool_constant.pass.cpp b/test/std/utilities/meta/meta.help/bool_constant.pass.cpp index 71110ea3bfb09..dcacf379b9ae3 100644 --- a/test/std/utilities/meta/meta.hel/bool_constant.pass.cpp +++ b/test/std/utilities/meta/meta.help/bool_constant.pass.cpp @@ -14,9 +14,11 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" + int main() { -#if __cplusplus > 201402L +#if TEST_STD_VER > 14 typedef std::bool_constant<true> _t; static_assert(_t::value, ""); static_assert((std::is_same<_t::value_type, bool>::value), ""); diff --git a/test/std/utilities/meta/meta.hel/integral_constant.pass.cpp b/test/std/utilities/meta/meta.help/integral_constant.pass.cpp index 335305a282364..335305a282364 100644 --- a/test/std/utilities/meta/meta.hel/integral_constant.pass.cpp +++ b/test/std/utilities/meta/meta.help/integral_constant.pass.cpp diff --git a/test/std/utilities/meta/meta.logical/conjunction.pass.cpp b/test/std/utilities/meta/meta.logical/conjunction.pass.cpp index dce58ec23725d..d8dd386e9347a 100644 --- a/test/std/utilities/meta/meta.logical/conjunction.pass.cpp +++ b/test/std/utilities/meta/meta.logical/conjunction.pass.cpp @@ -11,7 +11,7 @@ // type_traits // template<class... B> struct conjunction; // C++17 -// template<class... B> +// template<class... B> // constexpr bool conjunction_v = conjunction<B...>::value; // C++17 #include <type_traits> @@ -34,7 +34,7 @@ int main() static_assert (!std::conjunction<std::true_type, std::false_type>::value, "" ); static_assert (!std::conjunction<std::false_type, std::true_type >::value, "" ); static_assert (!std::conjunction<std::false_type, std::false_type>::value, "" ); - + static_assert ( std::conjunction_v<std::true_type, std::true_type >, "" ); static_assert (!std::conjunction_v<std::true_type, std::false_type>, "" ); static_assert (!std::conjunction_v<std::false_type, std::true_type >, "" ); diff --git a/test/std/utilities/meta/meta.logical/disjunction.pass.cpp b/test/std/utilities/meta/meta.logical/disjunction.pass.cpp index 13cd9341b99f1..f5ba178d6483d 100644 --- a/test/std/utilities/meta/meta.logical/disjunction.pass.cpp +++ b/test/std/utilities/meta/meta.logical/disjunction.pass.cpp @@ -11,7 +11,7 @@ // type_traits // template<class... B> struct disjunction; // C++17 -// template<class... B> +// template<class... B> // constexpr bool disjunction_v = disjunction<B...>::value; // C++17 #include <type_traits> @@ -34,7 +34,7 @@ int main() static_assert ( std::disjunction<std::true_type, std::false_type>::value, "" ); static_assert ( std::disjunction<std::false_type, std::true_type >::value, "" ); static_assert (!std::disjunction<std::false_type, std::false_type>::value, "" ); - + static_assert ( std::disjunction_v<std::true_type, std::true_type >, "" ); static_assert ( std::disjunction_v<std::true_type, std::false_type>, "" ); static_assert ( std::disjunction_v<std::false_type, std::true_type >, "" ); diff --git a/test/std/utilities/meta/meta.logical/negation.pass.cpp b/test/std/utilities/meta/meta.logical/negation.pass.cpp index 76ff6c5b24db8..7b4eb27a75e1a 100644 --- a/test/std/utilities/meta/meta.logical/negation.pass.cpp +++ b/test/std/utilities/meta/meta.logical/negation.pass.cpp @@ -11,7 +11,7 @@ // type_traits // template<class B> struct negation; // C++17 -// template<class B> +// template<class B> // constexpr bool negation_v = negation<B>::value; // C++17 #include <type_traits> diff --git a/test/std/utilities/meta/meta.rel/is_callable.pass.cpp b/test/std/utilities/meta/meta.rel/is_callable.pass.cpp new file mode 100644 index 0000000000000..4c85f440b0bf9 --- /dev/null +++ b/test/std/utilities/meta/meta.rel/is_callable.pass.cpp @@ -0,0 +1,160 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// type_traits + +// is_callable + +// Most testing of is_callable is done within the [meta.trans.other] result_of +// tests. + +#include <type_traits> +#include <functional> +#include <memory> + +#include "test_macros.h" + +struct Tag {}; +struct DerFromTag : Tag {}; + +struct Implicit { + Implicit(int) {} +}; + +struct Explicit { + explicit Explicit(int) {} +}; + +struct NotCallableWithInt { + int operator()(int) = delete; + int operator()(Tag) { return 42; } +}; + +int main() +{ + { + using Fn = int(Tag::*)(int); + using RFn = int(Tag::*)(int) &&; + // INVOKE bullet 1, 2 and 3 + { + // Bullet 1 + static_assert(std::is_callable<Fn(Tag&, int)>::value, ""); + static_assert(std::is_callable<Fn(DerFromTag&, int)>::value, ""); + static_assert(std::is_callable<RFn(Tag&&, int)>::value, ""); + static_assert(!std::is_callable<RFn(Tag&, int)>::value, ""); + static_assert(!std::is_callable<Fn(Tag&)>::value, ""); + static_assert(!std::is_callable<Fn(Tag const&, int)>::value, ""); + } + { + // Bullet 2 + using T = std::reference_wrapper<Tag>; + using DT = std::reference_wrapper<DerFromTag>; + using CT = std::reference_wrapper<const Tag>; + static_assert(std::is_callable<Fn(T&, int)>::value, ""); + static_assert(std::is_callable<Fn(DT&, int)>::value, ""); + static_assert(std::is_callable<Fn(const T&, int)>::value, ""); + static_assert(std::is_callable<Fn(T&&, int)>::value, ""); + static_assert(!std::is_callable<Fn(CT&, int)>::value, ""); + static_assert(!std::is_callable<RFn(T, int)>::value, ""); + } + { + // Bullet 3 + using T = Tag*; + using DT = DerFromTag*; + using CT = const Tag*; + using ST = std::unique_ptr<Tag>; + static_assert(std::is_callable<Fn(T&, int)>::value, ""); + static_assert(std::is_callable<Fn(DT&, int)>::value, ""); + static_assert(std::is_callable<Fn(const T&, int)>::value, ""); + static_assert(std::is_callable<Fn(T&&, int)>::value, ""); + static_assert(std::is_callable<Fn(ST, int)>::value, ""); + static_assert(!std::is_callable<Fn(CT&, int)>::value, ""); + static_assert(!std::is_callable<RFn(T, int)>::value, ""); + } + } + { + // Bullets 4, 5 and 6 + using Fn = int (Tag::*); + static_assert(!std::is_callable<Fn()>::value, ""); + { + // Bullet 4 + static_assert(std::is_callable<Fn(Tag&)>::value, ""); + static_assert(std::is_callable<Fn(DerFromTag&)>::value, ""); + static_assert(std::is_callable<Fn(Tag&&)>::value, ""); + static_assert(std::is_callable<Fn(Tag const&)>::value, ""); + } + { + // Bullet 5 + using T = std::reference_wrapper<Tag>; + using DT = std::reference_wrapper<DerFromTag>; + using CT = std::reference_wrapper<const Tag>; + static_assert(std::is_callable<Fn(T&)>::value, ""); + static_assert(std::is_callable<Fn(DT&)>::value, ""); + static_assert(std::is_callable<Fn(const T&)>::value, ""); + static_assert(std::is_callable<Fn(T&&)>::value, ""); + static_assert(std::is_callable<Fn(CT&)>::value, ""); + } + { + // Bullet 6 + using T = Tag*; + using DT = DerFromTag*; + using CT = const Tag*; + using ST = std::unique_ptr<Tag>; + static_assert(std::is_callable<Fn(T&)>::value, ""); + static_assert(std::is_callable<Fn(DT&)>::value, ""); + static_assert(std::is_callable<Fn(const T&)>::value, ""); + static_assert(std::is_callable<Fn(T&&)>::value, ""); + static_assert(std::is_callable<Fn(ST)>::value, ""); + static_assert(std::is_callable<Fn(CT&)>::value, ""); + } + } + { + // INVOKE bullet 7 + { + // Function pointer + using Fp = void(*)(Tag&, int); + static_assert(std::is_callable<Fp(Tag&, int)>::value, ""); + static_assert(std::is_callable<Fp(DerFromTag&, int)>::value, ""); + static_assert(!std::is_callable<Fp(const Tag&, int)>::value, ""); + static_assert(!std::is_callable<Fp()>::value, ""); + static_assert(!std::is_callable<Fp(Tag&)>::value, ""); + } + { + // Function reference + using Fp = void(&)(Tag&, int); + static_assert(std::is_callable<Fp(Tag&, int)>::value, ""); + static_assert(std::is_callable<Fp(DerFromTag&, int)>::value, ""); + static_assert(!std::is_callable<Fp(const Tag&, int)>::value, ""); + static_assert(!std::is_callable<Fp()>::value, ""); + static_assert(!std::is_callable<Fp(Tag&)>::value, ""); + } + { + // Function object + using Fn = NotCallableWithInt; + static_assert(std::is_callable<Fn(Tag)>::value, ""); + static_assert(!std::is_callable<Fn(int)>::value, ""); + } + } + { + // Check that the conversion to the return type is properly checked + using Fn = int(*)(); + static_assert(std::is_callable<Fn(), Implicit>::value, ""); + static_assert(std::is_callable<Fn(), double>::value, ""); + static_assert(std::is_callable<Fn(), const volatile void>::value, ""); + static_assert(!std::is_callable<Fn(), Explicit>::value, ""); + } + { + // Check for is_callable_v + using Fn = void(*)(); + static_assert(std::is_callable_v<Fn()>, ""); + static_assert(!std::is_callable_v<Fn(int)>, ""); + } +} 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 1681c39972d28..552c16075da7a 100644 --- a/test/std/utilities/meta/meta.rel/is_convertible.pass.cpp +++ b/test/std/utilities/meta/meta.rel/is_convertible.pass.cpp @@ -12,7 +12,6 @@ // is_convertible #include <type_traits> - #include "test_macros.h" template <class T, class U> @@ -46,12 +45,22 @@ void test_is_not_convertible() } typedef void Function(); +typedef void ConstFunction() const; typedef char Array[1]; +struct StringType { + StringType(const char*) {} +}; + class NonCopyable { NonCopyable(NonCopyable&); }; +template <typename T> +class CannotInstantiate { + enum { X = T::ThisExpressionWillBlowUp }; +}; + int main() { // void @@ -64,12 +73,19 @@ int main() test_is_not_convertible<void,char> (); test_is_not_convertible<void,char&> (); test_is_not_convertible<void,char*> (); + test_is_not_convertible<char, void>(); // Function test_is_not_convertible<Function, void> (); test_is_not_convertible<Function, Function> (); test_is_convertible<Function, Function&> (); test_is_convertible<Function, Function*> (); + test_is_convertible<Function, Function*const> (); + +#if TEST_STD_VER >= 11 + static_assert(( std::is_convertible<Function, Function&&>::value), ""); +#endif + test_is_not_convertible<Function, Array> (); test_is_not_convertible<Function, Array&> (); test_is_not_convertible<Function, char> (); @@ -100,6 +116,16 @@ int main() test_is_not_convertible<Function*, char&> (); test_is_not_convertible<Function*, char*> (); + // Non-referencable function type + static_assert((!std::is_convertible<ConstFunction, Function>::value), ""); + static_assert((!std::is_convertible<ConstFunction, Function*>::value), ""); + static_assert((!std::is_convertible<ConstFunction, Function&>::value), ""); + static_assert((!std::is_convertible<ConstFunction, Function>::value), ""); + static_assert((!std::is_convertible<Function*, ConstFunction>::value), ""); + static_assert((!std::is_convertible<Function&, ConstFunction>::value), ""); + static_assert((!std::is_convertible<ConstFunction, ConstFunction>::value), ""); + static_assert((!std::is_convertible<ConstFunction, void>::value), ""); + // Array test_is_not_convertible<Array, void> (); test_is_not_convertible<Array, Function> (); @@ -109,17 +135,37 @@ int main() static_assert((!std::is_convertible<Array, Array&>::value), ""); static_assert(( std::is_convertible<Array, const Array&>::value), ""); + static_assert((!std::is_convertible<Array, const volatile Array&>::value), ""); + static_assert((!std::is_convertible<const Array, Array&>::value), ""); static_assert(( std::is_convertible<const Array, const Array&>::value), ""); + static_assert((!std::is_convertible<Array, volatile Array&>::value), ""); + static_assert((!std::is_convertible<Array, const volatile Array&>::value), ""); + +#if TEST_STD_VER >= 11 + static_assert(( std::is_convertible<Array, Array&&>::value), ""); + static_assert(( std::is_convertible<Array, const Array&&>::value), ""); + static_assert(( std::is_convertible<Array, volatile Array&&>::value), ""); + static_assert(( std::is_convertible<Array, const volatile Array&&>::value), ""); + static_assert(( std::is_convertible<const Array, const Array&&>::value), ""); + static_assert((!std::is_convertible<Array&, Array&&>::value), ""); + static_assert((!std::is_convertible<Array&&, Array&>::value), ""); +#endif test_is_not_convertible<Array, char> (); test_is_not_convertible<Array, char&> (); static_assert(( std::is_convertible<Array, char*>::value), ""); static_assert(( std::is_convertible<Array, const char*>::value), ""); + static_assert(( std::is_convertible<Array, char* const>::value), ""); + static_assert(( std::is_convertible<Array, char* const volatile>::value), ""); + static_assert((!std::is_convertible<const Array, char*>::value), ""); static_assert(( std::is_convertible<const Array, const char*>::value), ""); + static_assert((!std::is_convertible<char[42][42], char*>::value), ""); + static_assert((!std::is_convertible<char[][1], char*>::value), ""); + // Array& test_is_not_convertible<Array&, void> (); test_is_not_convertible<Array&, Function> (); @@ -140,6 +186,9 @@ int main() static_assert((!std::is_convertible<const Array&, char*>::value), ""); static_assert(( std::is_convertible<const Array&, const char*>::value), ""); + static_assert((std::is_convertible<Array, StringType>::value), ""); + static_assert((std::is_convertible<char(&)[], StringType>::value), ""); + // char test_is_not_convertible<char, void> (); test_is_not_convertible<char, Function> (); @@ -149,7 +198,7 @@ int main() test_is_not_convertible<char, Array&> (); test_is_convertible<char, char> (); - + static_assert((!std::is_convertible<char, char&>::value), ""); static_assert(( std::is_convertible<char, const char&>::value), ""); static_assert((!std::is_convertible<const char, char&>::value), ""); @@ -166,7 +215,7 @@ int main() test_is_not_convertible<char&, Array&> (); test_is_convertible<char&, char> (); - + static_assert(( std::is_convertible<char&, char&>::value), ""); static_assert(( std::is_convertible<char&, const char&>::value), ""); static_assert((!std::is_convertible<const char&, char&>::value), ""); @@ -184,7 +233,7 @@ int main() test_is_not_convertible<char*, char> (); test_is_not_convertible<char*, char&> (); - + static_assert(( std::is_convertible<char*, char*>::value), ""); static_assert(( std::is_convertible<char*, const char*>::value), ""); static_assert((!std::is_convertible<const char*, char*>::value), ""); @@ -202,8 +251,11 @@ int main() 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) +#if TEST_STD_VER >= 11 || !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) test_is_not_convertible<NonCopyable&, NonCopyable>(); #endif + // Ensure that CannotInstantiate is not instantiated by is_convertible when it is not needed. + // For example CannotInstantiate is instatiated as a part of ADL lookup for arguments of type CannotInstantiate*. + static_assert((std::is_convertible<CannotInstantiate<int>*, CannotInstantiate<int>*>::value), ""); } diff --git a/test/std/utilities/meta/meta.rel/is_nothrow_callable.pass.cpp b/test/std/utilities/meta/meta.rel/is_nothrow_callable.pass.cpp new file mode 100644 index 0000000000000..eefa6d1f22b18 --- /dev/null +++ b/test/std/utilities/meta/meta.rel/is_nothrow_callable.pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// type_traits + +// is_nothrow_callable + +#include <type_traits> +#include <functional> + +#include "test_macros.h" + +struct Tag {}; + +struct Implicit { + Implicit(int) noexcept {} +}; + +struct ThrowsImplicit { + ThrowsImplicit(int) {} +}; + +struct Explicit { + explicit Explicit(int) noexcept {} +}; + +template <bool IsNoexcept, class Ret, class ...Args> +struct CallObject { + Ret operator()(Args&&...) const noexcept(IsNoexcept); +}; + +template <class Fn> +constexpr bool throws_callable() { + return std::is_callable<Fn>::value && + !std::is_nothrow_callable<Fn>::value; +} + +template <class Fn, class Ret> +constexpr bool throws_callable() { + return std::is_callable<Fn, Ret>::value && + !std::is_nothrow_callable<Fn, Ret>::value; +} + +// FIXME(EricWF) Don't test the where noexcept is *not* part of the type system +// once implementations have caught up. +void test_noexcept_function_pointers() +{ + struct Dummy { void foo() noexcept {} static void bar() noexcept {} }; +#if !defined(__cpp_noexcept_function_type) + { + // Check that PMF's and function pointers *work*. is_nothrow_callable will always + // return false because 'noexcept' is not part of the function type. + static_assert(throws_callable<decltype(&Dummy::foo)(Dummy&)>(), ""); + static_assert(throws_callable<decltype(&Dummy::bar)()>(), ""); + } +#else + { + // Check that PMF's and function pointers actually work and that + // is_nothrow_callable returns true for noexcept PMF's and function + // pointers. + static_assert(std::is_nothrow_callable<decltype(&Dummy::foo)(Dummy&)>::value, ""); + static_assert(std::is_nothrow_callable<decltype(&Dummy::bar)()>::value, ""); + } +#endif +} + +int main() +{ + { + // Check that the conversion to the return type is properly checked + using Fn = CallObject<true, int>; + static_assert(std::is_nothrow_callable<Fn(), Implicit>::value, ""); + static_assert(std::is_nothrow_callable<Fn(), double>::value, ""); + static_assert(std::is_nothrow_callable<Fn(), const volatile void>::value, ""); + static_assert(throws_callable<Fn(), ThrowsImplicit>(), ""); + static_assert(!std::is_nothrow_callable<Fn(), Explicit>(), ""); + } + { + // Check that the conversion to the parameters is properly checked + using Fn = CallObject<true, void, const Implicit&, const ThrowsImplicit&>; + static_assert(std::is_nothrow_callable<Fn(Implicit&, ThrowsImplicit&)>::value, ""); + static_assert(std::is_nothrow_callable<Fn(int, ThrowsImplicit&)>::value, ""); + static_assert(throws_callable<Fn(int, int)>(), ""); + static_assert(!std::is_nothrow_callable<Fn()>::value, ""); + } + { + // Check that the noexcept-ness of function objects is checked. + using Fn = CallObject<true, void>; + using Fn2 = CallObject<false, void>; + static_assert(std::is_nothrow_callable<Fn()>::value, ""); + static_assert(throws_callable<Fn2()>(), ""); + } + { + // Check that PMD derefs are noexcept + using Fn = int (Tag::*); + static_assert(std::is_nothrow_callable<Fn(Tag&)>::value, ""); + static_assert(std::is_nothrow_callable<Fn(Tag&), Implicit>::value, ""); + static_assert(throws_callable<Fn(Tag&), ThrowsImplicit>(), ""); + } + { + // Check for is_nothrow_callable_v + using Fn = CallObject<true, int>; + static_assert(std::is_nothrow_callable_v<Fn()>, ""); + static_assert(!std::is_nothrow_callable_v<Fn(int)>, ""); + } + test_noexcept_function_pointers(); +} diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp index a53bed984c5e2..079661d0c1749 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp @@ -164,7 +164,7 @@ int main() // Use alignof(std::max_align_t) below to find the max alignment instead of // hardcoding it, because it's different on different platforms. // (For example 8 on arm and 16 on x86.) -#if __cplusplus < 201103L +#if TEST_STD_VER < 11 #define alignof __alignof__ #endif { diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/enable_if2.fail.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/enable_if2.fail.cpp index 8ce894578c4fd..8c9b42d60f30e 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.other/enable_if2.fail.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.other/enable_if2.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // type_traits // enable_if @@ -15,9 +16,5 @@ int main() { -#if _LIBCPP_STD_VER > 11 typedef std::enable_if_t<false> A; -#else - static_assert ( false, "" ); -#endif } 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 5a925bb34b260..fc01b22c36abe 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,6 +13,7 @@ #include <type_traits> #include <memory> +#include <cassert> #include "test_macros.h" struct S @@ -25,6 +26,11 @@ struct S double const volatile& operator()(char, int&) const volatile; }; + +struct SD : public S { }; + +struct NotDerived {}; + template <class Tp> struct Voider { typedef void type; @@ -39,6 +45,10 @@ struct HasType<T, typename Voider<typename T::type>::type> : std::true_type {}; template <class T, class U> void test_result_of() { +#if TEST_STD_VER > 14 + static_assert(std::is_callable<T>::value, ""); + static_assert(std::is_callable<T, U>::value, ""); +#endif static_assert((std::is_same<typename std::result_of<T>::type, U>::value), ""); } @@ -48,10 +58,14 @@ void test_no_result() #if TEST_STD_VER >= 11 static_assert((!HasType<std::result_of<T> >::value), ""); #endif +#if TEST_STD_VER > 14 + static_assert(std::is_callable<T>::value == false, ""); +#endif } int main() { + typedef NotDerived ND; { // functor object test_result_of<S(int), short> (); test_result_of<S&(unsigned char, int&), double> (); @@ -90,32 +104,64 @@ int main() 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_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::reference_wrapper<S>), int> (); + test_result_of<PMS0(const std::reference_wrapper<S>&), int> (); + test_result_of<PMS0( std::reference_wrapper<SD>), int> (); + test_result_of<PMS0(const std::reference_wrapper<SD>&), int> (); + test_result_of<PMS0(std::unique_ptr<S>), int> (); + test_result_of<PMS0(std::unique_ptr<SD>), int> (); test_no_result<PMS0(const S&)>(); test_no_result<PMS0(volatile S&)>(); test_no_result<PMS0(const volatile S&)>(); + test_no_result<PMS0(ND & )>(); + test_no_result<PMS0(const ND& )>(); + test_no_result<PMS0(std::unique_ptr<S const> )>(); + test_no_result<PMS0(std::reference_wrapper<S const>)>(); + test_no_result<PMS0(std::reference_wrapper<ND> )>(); + test_no_result<PMS0(std::unique_ptr<ND> )>(); - 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_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_result_of<PMS1(std::unique_ptr<SD>, int), int*> (); + test_result_of<PMS1(std::reference_wrapper<S>, int), int*> (); + test_result_of<PMS1(const std::reference_wrapper<S>&, int), int*> (); + test_result_of<PMS1(std::reference_wrapper<SD>, int), int*> (); + test_result_of<PMS1(const std::reference_wrapper<SD>&, 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_no_result<PMS1(ND &, int)>(); + test_no_result<PMS1(const ND&, int)>(); + test_no_result<PMS1(std::unique_ptr<S const>, int)>(); + test_no_result<PMS1(std::reference_wrapper<S const>, int)>(); + test_no_result<PMS1(std::reference_wrapper<ND>, int)>(); + test_no_result<PMS1(std::unique_ptr<ND>, 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_result_of<PMS2(std::unique_ptr<SD>, int, int), int&> (); + test_result_of<PMS2(std::reference_wrapper<S>, int, int), int&> (); + test_result_of<PMS2(const std::reference_wrapper<S>&, int, int), int&> (); + test_result_of<PMS2(std::reference_wrapper<SD>, int, int), int&> (); + test_result_of<PMS2(const std::reference_wrapper<SD>&, 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)>(); + test_no_result<PMS2(std::unique_ptr<S const>, int, int)>(); + test_no_result<PMS2(std::reference_wrapper<S const>, int, int)>(); + test_no_result<PMS2(const ND&, int, int)>(); + test_no_result<PMS2(std::reference_wrapper<ND>, int, int)>(); + test_no_result<PMS2(std::unique_ptr<ND>, int, int)>(); typedef int (S::*PMS0C)() const; typedef int* (S::*PMS1C)(long) const; @@ -128,6 +174,15 @@ int main() test_result_of<PMS0C( S*&), int> (); test_result_of<PMS0C(const S*&), int> (); test_result_of<PMS0C(std::unique_ptr<S>), int> (); + test_result_of<PMS0C(std::unique_ptr<SD>), int> (); + test_result_of<PMS0C(std::reference_wrapper<S> ), int> (); + test_result_of<PMS0C(std::reference_wrapper<const S> ), int> (); + test_result_of<PMS0C(const std::reference_wrapper<S> & ), int> (); + test_result_of<PMS0C(const std::reference_wrapper<const S> &), int> (); + test_result_of<PMS0C(std::reference_wrapper<SD> ), int> (); + test_result_of<PMS0C(std::reference_wrapper<const SD> ), int> (); + test_result_of<PMS0C(const std::reference_wrapper<SD> & ), int> (); + test_result_of<PMS0C(const std::reference_wrapper<const SD> &), int> (); test_no_result<PMS0C(volatile S&)>(); test_no_result<PMS0C(const volatile S&)>(); @@ -248,5 +303,16 @@ int main() 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&> (); + test_result_of<PMD(SD&), char &>(); + test_result_of<PMD(SD const&), const char&>(); + test_result_of<PMD(SD*), char&>(); + test_result_of<PMD(const SD*), const char&>(); + test_result_of<PMD(std::unique_ptr<S>), char &>(); + test_result_of<PMD(std::unique_ptr<S const>), const char&>(); +#if TEST_STD_VER >= 11 + test_result_of<PMD(std::reference_wrapper<S>), char&>(); + test_result_of<PMD(std::reference_wrapper<S const>), const char&>(); +#endif + test_no_result<PMD(ND&)>(); } } 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 index 6996cddc08b90..8cb5853bbc6d7 100644 --- 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 @@ -14,6 +14,8 @@ // result_of<Fn(ArgTypes...)> #include <type_traits> +#include <memory> +#include <utility> #include "test_macros.h" struct wat @@ -23,6 +25,8 @@ struct wat }; struct F {}; +struct FD : public F {}; +struct NotDerived {}; template <class T, class U> void test_result_of_imp() @@ -31,10 +35,15 @@ void test_result_of_imp() #if TEST_STD_VER > 11 static_assert((std::is_same<std::result_of_t<T>, U>::value), ""); #endif +#if TEST_STD_VER > 14 + static_assert(std::is_callable<T>::value, ""); + static_assert(std::is_callable<T, U>::value, ""); +#endif } int main() { + typedef NotDerived ND; { typedef char F::*PMD; test_result_of_imp<PMD(F &), char &>(); @@ -51,6 +60,31 @@ int main() 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<PMD(FD &), char &>(); + test_result_of_imp<PMD(FD const &), char const &>(); + test_result_of_imp<PMD(FD volatile &), char volatile &>(); + test_result_of_imp<PMD(FD const volatile &), char const volatile &>(); + + test_result_of_imp<PMD(FD &&), char &&>(); + test_result_of_imp<PMD(FD const &&), char const &&>(); + test_result_of_imp<PMD(FD volatile &&), char volatile &&>(); + test_result_of_imp<PMD(FD const volatile &&), char const volatile &&>(); + + test_result_of_imp<PMD(FD ), char &&>(); + test_result_of_imp<PMD(FD const ), char &&>(); + test_result_of_imp<PMD(FD volatile ), char &&>(); + test_result_of_imp<PMD(FD const volatile ), char &&>(); + + test_result_of_imp<PMD(std::unique_ptr<F>), char &>(); + test_result_of_imp<PMD(std::unique_ptr<F const>), const char &>(); + test_result_of_imp<PMD(std::unique_ptr<FD>), char &>(); + test_result_of_imp<PMD(std::unique_ptr<FD const>), const char &>(); + + test_result_of_imp<PMD(std::reference_wrapper<F>), char &>(); + test_result_of_imp<PMD(std::reference_wrapper<F const>), const char &>(); + test_result_of_imp<PMD(std::reference_wrapper<FD>), char &>(); + test_result_of_imp<PMD(std::reference_wrapper<FD const>), const char &>(); } { test_result_of_imp<int (F::* (F &)) () &, int> (); @@ -83,6 +117,42 @@ int main() 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::* (FD &)) () &, int> (); + test_result_of_imp<int (F::* (FD &)) () const &, int> (); + test_result_of_imp<int (F::* (FD &)) () volatile &, int> (); + test_result_of_imp<int (F::* (FD &)) () const volatile &, int> (); + test_result_of_imp<int (F::* (FD const &)) () const &, int> (); + test_result_of_imp<int (F::* (FD const &)) () const volatile &, int> (); + test_result_of_imp<int (F::* (FD volatile &)) () volatile &, int> (); + test_result_of_imp<int (F::* (FD volatile &)) () const volatile &, int> (); + test_result_of_imp<int (F::* (FD const volatile &)) () const volatile &, int> (); + + test_result_of_imp<int (F::* (FD &&)) () &&, int> (); + test_result_of_imp<int (F::* (FD &&)) () const &&, int> (); + test_result_of_imp<int (F::* (FD &&)) () volatile &&, int> (); + test_result_of_imp<int (F::* (FD &&)) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD const &&)) () const &&, int> (); + test_result_of_imp<int (F::* (FD const &&)) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD volatile &&)) () volatile &&, int> (); + test_result_of_imp<int (F::* (FD volatile &&)) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD const volatile &&)) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD )) () &&, int> (); + test_result_of_imp<int (F::* (FD )) () const &&, int> (); + test_result_of_imp<int (F::* (FD )) () volatile &&, int> (); + test_result_of_imp<int (F::* (FD )) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD const )) () const &&, int> (); + test_result_of_imp<int (F::* (FD const )) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD volatile )) () volatile &&, int> (); + test_result_of_imp<int (F::* (FD volatile )) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD const volatile )) () const volatile &&, int> (); + } + { + test_result_of_imp<int (F::* (std::reference_wrapper<F>)) (), int>(); + test_result_of_imp<int (F::* (std::reference_wrapper<const F>)) () const, int>(); + test_result_of_imp<int (F::* (std::unique_ptr<F> )) (), int>(); + test_result_of_imp<int (F::* (std::unique_ptr<const F> )) () const, int>(); + } test_result_of_imp<decltype(&wat::foo)(wat), void>(); } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp index 728062b70684a..1d7b23c192225 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp @@ -14,6 +14,8 @@ #include <type_traits> #include <climits> +#include "test_macros.h" + enum E { V = INT_MIN }; enum F { W = UINT_MAX }; @@ -29,7 +31,7 @@ int main() static_assert((std::is_same<std::underlying_type_t<F>, unsigned>::value), ""); #endif -#if __has_feature(cxx_strong_enums) +#if TEST_STD_VER >= 11 enum G : char { }; static_assert((std::is_same<std::underlying_type<G>::type, char>::value), @@ -37,5 +39,5 @@ int main() #if _LIBCPP_STD_VER > 11 static_assert((std::is_same<std::underlying_type_t<G>, char>::value), ""); #endif -#endif // __has_feature(cxx_strong_enums) +#endif // TEST_STD_VER >= 11 } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.ptr/add_pointer.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.ptr/add_pointer.pass.cpp index 76d0f12d03fb5..51b3e5d736882 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.ptr/add_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.ptr/add_pointer.pass.cpp @@ -10,18 +10,42 @@ // type_traits // add_pointer +// If T names a referenceable type or a (possibly cv-qualified) void type then +// the member typedef type shall name the same type as remove_reference_t<T>*; +// otherwise, type shall name T. #include <type_traits> +#include "test_macros.h" template <class T, class U> void test_add_pointer() { static_assert((std::is_same<typename std::add_pointer<T>::type, U>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::add_pointer_t<T>, U>::value), ""); #endif } +template <class F> +void test_function0() +{ + static_assert((std::is_same<typename std::add_pointer<F>::type, F*>::value), ""); +#if TEST_STD_VER > 11 + static_assert((std::is_same<std::add_pointer_t<F>, F*>::value), ""); +#endif +} + +template <class F> +void test_function1() +{ + static_assert((std::is_same<typename std::add_pointer<F>::type, F>::value), ""); +#if TEST_STD_VER > 11 + static_assert((std::is_same<std::add_pointer_t<F>, F>::value), ""); +#endif +} + +struct Foo {}; + int main() { test_add_pointer<void, void*>(); @@ -31,4 +55,26 @@ int main() test_add_pointer<const int&, const int*>(); test_add_pointer<int*, int**>(); test_add_pointer<const int*, const int**>(); + test_add_pointer<Foo, Foo*>(); + +// LWG 2101 specifically talks about add_pointer and functions. +// The term of art is "a referenceable type", which a cv- or ref-qualified function is not. + test_function0<void()>(); +#if TEST_STD_VER >= 11 + test_function1<void() const>(); + test_function1<void() &>(); + test_function1<void() &&>(); + test_function1<void() const &>(); + test_function1<void() const &&>(); +#endif + +// But a cv- or ref-qualified member function *is* "a referenceable type" + test_function0<void (Foo::*)()>(); +#if TEST_STD_VER >= 11 + test_function0<void (Foo::*)() const>(); + test_function0<void (Foo::*)() &>(); + test_function0<void (Foo::*)() &&>(); + test_function0<void (Foo::*)() const &>(); + test_function0<void (Foo::*)() const &&>(); +#endif } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.ptr/remove_pointer.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.ptr/remove_pointer.pass.cpp index 9cecd39049fc4..cccbb6011edf1 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.ptr/remove_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.ptr/remove_pointer.pass.cpp @@ -12,12 +12,13 @@ // remove_pointer #include <type_traits> +#include "test_macros.h" template <class T, class U> void test_remove_pointer() { static_assert((std::is_same<typename std::remove_pointer<T>::type, U>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::remove_pointer_t<T>, U>::value), ""); #endif } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.ref/add_lvalue_ref.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.ref/add_lvalue_ref.pass.cpp index fb53312cbe677..c82c282995355 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.ref/add_lvalue_ref.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.ref/add_lvalue_ref.pass.cpp @@ -10,14 +10,17 @@ // type_traits // add_lvalue_reference +// If T names a referenceable type then the member typedef type +// shall name T&; otherwise, type shall name T. #include <type_traits> +#include "test_macros.h" template <class T, class U> void test_add_lvalue_reference() { static_assert((std::is_same<typename std::add_lvalue_reference<T>::type, U>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::add_lvalue_reference_t<T>, U>::value), ""); #endif } @@ -26,7 +29,7 @@ template <class F> void test_function0() { static_assert((std::is_same<typename std::add_lvalue_reference<F>::type, F&>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::add_lvalue_reference_t<F>, F&>::value), ""); #endif } @@ -35,7 +38,7 @@ template <class F> void test_function1() { static_assert((std::is_same<typename std::add_lvalue_reference<F>::type, F>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::add_lvalue_reference_t<F>, F>::value), ""); #endif } @@ -51,20 +54,26 @@ int main() test_add_lvalue_reference<const int&, const int&>(); test_add_lvalue_reference<int*, int*&>(); test_add_lvalue_reference<const int*, const int*&>(); + test_add_lvalue_reference<Foo, Foo&>(); // LWG 2101 specifically talks about add_lvalue_reference and functions. // The term of art is "a referenceable type", which a cv- or ref-qualified function is not. test_function0<void()>(); -// test_function1<void() const>(); -// test_function1<void() &>(); -// test_function1<void() &&>(); -// test_function1<void() const &>(); -// test_function1<void() const &&>(); +#if TEST_STD_VER >= 11 + test_function1<void() const>(); + test_function1<void() &>(); + test_function1<void() &&>(); + test_function1<void() const &>(); + test_function1<void() const &&>(); +#endif +// But a cv- or ref-qualified member function *is* "a referenceable type" test_function0<void (Foo::*)()>(); +#if TEST_STD_VER >= 11 test_function0<void (Foo::*)() const>(); test_function0<void (Foo::*)() &>(); test_function0<void (Foo::*)() &&>(); test_function0<void (Foo::*)() const &>(); test_function0<void (Foo::*)() const &&>(); +#endif } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.ref/add_rvalue_ref.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.ref/add_rvalue_ref.pass.cpp index e8f08fdc398ad..fc147c37b1acc 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.ref/add_rvalue_ref.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.ref/add_rvalue_ref.pass.cpp @@ -10,8 +10,11 @@ // type_traits // add_rvalue_reference +// If T names a referenceable type then the member typedef type +// shall name T&&; otherwise, type shall name T. #include <type_traits> +#include "test_macros.h" #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -19,13 +22,32 @@ template <class T, class U> void test_add_rvalue_reference() { static_assert((std::is_same<typename std::add_rvalue_reference<T>::type, U>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::add_rvalue_reference_t<T>, U>::value), ""); #endif } +template <class F> +void test_function0() +{ + static_assert((std::is_same<typename std::add_rvalue_reference<F>::type, F&&>::value), ""); +#if TEST_STD_VER > 11 + static_assert((std::is_same<std::add_rvalue_reference_t<F>, F&&>::value), ""); +#endif +} + +template <class F> +void test_function1() +{ + static_assert((std::is_same<typename std::add_rvalue_reference<F>::type, F>::value), ""); +#if TEST_STD_VER > 11 + static_assert((std::is_same<std::add_rvalue_reference_t<F>, F>::value), ""); +#endif +} #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +struct Foo {}; + int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -36,5 +58,27 @@ int main() test_add_rvalue_reference<const int&, const int&>(); test_add_rvalue_reference<int*, int*&&>(); test_add_rvalue_reference<const int*, const int*&&>(); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + test_add_rvalue_reference<Foo, Foo&&>(); + +// LWG 2101 specifically talks about add_rvalue_reference and functions. +// The term of art is "a referenceable type", which a cv- or ref-qualified function is not. + test_function0<void()>(); +#if TEST_STD_VER >= 11 + test_function1<void() const>(); + test_function1<void() &>(); + test_function1<void() &&>(); + test_function1<void() const &>(); + test_function1<void() const &&>(); +#endif + +// But a cv- or ref-qualified member function *is* "a referenceable type" + test_function0<void (Foo::*)()>(); +#if TEST_STD_VER >= 11 + test_function0<void (Foo::*)() const>(); + test_function0<void (Foo::*)() &>(); + test_function0<void (Foo::*)() &&>(); + test_function0<void (Foo::*)() const &>(); + test_function0<void (Foo::*)() const &&>(); +#endif +#endif } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.ref/remove_ref.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.ref/remove_ref.pass.cpp index f9ebc37a5dd28..e335bd19ef2d3 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.ref/remove_ref.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.ref/remove_ref.pass.cpp @@ -12,12 +12,13 @@ // remove_reference #include <type_traits> +#include "test_macros.h" template <class T, class U> void test_remove_reference() { static_assert((std::is_same<typename std::remove_reference<T>::type, U>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::remove_reference_t<T>, U>::value), ""); #endif } diff --git a/test/std/utilities/meta/meta.unary.prop.query/void_t.pass.cpp b/test/std/utilities/meta/meta.unary.prop.query/void_t.pass.cpp index ccec65fec3992..05ef99d0ebf4d 100644 --- a/test/std/utilities/meta/meta.unary.prop.query/void_t.pass.cpp +++ b/test/std/utilities/meta/meta.unary.prop.query/void_t.pass.cpp @@ -57,7 +57,7 @@ int main() test1<Class>(); test1<Class[]>(); test1<Class[5]>(); - + test2<void, int>(); test2<double, int>(); test2<int&, int>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/array.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/array.pass.cpp index f4dd356383af1..ef1fc4040dc75 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/array.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/array.pass.cpp @@ -12,12 +12,13 @@ // array #include <type_traits> +#include "test_macros.h" template <class T> void test_array_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, ""); @@ -46,10 +47,15 @@ void test_array() typedef char array[3]; typedef const char const_array[3]; typedef char incomplete_array[]; +struct Incomplete; int main() { test_array<array>(); test_array<const_array>(); test_array<incomplete_array>(); + test_array<Incomplete[]>(); + +// LWG#2582 + static_assert(!std::is_array<Incomplete>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/class.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/class.pass.cpp index ac5d6e5923117..8c8510882bf6d 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/class.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/class.pass.cpp @@ -12,12 +12,13 @@ // class #include <type_traits> +#include "test_macros.h" template <class T> void test_class_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, ""); @@ -47,7 +48,13 @@ class Class { }; +struct incomplete_type; + int main() { test_class<Class>(); + test_class<incomplete_type>(); + +// LWG#2582 + static_assert( std::is_class<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/enum.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/enum.pass.cpp index 7c9c78fcf2b9d..40dea443cd41f 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/enum.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/enum.pass.cpp @@ -12,12 +12,13 @@ // enum #include <type_traits> +#include "test_macros.h" template <class T> void test_enum_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, ""); @@ -44,8 +45,12 @@ void test_enum() } enum Enum {zero, one}; +struct incomplete_type; int main() { test_enum<Enum>(); + +// LWG#2582 + static_assert(!std::is_enum<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/floating_point.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/floating_point.pass.cpp index 286644960315f..217bc7e25659d 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/floating_point.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/floating_point.pass.cpp @@ -12,12 +12,13 @@ // floating_point #include <type_traits> +#include "test_macros.h" template <class T> void test_floating_point_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, ""); @@ -43,9 +44,14 @@ void test_floating_point() test_floating_point_imp<const volatile T>(); } +struct incomplete_type; + int main() { test_floating_point<float>(); test_floating_point<double>(); test_floating_point<long double>(); + +// LWG#2582 + static_assert(!std::is_floating_point<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/function.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/function.pass.cpp index b1df4f2d3f4cc..3f21b9a7dbcfe 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/function.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/function.pass.cpp @@ -12,13 +12,14 @@ // function #include <type_traits> +#include "test_macros.h" using namespace std; class Class {}; enum Enum1 {}; -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 enum class Enum2 : int {}; #else enum Enum2 {}; @@ -28,7 +29,7 @@ template <class T> void test() { 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, ""); @@ -64,6 +65,7 @@ void test() test<__VA_ARGS__ volatile &&>(); \ test<__VA_ARGS__ const volatile &&>() +struct incomplete_type; int main() { @@ -75,7 +77,7 @@ int main() TEST_REGULAR( void (int, ...) ); TEST_REGULAR( int (double, ...) ); TEST_REGULAR( int (double, char, ...) ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 TEST_REF_QUALIFIED( void () ); TEST_REF_QUALIFIED( void (int) ); TEST_REF_QUALIFIED( int (double) ); @@ -85,4 +87,7 @@ int main() TEST_REF_QUALIFIED( int (double, ...) ); TEST_REF_QUALIFIED( int (double, char, ...) ); #endif + +// LWG#2582 + static_assert(!std::is_function<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/integral.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/integral.pass.cpp index f68ed3ef7e57e..a50beeb3e3106 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/integral.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/integral.pass.cpp @@ -12,12 +12,13 @@ // integral #include <type_traits> +#include "test_macros.h" template <class T> void test_integral_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, ""); @@ -43,6 +44,8 @@ void test_integral() test_integral_imp<const volatile T>(); } +struct incomplete_type; + int main() { test_integral<bool>(); @@ -62,4 +65,7 @@ int main() test_integral<__int128_t>(); test_integral<__uint128_t>(); #endif + +// LWG#2582 + static_assert(!std::is_integral<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_array.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_array.pass.cpp index 72955defa3990..dfd09ac52bfa4 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_array.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_array.pass.cpp @@ -12,7 +12,7 @@ // is_array #include <type_traits> -#include <cstddef> // for std::nullptr_t +#include <cstddef> // for std::nullptr_t #include "test_macros.h" template <class T> @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -89,5 +90,5 @@ int main() test_is_not_array<Empty>(); test_is_not_array<bit_zero>(); test_is_not_array<NotEmpty>(); - test_is_not_array<Abstract>(); + test_is_not_array<incomplete_type>(); // LWG#2582 } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_class.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_class.pass.cpp index 97671e7b62e00..3c1a2181d2614 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_class.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_class.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -76,6 +77,7 @@ int main() test_is_class<bit_zero>(); test_is_class<NotEmpty>(); test_is_class<Abstract>(); + test_is_class<incomplete_type>(); #if TEST_STD_VER >= 11 // In C++03 we have an emulation of std::nullptr_t diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_enum.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_enum.pass.cpp index 481260ea6e524..2603bdff26d2d 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_enum.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_enum.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -90,4 +91,5 @@ int main() test_is_not_enum<NotEmpty>(); test_is_not_enum<Abstract>(); test_is_not_enum<FunctionPtr>(); + test_is_not_enum<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_floating_point.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_floating_point.pass.cpp index de9c146bcb4e2..7e19c0629672c 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_floating_point.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_floating_point.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -98,4 +99,5 @@ int main() test_is_not_floating_point<Abstract>(); test_is_not_floating_point<Enum>(); test_is_not_floating_point<FunctionPtr>(); + test_is_not_floating_point<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_function.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_function.pass.cpp index 9a1d821b0746c..32e4f06beb04e 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_function.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_function.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -77,7 +78,7 @@ int main() test_is_function<int(int, double)>(); test_is_function<int(Abstract *)>(); test_is_function<void(...)>(); - + test_is_not_function<std::nullptr_t>(); test_is_not_function<void>(); test_is_not_function<int>(); @@ -95,4 +96,5 @@ int main() test_is_not_function<NotEmpty>(); test_is_not_function<Abstract>(); test_is_not_function<Abstract*>(); + test_is_not_function<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp index 86b63c53da54d..09997626ea06d 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -101,4 +102,5 @@ int main() test_is_not_integral<bit_zero>(); test_is_not_integral<NotEmpty>(); test_is_not_integral<Abstract>(); + test_is_not_integral<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_lvalue_reference.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_lvalue_reference.pass.cpp index 0e59f7153f506..41b8d44b93158 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_lvalue_reference.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_lvalue_reference.pass.cpp @@ -69,6 +69,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -92,4 +93,5 @@ int main() test_is_not_lvalue_reference<bit_zero>(); test_is_not_lvalue_reference<NotEmpty>(); test_is_not_lvalue_reference<Abstract>(); + test_is_not_lvalue_reference<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_object_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_object_pointer.pass.cpp index 8da411d2eeed6..9498edc652abf 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_object_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_object_pointer.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -94,4 +95,5 @@ int main() test_is_not_member_object_pointer<bit_zero>(); test_is_not_member_object_pointer<NotEmpty>(); test_is_not_member_object_pointer<Abstract>(); + test_is_not_member_object_pointer<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_pointer.pass.cpp index 19a74b01d0fdc..d4043f48f98ed 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_pointer.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -95,4 +96,5 @@ int main() test_is_not_member_pointer<bit_zero>(); test_is_not_member_pointer<NotEmpty>(); test_is_not_member_pointer<Abstract>(); + test_is_not_member_pointer<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_null_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_null_pointer.pass.cpp index 80f563e8969e3..f575763300a70 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_null_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_null_pointer.pass.cpp @@ -69,6 +69,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -92,4 +93,5 @@ int main() test_is_not_null_pointer<bit_zero>(); test_is_not_null_pointer<NotEmpty>(); test_is_not_null_pointer<Abstract>(); + test_is_not_null_pointer<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_pointer.pass.cpp index a901aed1143e2..257719eb940ee 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_pointer.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -91,4 +92,5 @@ int main() test_is_not_pointer<bit_zero>(); test_is_not_pointer<NotEmpty>(); test_is_not_pointer<Abstract>(); + test_is_not_pointer<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_rvalue_reference.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_rvalue_reference.pass.cpp index b7b52687018a0..89639377ce81a 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_rvalue_reference.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_rvalue_reference.pass.cpp @@ -69,6 +69,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -92,4 +93,5 @@ int main() test_is_not_rvalue_reference<bit_zero>(); test_is_not_rvalue_reference<NotEmpty>(); test_is_not_rvalue_reference<Abstract>(); + test_is_not_rvalue_reference<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_union.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_union.pass.cpp index 307fedb32b269..415d9a7813dd2 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_union.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_union.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -90,4 +91,5 @@ int main() test_is_not_union<bit_zero>(); test_is_not_union<NotEmpty>(); test_is_not_union<Abstract>(); + test_is_not_union<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_void.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_void.pass.cpp index 1647666adf2e2..952a5b748f532 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_void.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_void.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -89,4 +90,5 @@ int main() test_is_not_void<Abstract>(); test_is_not_void<Enum>(); test_is_not_void<FunctionPtr>(); + test_is_not_void<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/lvalue_ref.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/lvalue_ref.pass.cpp index 3b6ccade7e742..13cad58c0ef3f 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/lvalue_ref.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/lvalue_ref.pass.cpp @@ -34,8 +34,13 @@ void test_lvalue_ref() static_assert(!std::is_function<T>::value, ""); } +struct incomplete_type; + int main() { test_lvalue_ref<int&>(); test_lvalue_ref<const int&>(); + +// LWG#2582 + static_assert(!std::is_lvalue_reference<incomplete_type>::value, ""); } 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 6f546efdf51e1..a895a8d447b66 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 @@ -48,6 +48,8 @@ class Class { }; +struct incomplete_type; + int main() { test_member_function_pointer<void (Class::*)()>(); @@ -133,4 +135,7 @@ int main() test_member_function_pointer<void (Class::*)(int,...) const volatile &&>(); test_member_function_pointer<void (Class::*)(int, char,...) const volatile &&>(); #endif + +// LWG#2582 + static_assert(!std::is_member_function_pointer<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp index e13e58632a325..b0edea37e8e89 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp @@ -48,6 +48,8 @@ class Class { }; +struct incomplete_type; + int main() { test_member_function_pointer<void (Class::*)()>(); @@ -73,4 +75,7 @@ int main() test_member_function_pointer<void (Class::*)(...) volatile>(); test_member_function_pointer<void (Class::*)(int, ...) volatile>(); test_member_function_pointer<void (Class::*)(int, char, ...) volatile>(); + +// LWG#2582 + static_assert(!std::is_member_function_pointer<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_object_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_object_pointer.pass.cpp index 4e6699cc3e7c0..76deef4291e71 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_object_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_object_pointer.pass.cpp @@ -12,12 +12,13 @@ // member_object_pointer #include <type_traits> +#include "test_macros.h" template <class T> void test_member_object_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, ""); @@ -47,7 +48,12 @@ class Class { }; +struct incomplete_type; + int main() { test_member_object_pointer<int Class::*>(); + +// LWG#2582 + static_assert(!std::is_member_object_pointer<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/nullptr.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/nullptr.pass.cpp index 1c7a32fc9dc97..076204c9c094e 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/nullptr.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/nullptr.pass.cpp @@ -14,8 +14,9 @@ #include <type_traits> #include <cstddef> // for std::nullptr_t +#include "test_macros.h" -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 template <class T> void test_nullptr_imp() { @@ -44,9 +45,14 @@ void test_nullptr() test_nullptr_imp<const volatile T>(); } +struct incomplete_type; + int main() { test_nullptr<std::nullptr_t>(); + +// LWG#2582 + static_assert(!std::is_null_pointer<incomplete_type>::value, ""); } #else int main() {} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/pointer.pass.cpp index 7073c106b44b7..f9c83c67d2195 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/pointer.pass.cpp @@ -12,12 +12,14 @@ // pointer #include <type_traits> +#include "test_macros.h" + template <class T> void test_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, ""); @@ -43,10 +45,15 @@ void test_pointer() test_pointer_imp<const volatile T>(); } +struct incomplete_type; + int main() { test_pointer<void*>(); test_pointer<int*>(); test_pointer<const int*>(); test_pointer<void (*)(int)>(); + +// LWG#2582 + static_assert(!std::is_pointer<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/rvalue_ref.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/rvalue_ref.pass.cpp index 7964424036348..99fd2887981f9 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/rvalue_ref.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/rvalue_ref.pass.cpp @@ -12,12 +12,13 @@ // rvalue_ref #include <type_traits> +#include "test_macros.h" template <class T> void test_rvalue_ref() { 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, ""); @@ -34,10 +35,15 @@ void test_rvalue_ref() static_assert(!std::is_function<T>::value, ""); } +struct incomplete_type; + int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES test_rvalue_ref<int&&>(); test_rvalue_ref<const int&&>(); + +// LWG#2582 + static_assert(!std::is_rvalue_reference<incomplete_type>::value, ""); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/union.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/union.pass.cpp index 6cabb717c0c68..36ad00400d359 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/union.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/union.pass.cpp @@ -12,12 +12,13 @@ // union #include <type_traits> +#include "test_macros.h" template <class T> void test_union_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, ""); @@ -49,7 +50,12 @@ union Union double __; }; +struct incomplete_type; + int main() { test_union<Union>(); + +// LWG#2582 + static_assert(!std::is_union<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/void.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/void.pass.cpp index f20bcf87ea150..c7597eb4eaf77 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/void.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/void.pass.cpp @@ -12,12 +12,13 @@ // void #include <type_traits> +#include "test_macros.h" template <class T> void test_void_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, ""); @@ -43,7 +44,12 @@ void test_void() test_void_imp<const volatile T>(); } +struct incomplete_type; + int main() { test_void<void>(); + +// LWG#2582 + static_assert(!std::is_void<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/array.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/array.pass.cpp index 3476d5ceea2ba..f601bd12cadbd 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/array.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/array.pass.cpp @@ -38,9 +38,12 @@ typedef char array[3]; typedef const char const_array[3]; typedef char incomplete_array[]; +class incomplete_type; + int main() { test_array<array>(); test_array<const_array>(); test_array<incomplete_array>(); + test_array<incomplete_type[]>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/class.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/class.pass.cpp index 49e41380ca273..5fa5da12aef8a 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/class.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/class.pass.cpp @@ -38,7 +38,10 @@ class Class { }; +class incomplete_type; + int main() { test_class<Class>(); + test_class<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_arithmetic.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_arithmetic.pass.cpp index a3f18d52a7067..02c539712c653 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_arithmetic.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_arithmetic.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_arithmetic() #endif } +class incomplete_type; + class Empty { }; @@ -98,6 +100,7 @@ int main() test_is_not_arithmetic<Enum>(); test_is_not_arithmetic<FunctionPtr>(); test_is_not_arithmetic<Empty>(); + test_is_not_arithmetic<incomplete_type>(); test_is_not_arithmetic<bit_zero>(); test_is_not_arithmetic<NotEmpty>(); test_is_not_arithmetic<Abstract>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_compound.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_compound.pass.cpp index 6a1798ab5adc2..d8d5162c1a02b 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_compound.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_compound.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_compound() #endif } +class incomplete_type; + class Empty { }; @@ -81,6 +83,7 @@ int main() test_is_compound<int&&>(); test_is_compound<Union>(); test_is_compound<Empty>(); + test_is_compound<incomplete_type>(); test_is_compound<bit_zero>(); test_is_compound<int*>(); test_is_compound<const int*>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_fundamental.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_fundamental.pass.cpp index e16337e05f1ce..f776196dd7a98 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_fundamental.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_fundamental.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_fundamental() #endif } +class incomplete_type; + class Empty { }; @@ -94,7 +96,7 @@ int main() test_is_fundamental<long double>(); test_is_fundamental<char16_t>(); test_is_fundamental<char32_t>(); - + test_is_not_fundamental<char[3]>(); test_is_not_fundamental<char[]>(); test_is_not_fundamental<void *>(); @@ -103,6 +105,7 @@ int main() test_is_not_fundamental<int&&>(); test_is_not_fundamental<Union>(); test_is_not_fundamental<Empty>(); + test_is_not_fundamental<incomplete_type>(); test_is_not_fundamental<bit_zero>(); test_is_not_fundamental<int*>(); test_is_not_fundamental<const int*>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_member_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_member_pointer.pass.cpp index 890da659e2180..c2804885ac50b 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_member_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_member_pointer.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_member_pointer() #endif } +class incomplete_type; + class Empty { }; @@ -73,9 +75,9 @@ typedef void (*FunctionPtr)(); int main() { -// Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), -// std::nullptr_t, and cv-qualified versions of these types (3.9.3) -// are collectively called scalar types. +// Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), +// std::nullptr_t, and cv-qualified versions of these types (3.9.3) +// are collectively called scalar types. test_is_member_pointer<int Empty::*>(); test_is_member_pointer<void (Empty::*)(int)>(); @@ -93,6 +95,7 @@ int main() test_is_not_member_pointer<char[]>(); test_is_not_member_pointer<Union>(); test_is_not_member_pointer<Empty>(); + test_is_not_member_pointer<incomplete_type>(); test_is_not_member_pointer<bit_zero>(); test_is_not_member_pointer<NotEmpty>(); test_is_not_member_pointer<Abstract>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_object.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_object.pass.cpp index ff7dda30d111c..311215b816438 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_object.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_object.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_object() #endif } +class incomplete_type; + class Empty { }; @@ -73,7 +75,7 @@ typedef void (*FunctionPtr)(); int main() { -// An object type is a (possibly cv-qualified) type that is not a function type, +// An object type is a (possibly cv-qualified) type that is not a function type, // not a reference type, and not a void type. test_is_object<std::nullptr_t>(); @@ -86,8 +88,8 @@ int main() test_is_object<int*>(); test_is_object<const int*>(); test_is_object<Enum>(); - test_is_object<Empty>(); - test_is_object<bit_zero>(); + test_is_object<incomplete_type>(); + test_is_object<bit_zero>(); test_is_object<NotEmpty>(); test_is_object<Abstract>(); test_is_object<FunctionPtr>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_reference.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_reference.pass.cpp index e56c8f7618147..b546458bdcb82 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_reference.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_reference.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_reference() #endif } +class incomplete_type; + class Empty { }; @@ -87,6 +89,7 @@ int main() test_is_not_reference<void *>(); test_is_not_reference<FunctionPtr>(); test_is_not_reference<Union>(); + test_is_not_reference<incomplete_type>(); test_is_not_reference<Empty>(); test_is_not_reference<bit_zero>(); test_is_not_reference<int*>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_scalar.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_scalar.pass.cpp index 2b412a68833bf..39ac07ad4bc51 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_scalar.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_scalar.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_scalar() #endif } +class incomplete_type; + class Empty { }; @@ -73,9 +75,9 @@ typedef void (*FunctionPtr)(); int main() { -// Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), -// std::nullptr_t, and cv-qualified versions of these types (3.9.3) -// are collectively called scalar types. +// Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), +// std::nullptr_t, and cv-qualified versions of these types (3.9.3) +// are collectively called scalar types. test_is_scalar<std::nullptr_t>(); test_is_scalar<short>(); @@ -104,6 +106,7 @@ int main() test_is_not_scalar<char[]>(); test_is_not_scalar<Union>(); test_is_not_scalar<Empty>(); + test_is_not_scalar<incomplete_type>(); test_is_not_scalar<bit_zero>(); test_is_not_scalar<NotEmpty>(); test_is_not_scalar<Abstract>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/has_virtual_destructor.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/has_virtual_destructor.pass.cpp index 36020139ec586..7330f4b351258 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/has_virtual_destructor.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/has_virtual_destructor.pass.cpp @@ -13,6 +13,8 @@ #include <type_traits> +#include "test_macros.h" + template <class T> void test_has_virtual_destructor() { 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 c0f6bb9bdfafc..b734a1aa60d86 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 @@ -77,7 +77,7 @@ int main() 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_const.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_const.pass.cpp index 7f63ae40aca78..616f25180a600 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_const.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_const.pass.cpp @@ -29,6 +29,8 @@ void test_is_const() #endif } +struct A; // incomplete + int main() { test_is_const<void>(); @@ -39,6 +41,8 @@ int main() test_is_const<char[3]>(); test_is_const<char[]>(); + test_is_const<A>(); + static_assert(!std::is_const<int&>::value, ""); static_assert(!std::is_const<const int&>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp index 5401d95532b1d..9f8fdc7fc6357 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp @@ -8,6 +8,8 @@ //===----------------------------------------------------------------------===// // type_traits +// XFAIL: apple-clang-6.0 +// The Apple-6 compiler gets is_constructible<void ()> wrong. // template <class T, class... Args> // struct is_constructible; @@ -19,7 +21,7 @@ struct A { explicit A(int); A(int, double); -#if __has_feature(cxx_access_control_sfinae) +#if TEST_STD_VER >= 11 private: #endif A(char); @@ -89,7 +91,7 @@ int main() test_is_constructible<int&, int&> (); test_is_not_constructible<A> (); -#if __has_feature(cxx_access_control_sfinae) +#if TEST_STD_VER >= 11 test_is_not_constructible<A, char> (); #else test_is_constructible<A, char> (); @@ -99,4 +101,13 @@ int main() test_is_not_constructible<int&> (); test_is_not_constructible<Abstract> (); test_is_not_constructible<AbstractDestructor> (); + +// LWG 2560 -- postpone this test until bots updated +// test_is_not_constructible<void()> (); +#if TEST_STD_VER > 11 +// test_is_not_constructible<void() const> (); +// test_is_not_constructible<void() volatile> (); +// test_is_not_constructible<void() &> (); +// test_is_not_constructible<void() &&> (); +#endif } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp index 421f865a623c4..ac8b80bbd3a4d 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp @@ -79,7 +79,7 @@ int main() test_is_not_copy_assignable<int[]> (); test_is_not_copy_assignable<int[3]> (); #endif -#if __has_feature(cxx_access_control_sfinae) +#if TEST_STD_VER >= 11 test_is_not_copy_assignable<B> (); #endif test_is_not_copy_assignable<void> (); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_constructible.pass.cpp index fe2e01429b22b..684d85d3d40ce 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_constructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_constructible.pass.cpp @@ -89,7 +89,7 @@ int main() test_is_not_copy_constructible<void>(); test_is_not_copy_constructible<Abstract>(); test_is_not_copy_constructible<C>(); -#if __has_feature(cxx_access_control_sfinae) +#if TEST_STD_VER >= 11 test_is_not_copy_constructible<B>(); #endif } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_default_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_default_constructible.pass.cpp index 7b46eeaab66b9..318147e5d4a34 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_default_constructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_default_constructible.pass.cpp @@ -100,7 +100,7 @@ int main() test_is_not_default_constructible<char[]>(); test_is_not_default_constructible<Abstract>(); test_is_not_default_constructible<NoDefaultConstructor>(); -#if __has_feature(cxx_access_control_sfinae) +#if TEST_STD_VER >= 11 test_is_not_default_constructible<B>(); #endif } 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 60d607aba61c3..5e8bfeaa41d28 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 @@ -11,9 +11,15 @@ // is_destructible +// Prevent warning when testing the Abstract test type. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor" +#endif + #include <type_traits> #include "test_macros.h" + template <class T> void test_is_destructible() { diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_final.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_final.pass.cpp index baf85e3e81395..5a440598bb020 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_final.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_final.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // type_traits // is_final @@ -14,8 +15,6 @@ #include <type_traits> #include "test_macros.h" -#if _LIBCPP_STD_VER > 11 - struct P final { }; union U1 { }; union U2 final { }; @@ -54,13 +53,10 @@ int main () { test_is_not_final<int>(); test_is_not_final<int*>(); - test_is_final <P>(); - test_is_not_final<P*>(); + test_is_final <P>(); + test_is_not_final<P*>(); test_is_not_final<U1>(); test_is_not_final<U1*>(); - test_is_final <U2>(); - test_is_not_final<U2*>(); + test_is_final <U2>(); + test_is_not_final<U2*>(); } -#else -int main () {} -#endif diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp index c778a5d24b2e6..8200b468fe3a4 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp @@ -107,7 +107,7 @@ int main() #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES test_is_nothrow_constructible<Tuple &&, Empty> (); // See bug #19616. #endif - + test_is_not_nothrow_constructible<A, int> (); test_is_not_nothrow_constructible<A, int, double> (); test_is_not_nothrow_constructible<A> (); 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 42c9807efa833..58e0e0f98b580 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 @@ -11,6 +11,11 @@ // is_nothrow_destructible +// Prevent warning when testing the Abstract test type. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor" +#endif + #include <type_traits> #include "test_macros.h" diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp new file mode 100644 index 0000000000000..7510b4e7293c9 --- /dev/null +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// type_traits + +// is_swappable + +#include <type_traits> +#include <vector> +#include "test_macros.h" + +namespace MyNS { + +// Make the test types non-copyable so that generic std::swap is not valid. +struct A { + A(A const&) = delete; + A& operator=(A const&) = delete; +}; + +struct B { + B(B const&) = delete; + B& operator=(B const&) = delete; +}; + +void swap(A&, A&) noexcept {} +void swap(B&, B&) {} + +struct M { + M(M const&) = delete; + M& operator=(M const&) = delete; +}; + +void swap(M&&, M&&) noexcept {} + +struct ThrowingMove { + ThrowingMove(ThrowingMove&&) {} + ThrowingMove& operator=(ThrowingMove&&) { return *this; } +}; + +} // namespace MyNS + +int main() +{ + using namespace MyNS; + { + // Test that is_swappable applies an lvalue reference to the type. + static_assert(std::is_nothrow_swappable<int>::value, ""); + static_assert(std::is_nothrow_swappable<int&>::value, ""); + static_assert(!std::is_nothrow_swappable<M>::value, ""); + static_assert(!std::is_nothrow_swappable<M&&>::value, ""); + } + { + // Test that it correctly deduces the noexcept of swap. + static_assert(std::is_nothrow_swappable<A>::value, ""); + static_assert(!std::is_nothrow_swappable<B>::value + && std::is_swappable<B>::value, ""); + static_assert(!std::is_nothrow_swappable<ThrowingMove>::value + && std::is_swappable<ThrowingMove>::value, ""); + } + { + // Test that it doesn't drop the qualifiers + static_assert(!std::is_nothrow_swappable<const A>::value, ""); + } + { + // test non-referenceable types + static_assert(!std::is_nothrow_swappable<void>::value, ""); + static_assert(!std::is_nothrow_swappable<int() const>::value, ""); + static_assert(!std::is_nothrow_swappable<int(int, ...) const &>::value, ""); + } + { + // test for presence of is_nothrow_swappable_v + static_assert(std::is_nothrow_swappable_v<int>, ""); + static_assert(!std::is_nothrow_swappable_v<void>, ""); + } +} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp new file mode 100644 index 0000000000000..408231f6057f8 --- /dev/null +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.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, c++14 + +// type_traits + +// is_nothrow_swappable_with + +#include <type_traits> +#include <vector> +#include "test_macros.h" + +namespace MyNS { + +struct A { + A(A const&) = delete; + A& operator=(A const&) = delete; +}; + +struct B { + B(B const&) = delete; + B& operator=(B const&) = delete; +}; + +struct C {}; +struct D {}; + +void swap(A&, A&) {} + +void swap(A&, B&) noexcept {} +void swap(B&, A&) noexcept {} + +void swap(A&, C&) noexcept {} +void swap(C&, A&) {} + +struct M {}; + +void swap(M&&, M&&) noexcept {} + +} // namespace MyNS + +int main() +{ + using namespace MyNS; + { + // Test that is_swappable_with doesn't apply an lvalue reference + // to the type. Instead it is up to the user. + static_assert(!std::is_nothrow_swappable_with<int, int>::value, ""); + static_assert(std::is_nothrow_swappable_with<int&, int&>::value, ""); + static_assert(std::is_nothrow_swappable_with<M, M>::value, ""); + static_assert(std::is_swappable_with<A&, A&>::value && + !std::is_nothrow_swappable_with<A&, A&>::value, ""); + } + { + // test that hetrogenius swap is allowed only if both 'swap(A, B)' and + // 'swap(B, A)' are valid. + static_assert(std::is_nothrow_swappable_with<A&, B&>::value, ""); + static_assert(!std::is_nothrow_swappable_with<A&, C&>::value && + std::is_swappable_with<A&, C&>::value, ""); + static_assert(!std::is_nothrow_swappable_with<D&, C&>::value, ""); + } + { + // test we guard against cv void inputs as required. + static_assert(!std::is_nothrow_swappable_with_v<void, int>, ""); + static_assert(!std::is_nothrow_swappable_with_v<int, void>, ""); + static_assert(!std::is_nothrow_swappable_with_v<const void, const volatile void>, ""); + + } + { + // test for presence of is_nothrow_swappable_with_v + static_assert(std::is_nothrow_swappable_with_v<int&, int&>, ""); + static_assert(!std::is_nothrow_swappable_with_v<int&&, int&&>, ""); + } +} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp index b66e7a296f39a..6ce1c03775262 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp @@ -65,7 +65,7 @@ class Abstract virtual ~Abstract() = 0; }; -#if __has_feature(cxx_attributes) +#if TEST_STD_VER >= 11 class Final final { }; #else diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_signed.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_signed.pass.cpp index 94bf7fb580412..745efd00895c8 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_signed.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_signed.pass.cpp @@ -50,6 +50,8 @@ public: ~Class(); }; +struct A; // incomplete + int main() { test_is_not_signed<void>(); @@ -61,6 +63,7 @@ int main() test_is_not_signed<char[]>(); test_is_not_signed<bool>(); test_is_not_signed<unsigned>(); + test_is_not_signed<A>(); test_is_signed<int>(); test_is_signed<double>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp new file mode 100644 index 0000000000000..b17ca76fd5869 --- /dev/null +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// type_traits + +// is_swappable + +#include <type_traits> +#include <utility> +#include <vector> +#include "test_macros.h" + +namespace MyNS { + +// Make the test types non-copyable so that generic std::swap is not valid. +struct A { + A(A const&) = delete; + A& operator=(A const&) = delete; +}; + +struct B { + B(B const&) = delete; + B& operator=(B const&) = delete; +}; + +struct C {}; +struct D {}; + +void swap(A&, A&) {} + +void swap(A&, B&) {} +void swap(B&, A&) {} + +void swap(A&, C&) {} // missing swap(C, A) +void swap(D&, C&) {} + +struct M { + M(M const&) = delete; + M& operator=(M const&) = delete; +}; + +void swap(M&&, M&&) {} + +struct DeletedSwap { + friend void swap(DeletedSwap&, DeletedSwap&) = delete; +}; + +} // namespace MyNS + +namespace MyNS2 { + +struct AmbiguousSwap {}; + +template <class T> +void swap(T&, T&) {} + +} // end namespace MyNS2 + +int main() +{ + using namespace MyNS; + { + // Test that is_swappable applies an lvalue reference to the type. + static_assert(std::is_swappable<A>::value, ""); + static_assert(std::is_swappable<A&>::value, ""); + static_assert(!std::is_swappable<M>::value, ""); + static_assert(!std::is_swappable<M&&>::value, ""); + } + static_assert(!std::is_swappable<B>::value, ""); + static_assert(std::is_swappable<C>::value, ""); + { + // test non-referencable types + static_assert(!std::is_swappable<void>::value, ""); + static_assert(!std::is_swappable<int() const>::value, ""); + static_assert(!std::is_swappable<int() &>::value, ""); + } + { + // test that a deleted swap is correctly handled. + static_assert(!std::is_swappable<DeletedSwap>::value, ""); + } + { + // test that a swap with ambiguous overloads is handled correctly. + static_assert(!std::is_swappable<MyNS2::AmbiguousSwap>::value, ""); + } + { + // test for presence of is_swappable_v + static_assert(std::is_swappable_v<int>, ""); + static_assert(!std::is_swappable_v<M>, ""); + } +} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp new file mode 100644 index 0000000000000..c3ae1706f0950 --- /dev/null +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.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. +// +//===----------------------------------------------------------------------===// + +// type_traits + +// is_swappable + +// IMPORTANT: The include order is part of the test. We want to pick up +// the following definitions in this order: +// 1) is_swappable, is_nothrow_swappable +// 2) iter_swap, swap_ranges +// 3) swap(T (&)[N], T (&)[N]) +// This test checks that (1) and (2) see forward declarations +// for (3). +#include <type_traits> +#include <algorithm> +#include <utility> + +#include "test_macros.h" + +int main() +{ + // Use a builtin type so we don't get ADL lookup. + typedef double T[17][29]; + { + LIBCPP_STATIC_ASSERT(std::__is_swappable<T>::value, ""); +#if TEST_STD_VER > 14 + static_assert(std::is_swappable_v<T>, ""); +#endif + } + { + T t1 = {}; + T t2 = {}; + std::iter_swap(t1, t2); + std::swap_ranges(t1, t1 + 17, t2); + } +} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp new file mode 100644 index 0000000000000..a049eab9a1923 --- /dev/null +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// type_traits + +// is_swappable_with + +#include <type_traits> +#include <vector> +#include "test_macros.h" + +namespace MyNS { + +struct A { + A(A const&) = delete; + A& operator=(A const&) = delete; +}; + +struct B { + B(B const&) = delete; + B& operator=(B const&) = delete; +}; + +struct C {}; +struct D {}; + +void swap(A&, A&) {} + +void swap(A&, B&) {} +void swap(B&, A&) {} + +void swap(A&, C&) {} // missing swap(C, A) +void swap(D&, C&) {} + +struct M {}; + +void swap(M&&, M&&) {} + +} // namespace MyNS + +int main() +{ + using namespace MyNS; + { + // Test that is_swappable_with doesn't apply an lvalue reference + // to the type. Instead it is up to the user. + static_assert(!std::is_swappable_with<int, int>::value, ""); + static_assert(std::is_swappable_with<int&, int&>::value, ""); + static_assert(std::is_swappable_with<M, M>::value, ""); + static_assert(std::is_swappable_with<A&, A&>::value, ""); + } + { + // test that heterogeneous swap is allowed only if both 'swap(A, B)' and + // 'swap(B, A)' are valid. + static_assert(std::is_swappable_with<A&, B&>::value, ""); + static_assert(!std::is_swappable_with<A&, C&>::value, ""); + static_assert(!std::is_swappable_with<D&, C&>::value, ""); + } + { + // test that cv void is guarded against as required. + static_assert(!std::is_swappable_with_v<void, int>, ""); + static_assert(!std::is_swappable_with_v<int, void>, ""); + static_assert(!std::is_swappable_with_v<const void, const volatile void>, ""); + } + { + // test for presence of is_swappable_with_v + static_assert(std::is_swappable_with_v<int&, int&>, ""); + static_assert(!std::is_swappable_with_v<D&, C&>, ""); + } +} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_assignable.pass.cpp index 3ebb9dba429d0..a9b538b2dffc7 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_assignable.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_assignable.pass.cpp @@ -11,6 +11,8 @@ // is_trivially_assignable +// XFAIL: gcc-4.9 + #include <type_traits> #include "test_macros.h" diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_assignable.pass.cpp index 25429f5470e7b..966573c9f0fe5 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_assignable.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_assignable.pass.cpp @@ -11,6 +11,8 @@ // is_trivially_copy_assignable +// XFAIL: gcc-4.9 + #include <type_traits> #include "test_macros.h" diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_constructible.pass.cpp index 9556959e12621..2922f22766696 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_constructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_constructible.pass.cpp @@ -11,6 +11,8 @@ // is_trivially_copy_constructible +// XFAIL: gcc-4.9 + #include <type_traits> #include "test_macros.h" diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copyable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copyable.pass.cpp index c19a29ffb5869..42ecdb3b896a8 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copyable.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copyable.pass.cpp @@ -11,6 +11,8 @@ // is_trivially_copyable +// XFAIL: gcc-4.9 + #include <type_traits> #include <cassert> #include "test_macros.h" 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 9e2507067d2d3..3372e615d71de 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 @@ -11,6 +11,11 @@ // is_trivially_destructible +// Prevent warning when testing the Abstract test type. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor" +#endif + #include <type_traits> #include "test_macros.h" diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_assignable.pass.cpp index eca596ee1c19e..9a27c73cdfd8b 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_assignable.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_assignable.pass.cpp @@ -11,6 +11,8 @@ // is_trivially_move_assignable +// XFAIL: gcc-4.9 + #include <type_traits> #include "test_macros.h" diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_constructible.pass.cpp index 313da175f7156..941ff31f89da8 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_constructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_constructible.pass.cpp @@ -11,6 +11,8 @@ // is_trivially_move_constructible +// XFAIL: gcc-4.9 + #include <type_traits> #include "test_macros.h" @@ -60,7 +62,7 @@ struct A A(const A&); }; -#if __has_feature(cxx_defaulted_functions) +#if TEST_STD_VER >= 11 struct MoveOnly1 { @@ -89,7 +91,7 @@ int main() test_is_trivially_move_constructible<const int*>(); test_is_trivially_move_constructible<bit_zero>(); -#if __has_feature(cxx_defaulted_functions) +#if TEST_STD_VER >= 11 static_assert(!std::is_trivially_move_constructible<MoveOnly1>::value, ""); static_assert( std::is_trivially_move_constructible<MoveOnly2>::value, ""); #endif diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_unsigned.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_unsigned.pass.cpp index 9ca42432df169..376c7e005ce9e 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_unsigned.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_unsigned.pass.cpp @@ -50,6 +50,8 @@ public: ~Class(); }; +struct A; // incomplete + int main() { test_is_not_unsigned<void>(); @@ -61,6 +63,7 @@ int main() test_is_not_unsigned<char[]>(); test_is_not_unsigned<int>(); test_is_not_unsigned<double>(); + test_is_not_unsigned<A>(); test_is_unsigned<bool>(); test_is_unsigned<unsigned>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_volatile.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_volatile.pass.cpp index 36697a3f3eba0..cc8d66ae6888c 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_volatile.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_volatile.pass.cpp @@ -29,6 +29,8 @@ void test_is_volatile() #endif } +struct A; // incomplete + int main() { test_is_volatile<void>(); @@ -39,6 +41,8 @@ int main() test_is_volatile<char[3]>(); test_is_volatile<char[]>(); + test_is_volatile<A>(); + static_assert(!std::is_volatile<int&>::value, ""); static_assert(!std::is_volatile<volatile int&>::value, ""); } 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 9411435e29e87..ab623bb01f789 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 @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: libcpp-no-exceptions // template <class charT> // explicit bitset(const charT* str, // typename basic_string<charT>::size_type n = basic_string<charT>::npos, @@ -18,20 +17,19 @@ #include <algorithm> // for 'min' and 'max' #include <stdexcept> // for 'invalid_argument' -#pragma clang diagnostic ignored "-Wtautological-compare" +#include "test_macros.h" template <std::size_t N> void test_char_pointer_ctor() { { - try - { - std::bitset<N> v("xxx1010101010xxxx"); - assert(false); - } - catch (std::invalid_argument&) - { - } +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + std::bitset<N> v("xxx1010101010xxxx"); + assert(false); + } + catch (std::invalid_argument&) {} +#endif } { diff --git a/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp b/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp index bd5ca7e08b2ab..f4f8d390de08f 100644 --- a/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp @@ -12,19 +12,26 @@ #include <bitset> #include <cassert> -#pragma clang diagnostic ignored "-Wtautological-compare" +#include "test_macros.h" template <std::size_t N> void test_default_ctor() { { - _LIBCPP_CONSTEXPR std::bitset<N> v1; - assert(v1.size() == N); - for (std::size_t i = 0; i < N; ++i) - assert(v1[i] == false); + TEST_CONSTEXPR std::bitset<N> v1; + assert(v1.size() == N); + for (std::size_t i = 0; i < N; ++i) + assert(v1[i] == false); } +#if TEST_STD_VER >= 11 + { + constexpr std::bitset<N> v1; + static_assert(v1.size() == N, ""); + } +#endif } + int main() { test_default_ctor<0>(); 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 b08720f57ee36..0e4793027c989 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 @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: libcpp-no-exceptions // test bitset(string, pos, n, zero, one); #include <bitset> @@ -15,65 +14,60 @@ #include <algorithm> // for 'min' and 'max' #include <stdexcept> // for 'invalid_argument' -#pragma clang diagnostic ignored "-Wtautological-compare" +#include "test_macros.h" template <std::size_t N> void test_string_ctor() { +#ifndef TEST_HAS_NO_EXCEPTIONS { - try - { - std::string str("xxx1010101010xxxx"); - std::bitset<N> v(str, str.size()+1, 10); - assert(false); - } - catch (std::out_of_range&) - { - } + try { + std::string str("xxx1010101010xxxx"); + std::bitset<N> v(str, str.size()+1, 10); + assert(false); + } + catch (std::out_of_range&) + { + } } - - { - try { - std::string str("xxx1010101010xxxx"); - std::bitset<N> v(str, 2, 10); - assert(false); + try { + std::string str("xxx1010101010xxxx"); + std::bitset<N> v(str, 2, 10); + assert(false); + } + catch (std::invalid_argument&) + { + } } - catch (std::invalid_argument&) { + try { + std::string str("xxxbababababaxxxx"); + std::bitset<N> v(str, 2, 10, 'a', 'b'); + assert(false); + } + catch (std::invalid_argument&) + { + } } - } - +#endif // TEST_HAS_NO_EXCEPTIONS { - std::string str("xxx1010101010xxxx"); - std::bitset<N> v(str, 3, 10); - std::size_t M = std::min<std::size_t>(N, 10); - for (std::size_t i = 0; i < M; ++i) - assert(v[i] == (str[3 + M - 1 - i] == '1')); - for (std::size_t i = 10; i < N; ++i) - assert(v[i] == false); + std::string str("xxx1010101010xxxx"); + std::bitset<N> v(str, 3, 10); + std::size_t M = std::min<std::size_t>(N, 10); + for (std::size_t i = 0; i < M; ++i) + assert(v[i] == (str[3 + M - 1 - i] == '1')); + for (std::size_t i = 10; i < N; ++i) + assert(v[i] == false); } - - { - try { std::string str("xxxbababababaxxxx"); - std::bitset<N> v(str, 2, 10, 'a', 'b'); - assert(false); - } - catch (std::invalid_argument&) - { - } - } - - { - std::string str("xxxbababababaxxxx"); - std::bitset<N> v(str, 3, 10, 'a', 'b'); - std::size_t M = std::min<std::size_t>(N, 10); - for (std::size_t i = 0; i < M; ++i) - assert(v[i] == (str[3 + M - 1 - i] == 'b')); - for (std::size_t i = 10; i < N; ++i) - assert(v[i] == false); + std::bitset<N> v(str, 3, 10, 'a', 'b'); + std::size_t M = std::min<std::size_t>(N, 10); + for (std::size_t i = 0; i < M; ++i) + assert(v[i] == (str[3 + M - 1 - i] == 'b')); + for (std::size_t i = 10; i < N; ++i) + assert(v[i] == false); } } 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 f232447e08c3a..1b121c5fb9280 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 @@ -13,20 +13,26 @@ #include <cassert> #include <algorithm> // for 'min' and 'max' -#pragma clang diagnostic ignored "-Wtautological-compare" +#include "test_macros.h" template <std::size_t N> void test_val_ctor() { { - _LIBCPP_CONSTEXPR std::bitset<N> v(0xAAAAAAAAAAAAAAAAULL); - assert(v.size() == N); - unsigned M = std::min<std::size_t>(N, 64); - for (std::size_t i = 0; i < M; ++i) - assert(v[i] == (i & 1)); - for (std::size_t i = M; i < N; ++i) - assert(v[i] == false); + TEST_CONSTEXPR std::bitset<N> v(0xAAAAAAAAAAAAAAAAULL); + assert(v.size() == N); + unsigned M = std::min<std::size_t>(N, 64); + for (std::size_t i = 0; i < M; ++i) + assert(v[i] == (i & 1)); + for (std::size_t i = M; i < N; ++i) + assert(v[i] == false); } +#if TEST_STD_VER >= 11 + { + constexpr std::bitset<N> v(0xAAAAAAAAAAAAAAAAULL); + static_assert(v.size() == N, ""); + } +#endif } int main() diff --git a/test/std/utilities/template.bitset/bitset.hash/bitset.pass.cpp b/test/std/utilities/template.bitset/bitset.hash/bitset.pass.cpp index 520f2e8757c27..bc65078911b2c 100644 --- a/test/std/utilities/template.bitset/bitset.hash/bitset.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.hash/bitset.pass.cpp @@ -16,12 +16,12 @@ // size_t operator()(T val) const; // }; -// Not very portable - #include <bitset> #include <cassert> #include <type_traits> +#include "test_macros.h" + template <std::size_t N> void test() @@ -32,7 +32,9 @@ test() static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" ); H h; T bs(static_cast<unsigned long long>(N)); - assert(h(bs) == N); + const std::size_t result = h(bs); + LIBCPP_ASSERT(result == N); + ((void)result); // Prevent unused warning } int main() diff --git a/test/std/utilities/template.bitset/bitset.members/count.pass.cpp b/test/std/utilities/template.bitset/bitset.members/count.pass.cpp index fb9ce6422997a..c8a14c9b60496 100644 --- a/test/std/utilities/template.bitset/bitset.members/count.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/count.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp b/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp index 6c4f5c699850e..a25e5bd9da220 100644 --- a/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp b/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp index cffca68fb1ea6..88ce8e943caf1 100644 --- a/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp @@ -14,8 +14,6 @@ #include <cstdlib> #include <cassert> -#pragma clang diagnostic ignored "-Wtautological-compare" - template <std::size_t N> std::bitset<N> make_bitset() diff --git a/test/std/utilities/template.bitset/bitset.members/index.pass.cpp b/test/std/utilities/template.bitset/bitset.members/index.pass.cpp index b96aaa51ab8fc..02e58a7890c54 100644 --- a/test/std/utilities/template.bitset/bitset.members/index.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/index.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp b/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp index e3c28c6935767..870a504c2d751 100644 --- a/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp b/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp index 7fe9fa72e9243..57b77d2570d54 100644 --- a/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp b/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp index bed3e28ece818..3adab77b4131f 100644 --- a/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/not_all.pass.cpp b/test/std/utilities/template.bitset/bitset.members/not_all.pass.cpp index 2f8f7111f5a13..d9fbb3e11dad8 100644 --- a/test/std/utilities/template.bitset/bitset.members/not_all.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/not_all.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp b/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp index b599ec398b309..64ca15fda137d 100644 --- a/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/op_eq_eq.pass.cpp b/test/std/utilities/template.bitset/bitset.members/op_eq_eq.pass.cpp index 5f6cf3d0a30c1..24761c628c03e 100644 --- a/test/std/utilities/template.bitset/bitset.members/op_eq_eq.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/op_eq_eq.pass.cpp @@ -16,7 +16,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp b/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp index 6e63879890a64..f2880f67ab6e6 100644 --- a/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/op_xor_eq.pass.cpp b/test/std/utilities/template.bitset/bitset.members/op_xor_eq.pass.cpp index e68a641cadc66..420996759d0d7 100644 --- a/test/std/utilities/template.bitset/bitset.members/op_xor_eq.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/op_xor_eq.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/reset_all.pass.cpp b/test/std/utilities/template.bitset/bitset.members/reset_all.pass.cpp index ee44d92c43b8e..eed25e27448df 100644 --- a/test/std/utilities/template.bitset/bitset.members/reset_all.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/reset_all.pass.cpp @@ -12,7 +12,9 @@ #include <bitset> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> void test_reset_all() diff --git a/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp b/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp index 6de256b00cc55..f01d35b9a33c3 100644 --- a/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp @@ -13,9 +13,6 @@ #include <bitset> #include <cassert> -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wtautological-compare" - template <std::size_t N> void test_reset_one() { diff --git a/test/std/utilities/template.bitset/bitset.members/right_shift.pass.cpp b/test/std/utilities/template.bitset/bitset.members/right_shift.pass.cpp index 87fcc281fa26e..180fa84f4488b 100644 --- a/test/std/utilities/template.bitset/bitset.members/right_shift.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/right_shift.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp b/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp index 1dd89c1844b94..47494fc459a50 100644 --- a/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/set_all.pass.cpp b/test/std/utilities/template.bitset/bitset.members/set_all.pass.cpp index 56454a84f1135..e5c3e25352cc4 100644 --- a/test/std/utilities/template.bitset/bitset.members/set_all.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/set_all.pass.cpp @@ -12,7 +12,9 @@ #include <bitset> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> void test_set_all() diff --git a/test/std/utilities/template.bitset/bitset.members/test.pass.cpp b/test/std/utilities/template.bitset/bitset.members/test.pass.cpp index ce594d0ae891b..161afd11c291d 100644 --- a/test/std/utilities/template.bitset/bitset.members/test.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/test.pass.cpp @@ -14,8 +14,6 @@ #include <cstdlib> #include <cassert> -#pragma clang diagnostic ignored "-Wtautological-compare" - template <std::size_t N> std::bitset<N> make_bitset() diff --git a/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp b/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp index b65794097470f..5b2958cca5239 100644 --- a/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp @@ -26,7 +26,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp b/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp index 751cee69102a3..80792d919ccfd 100644 --- a/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp b/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp index fda5e5cda8eea..65a7004acb86d 100644 --- a/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp b/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp index 067f868215be9..dcabaa4a9a4d4 100644 --- a/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/time/date.time/ctime.pass.cpp b/test/std/utilities/time/date.time/ctime.pass.cpp index d0a838e0c2714..b9e19af32952e 100644 --- a/test/std/utilities/time/date.time/ctime.pass.cpp +++ b/test/std/utilities/time/date.time/ctime.pass.cpp @@ -21,11 +21,15 @@ int main() { std::clock_t c = 0; - ((void)c); // avoid unused warning std::size_t s = 0; std::time_t t = 0; - std::tm tm = {0}; + std::tm tm = {}; char str[3]; + ((void)c); // Prevent unused warning + ((void)s); // Prevent unused warning + ((void)t); // Prevent unused warning + ((void)tm); // Prevent unused warning + ((void)str); // Prevent unused warning static_assert((std::is_same<decltype(std::clock()), std::clock_t>::value), ""); 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), ""); diff --git a/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp index 2e3acbc52b115..b6b3aeea94f85 100644 --- a/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp +++ b/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp @@ -12,6 +12,10 @@ // XFAIL: with_system_cxx_lib=x86_64-apple-darwin11 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin12 +// Due to C++17 inline variables ASAN flags this test as containing an ODR +// violation because Clock::is_steady is defined in both the dylib and this TU. +// UNSUPPORTED: asan + // <chrono> // high_resolution_clock diff --git a/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp index 0e0b83b2f2440..6302ce6efb34b 100644 --- a/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp +++ b/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp @@ -13,6 +13,10 @@ // XFAIL: with_system_cxx_lib=x86_64-apple-darwin12 // UNSUPPORTED: libcpp-has-no-monotonic-clock +// Due to C++17 inline variables ASAN flags this test as containing an ODR +// violation because Clock::is_steady is defined in both the dylib and this TU. +// UNSUPPORTED: asan + // <chrono> // steady_clock diff --git a/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp index e277d4e67dc7a..cfbe9bd570329 100644 --- a/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp +++ b/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp @@ -12,6 +12,10 @@ // XFAIL: with_system_cxx_lib=x86_64-apple-darwin11 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin12 +// Due to C++17 inline variables ASAN flags this test as containing an ODR +// violation because Clock::is_steady is defined in both the dylib and this TU. +// UNSUPPORTED: asan + // <chrono> // system_clock diff --git a/test/std/utilities/time/time.duration/time.duration.alg/abs.pass.cpp b/test/std/utilities/time/time.duration/time.duration.alg/abs.pass.cpp index ec32c37a94232..30ea029b7ef4a 100644 --- a/test/std/utilities/time/time.duration/time.duration.alg/abs.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.alg/abs.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> diff --git a/test/std/utilities/time/time.duration/time.duration.cast/ceil.pass.cpp b/test/std/utilities/time/time.duration/time.duration.cast/ceil.pass.cpp index 6fb73b97db17e..8d7623c85e194 100644 --- a/test/std/utilities/time/time.duration/time.duration.cast/ceil.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.cast/ceil.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> diff --git a/test/std/utilities/time/time.duration/time.duration.cast/floor.pass.cpp b/test/std/utilities/time/time.duration/time.duration.cast/floor.pass.cpp index 57929dd912281..38db42a84cedf 100644 --- a/test/std/utilities/time/time.duration/time.duration.cast/floor.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.cast/floor.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> // floor diff --git a/test/std/utilities/time/time.duration/time.duration.cast/round.pass.cpp b/test/std/utilities/time/time.duration/time.duration.cast/round.pass.cpp index e50b85c991a21..2f9689007dfd9 100644 --- a/test/std/utilities/time/time.duration/time.duration.cast/round.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.cast/round.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> // round diff --git a/test/std/utilities/time/time.duration/time.duration.literals/literals.pass.cpp b/test/std/utilities/time/time.duration/time.duration.literals/literals.pass.cpp index 48324ae836513..d5c0207c0ee76 100644 --- a/test/std/utilities/time/time.duration/time.duration.literals/literals.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.literals/literals.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <chrono> #include <chrono> @@ -15,7 +16,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using namespace std::literals::chrono_literals; // Make sure the types are right @@ -25,12 +25,12 @@ int main() static_assert ( std::is_same<decltype( 3ms ), std::chrono::milliseconds>::value, "" ); static_assert ( std::is_same<decltype( 3us ), std::chrono::microseconds>::value, "" ); static_assert ( std::is_same<decltype( 3ns ), std::chrono::nanoseconds>::value, "" ); - + std::chrono::hours h = 4h; assert ( h == std::chrono::hours(4)); auto h2 = 4.0h; assert ( h == h2 ); - + std::chrono::minutes min = 36min; assert ( min == std::chrono::minutes(36)); auto min2 = 36.0min; @@ -55,5 +55,4 @@ int main() assert ( ns == std::chrono::nanoseconds(645)); auto ns2 = 645.ns; assert ( ns == ns2 ); -#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.literals/literals1.fail.cpp b/test/std/utilities/time/time.duration/time.duration.literals/literals1.fail.cpp index 46aaa30e51e4a..52208cb54d6d8 100644 --- a/test/std/utilities/time/time.duration/time.duration.literals/literals1.fail.cpp +++ b/test/std/utilities/time/time.duration/time.duration.literals/literals1.fail.cpp @@ -7,15 +7,13 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 #include <chrono> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 std::chrono::hours h = 4h; // should fail w/conversion operator not found -#else -#error -#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.literals/literals1.pass.cpp b/test/std/utilities/time/time.duration/time.duration.literals/literals1.pass.cpp index 574f9bcce8741..5e59e1153787d 100644 --- a/test/std/utilities/time/time.duration/time.duration.literals/literals1.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.literals/literals1.pass.cpp @@ -7,19 +7,20 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 #include <chrono> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 using namespace std::chrono; hours h = 4h; assert ( h == hours(4)); auto h2 = 4.0h; assert ( h == h2 ); - + minutes min = 36min; assert ( min == minutes(36)); auto min2 = 36.0min; @@ -44,5 +45,4 @@ int main() assert ( ns == nanoseconds(645)); auto ns2 = 645.ns; assert ( ns == ns2 ); -#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.literals/literals2.fail.cpp b/test/std/utilities/time/time.duration/time.duration.literals/literals2.fail.cpp index 17358e589f4fa..f190d7863066c 100644 --- a/test/std/utilities/time/time.duration/time.duration.literals/literals2.fail.cpp +++ b/test/std/utilities/time/time.duration/time.duration.literals/literals2.fail.cpp @@ -7,16 +7,14 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 #include <chrono> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 using std::chrono::hours; hours foo = 4h; // should fail w/conversion operator not found -#else -#error -#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.literals/literals2.pass.cpp b/test/std/utilities/time/time.duration/time.duration.literals/literals2.pass.cpp index e37bc6e679614..282b1c6572e24 100644 --- a/test/std/utilities/time/time.duration/time.duration.literals/literals2.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.literals/literals2.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <chrono> #include <chrono> @@ -15,14 +16,13 @@ int main() { -#if _LIBCPP_STD_VER > 11 using namespace std::literals; std::chrono::hours h = 4h; assert ( h == std::chrono::hours(4)); auto h2 = 4.0h; assert ( h == h2 ); - + std::chrono::minutes min = 36min; assert ( min == std::chrono::minutes(36)); auto min2 = 36.0min; @@ -47,5 +47,4 @@ int main() assert ( ns == std::chrono::nanoseconds(645)); auto ns2 = 645.ns; assert ( ns == ns2 ); -#endif } diff --git a/test/std/utilities/time/time.point/time.point.cast/ceil.pass.cpp b/test/std/utilities/time/time.point/time.point.cast/ceil.pass.cpp index 379929c7f2d81..e6e7c053885ae 100644 --- a/test/std/utilities/time/time.point/time.point.cast/ceil.pass.cpp +++ b/test/std/utilities/time/time.point/time.point.cast/ceil.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> // ceil diff --git a/test/std/utilities/time/time.point/time.point.cast/floor.pass.cpp b/test/std/utilities/time/time.point/time.point.cast/floor.pass.cpp index d0a908fa932a0..efd2d9e25cd7a 100644 --- a/test/std/utilities/time/time.point/time.point.cast/floor.pass.cpp +++ b/test/std/utilities/time/time.point/time.point.cast/floor.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> // floor diff --git a/test/std/utilities/time/time.point/time.point.cast/round.pass.cpp b/test/std/utilities/time/time.point/time.point.cast/round.pass.cpp index ab8bf3a75e79f..b5d16cf11d98d 100644 --- a/test/std/utilities/time/time.point/time.point.cast/round.pass.cpp +++ b/test/std/utilities/time/time.point/time.point.cast/round.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> // round diff --git a/test/std/utilities/time/time.point/time.point.comparisons/op_equal.pass.cpp b/test/std/utilities/time/time.point/time.point.comparisons/op_equal.pass.cpp index fbd3a1386d35b..a37bb266a0a95 100644 --- a/test/std/utilities/time/time.point/time.point.comparisons/op_equal.pass.cpp +++ b/test/std/utilities/time/time.point/time.point.comparisons/op_equal.pass.cpp @@ -54,7 +54,7 @@ int main() assert(!(t1 == t2)); assert( (t1 != t2)); } - + #if _LIBCPP_STD_VER > 11 { constexpr T1 t1(Duration1(3)); diff --git a/test/std/utilities/time/time.traits/time.traits.is_fp/treat_as_floating_point.pass.cpp b/test/std/utilities/time/time.traits/time.traits.is_fp/treat_as_floating_point.pass.cpp index f9ddc87a7a148..faacb573d74b0 100644 --- a/test/std/utilities/time/time.traits/time.traits.is_fp/treat_as_floating_point.pass.cpp +++ b/test/std/utilities/time/time.traits/time.traits.is_fp/treat_as_floating_point.pass.cpp @@ -14,6 +14,8 @@ #include <chrono> #include <type_traits> +#include "test_macros.h" + template <class T> void test() @@ -21,8 +23,8 @@ test() static_assert((std::is_base_of<std::is_floating_point<T>, std::chrono::treat_as_floating_point<T> >::value), ""); #if TEST_STD_VER > 14 - static_assert((std::is_base_of<std::is_floating_point<T>, - std::chrono::treat_as_floating_point_v<T> >), ""); + static_assert(std::is_floating_point<T>::value == + std::chrono::treat_as_floating_point_v<T>, ""); #endif } diff --git a/test/std/utilities/tuple/tuple.general/tuple.smartptr.pass.cpp b/test/std/utilities/tuple/tuple.general/tuple.smartptr.pass.cpp index 1d8be420d8376..d1b974c50753a 100644 --- a/test/std/utilities/tuple/tuple.general/tuple.smartptr.pass.cpp +++ b/test/std/utilities/tuple/tuple.general/tuple.smartptr.pass.cpp @@ -21,18 +21,13 @@ int main () { std::tuple<std::unique_ptr<char>> up; std::tuple<std::shared_ptr<char>> sp; std::tuple<std::weak_ptr <char>> wp; -// std::tuple<std::auto_ptr <char>> ap; } { std::tuple<std::unique_ptr<char[]>> up; std::tuple<std::shared_ptr<char[]>> sp; std::tuple<std::weak_ptr <char[]>> wp; -// std::tuple<std::auto_ptr <char[]>> ap; } - { - std::tuple<std::unique_ptr<char[5]>> up; - std::tuple<std::shared_ptr<char[5]>> sp; - std::tuple<std::weak_ptr <char[5]>> wp; -// std::tuple<std::auto_ptr <char[5]>> ap; - } -}
\ No newline at end of file + // Smart pointers of type 'T[N]' are not tested here since they are not + // supported by the standard nor by libc++'s implementation. + // See http://reviews.llvm.org/D21320 for more information. +} diff --git a/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp b/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp index df5fdff511e35..ce6dcf811e468 100644 --- a/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp @@ -9,7 +9,9 @@ // This is for bugs 18853 and 19118 -#if __cplusplus >= 201103L +#include "test_macros.h" + +#if TEST_STD_VER >= 11 #include <tuple> #include <functional> diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply.pass.cpp new file mode 100644 index 0000000000000..2e821945d09a1 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply.pass.cpp @@ -0,0 +1,275 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <tuple> + +// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&) + +// Test with different ref/ptr/cv qualified argument types. + +#include <tuple> +#include <array> +#include <utility> +#include <cassert> + +#include "test_macros.h" +#include "type_id.h" + +// std::array is explicitly allowed to be initialized with A a = { init-list };. +// Disable the missing braces warning for this reason. +#include "disable_missing_braces_warning.h" + + +constexpr int constexpr_sum_fn() { return 0; } + +template <class ...Ints> +constexpr int constexpr_sum_fn(int x1, Ints... rest) { return x1 + constexpr_sum_fn(rest...); } + +struct ConstexprSumT { + constexpr ConstexprSumT() = default; + template <class ...Ints> + constexpr int operator()(Ints... values) const { + return constexpr_sum_fn(values...); + } +}; + + +void test_constexpr_evaluation() +{ + constexpr ConstexprSumT sum_obj{}; + { + using Tup = std::tuple<>; + using Fn = int(&)(); + constexpr Tup t; + static_assert(std::apply(static_cast<Fn>(constexpr_sum_fn), t) == 0, ""); + static_assert(std::apply(sum_obj, t) == 0, ""); + } + { + using Tup = std::tuple<int>; + using Fn = int(&)(int); + constexpr Tup t(42); + static_assert(std::apply(static_cast<Fn>(constexpr_sum_fn), t) == 42, ""); + static_assert(std::apply(sum_obj, t) == 42, ""); + } + { + using Tup = std::tuple<int, long>; + using Fn = int(&)(int, int); + constexpr Tup t(42, 101); + static_assert(std::apply(static_cast<Fn>(constexpr_sum_fn), t) == 143, ""); + static_assert(std::apply(sum_obj, t) == 143, ""); + } + { + using Tup = std::pair<int, long>; + using Fn = int(&)(int, int); + constexpr Tup t(42, 101); + static_assert(std::apply(static_cast<Fn>(constexpr_sum_fn), t) == 143, ""); + static_assert(std::apply(sum_obj, t) == 143, ""); + } + { + using Tup = std::tuple<int, long, int>; + using Fn = int(&)(int, int, int); + constexpr Tup t(42, 101, -1); + static_assert(std::apply(static_cast<Fn>(constexpr_sum_fn), t) == 142, ""); + static_assert(std::apply(sum_obj, t) == 142, ""); + } + { + using Tup = std::array<int, 3>; + using Fn = int(&)(int, int, int); + constexpr Tup t = {42, 101, -1}; + static_assert(std::apply(static_cast<Fn>(constexpr_sum_fn), t) == 142, ""); + static_assert(std::apply(sum_obj, t) == 142, ""); + } +} + + +enum CallQuals { + CQ_None, + CQ_LValue, + CQ_ConstLValue, + CQ_RValue, + CQ_ConstRValue +}; + +template <class Tuple> +struct CallInfo { + CallQuals quals; + TypeID const* arg_types; + Tuple args; + + template <class ...Args> + CallInfo(CallQuals q, Args&&... xargs) + : quals(q), arg_types(&makeArgumentID<Args&&...>()), args(std::forward<Args>(xargs)...) + {} +}; + +template <class ...Args> +inline CallInfo<decltype(std::forward_as_tuple(std::declval<Args>()...))> +makeCallInfo(CallQuals quals, Args&&... args) { + return {quals, std::forward<Args>(args)...}; +} + +struct TrackedCallable { + + TrackedCallable() = default; + + template <class ...Args> auto operator()(Args&&... xargs) & + { return makeCallInfo(CQ_LValue, std::forward<Args>(xargs)...); } + + template <class ...Args> auto operator()(Args&&... xargs) const& + { return makeCallInfo(CQ_ConstLValue, std::forward<Args>(xargs)...); } + + template <class ...Args> auto operator()(Args&&... xargs) && + { return makeCallInfo(CQ_RValue, std::forward<Args>(xargs)...); } + + template <class ...Args> auto operator()(Args&&... xargs) const&& + { return makeCallInfo(CQ_ConstRValue, std::forward<Args>(xargs)...); } +}; + +template <class ...ExpectArgs, class Tuple> +void check_apply_quals_and_types(Tuple&& t) { + TypeID const* const expect_args = &makeArgumentID<ExpectArgs...>(); + TrackedCallable obj; + TrackedCallable const& cobj = obj; + { + auto ret = std::apply(obj, std::forward<Tuple>(t)); + assert(ret.quals == CQ_LValue); + assert(ret.arg_types == expect_args); + assert(ret.args == t); + } + { + auto ret = std::apply(cobj, std::forward<Tuple>(t)); + assert(ret.quals == CQ_ConstLValue); + assert(ret.arg_types == expect_args); + assert(ret.args == t); + } + { + auto ret = std::apply(std::move(obj), std::forward<Tuple>(t)); + assert(ret.quals == CQ_RValue); + assert(ret.arg_types == expect_args); + assert(ret.args == t); + } + { + auto ret = std::apply(std::move(cobj), std::forward<Tuple>(t)); + assert(ret.quals == CQ_ConstRValue); + assert(ret.arg_types == expect_args); + assert(ret.args == t); + } +} + +void test_call_quals_and_arg_types() +{ + TrackedCallable obj; + using Tup = std::tuple<int, int const&, unsigned&&>; + const int x = 42; + unsigned y = 101; + Tup t(-1, x, std::move(y)); + Tup const& ct = t; + check_apply_quals_and_types<int&, int const&, unsigned&>(t); + check_apply_quals_and_types<int const&, int const&, unsigned&>(ct); + check_apply_quals_and_types<int&&, int const&, unsigned&&>(std::move(t)); + check_apply_quals_and_types<int const&&, int const&, unsigned&&>(std::move(ct)); +} + + +struct NothrowMoveable { + NothrowMoveable() noexcept = default; + NothrowMoveable(NothrowMoveable const&) noexcept(false) {} + NothrowMoveable(NothrowMoveable&&) noexcept {} +}; + +template <bool IsNoexcept> +struct TestNoexceptCallable { + template <class ...Args> + NothrowMoveable operator()(Args...) const noexcept(IsNoexcept) { return {}; } +}; + +void test_noexcept() +{ + TestNoexceptCallable<true> nec; + TestNoexceptCallable<false> tc; + { + // test that the functions noexcept-ness is propagated + using Tup = std::tuple<int, const char*, long>; + Tup t; + ASSERT_NOEXCEPT(std::apply(nec, t)); + ASSERT_NOT_NOEXCEPT(std::apply(tc, t)); + } + { + // test that the noexcept-ness of the argument conversions is checked. + using Tup = std::tuple<NothrowMoveable, int>; + Tup t; + ASSERT_NOT_NOEXCEPT(std::apply(nec, t)); + ASSERT_NOEXCEPT(std::apply(nec, std::move(t))); + } +} + +namespace ReturnTypeTest { + static int my_int = 42; + + template <int N> struct index {}; + + void f(index<0>) {} + + int f(index<1>) { return 0; } + + int & f(index<2>) { return static_cast<int &>(my_int); } + int const & f(index<3>) { return static_cast<int const &>(my_int); } + int volatile & f(index<4>) { return static_cast<int volatile &>(my_int); } + int const volatile & f(index<5>) { return static_cast<int const volatile &>(my_int); } + + int && f(index<6>) { return static_cast<int &&>(my_int); } + int const && f(index<7>) { return static_cast<int const &&>(my_int); } + int volatile && f(index<8>) { return static_cast<int volatile &&>(my_int); } + int const volatile && f(index<9>) { return static_cast<int const volatile &&>(my_int); } + + int * f(index<10>) { return static_cast<int *>(&my_int); } + int const * f(index<11>) { return static_cast<int const *>(&my_int); } + int volatile * f(index<12>) { return static_cast<int volatile *>(&my_int); } + int const volatile * f(index<13>) { return static_cast<int const volatile *>(&my_int); } + + template <int Func, class Expect> + void test() + { + using RawInvokeResult = decltype(f(index<Func>{})); + static_assert(std::is_same<RawInvokeResult, Expect>::value, ""); + using FnType = RawInvokeResult (*) (index<Func>); + FnType fn = f; + std::tuple<index<Func>> t; ((void)t); + using InvokeResult = decltype(std::apply(fn, t)); + static_assert(std::is_same<InvokeResult, Expect>::value, ""); + } +} // end namespace ReturnTypeTest + +void test_return_type() +{ + using ReturnTypeTest::test; + test<0, void>(); + test<1, int>(); + test<2, int &>(); + test<3, int const &>(); + test<4, int volatile &>(); + test<5, int const volatile &>(); + test<6, int &&>(); + test<7, int const &&>(); + test<8, int volatile &&>(); + test<9, int const volatile &&>(); + test<10, int *>(); + test<11, int const *>(); + test<12, int volatile *>(); + test<13, int const volatile *>(); +} + +int main() { + test_constexpr_evaluation(); + test_call_quals_and_arg_types(); + test_return_type(); + test_noexcept(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply_extended_types.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply_extended_types.pass.cpp new file mode 100644 index 0000000000000..02d7fe43e9cdc --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply_extended_types.pass.cpp @@ -0,0 +1,426 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <tuple> + +// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&) + +// Testing extended function types. The extended function types are those +// named by INVOKE but that are not actual callable objects. These include +// bullets 1-4 of invoke. + +#include <tuple> +#include <array> +#include <utility> +#include <cassert> + +// std::array is explicitly allowed to be initialized with A a = { init-list };. +// Disable the missing braces warning for this reason. +#include "disable_missing_braces_warning.h" + +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; + + +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 == std::apply(mem1, t)); + assert(count == 1); + } + count = 0; + // member function w/pointer + { + T a; + TuplePtr t{&a}; + assert(1 == std::apply(mem1, t)); + assert(count == 1); + } + count = 0; + // member function w/base + { + Base a; + TupleBase t{a}; + assert(1 == std::apply(mem1, t)); + assert(count == 1); + } + count = 0; + // member function w/wrap + { + Wrap a; + TupleWrap t{a}; + assert(1 == std::apply(mem1, t)); + assert(count == 1); + } + count = 0; + // const member function w/ref + { + T const a; + ConstTuple t{a}; + assert(1 == std::apply(mem2, t)); + assert(count == 1); + } + count = 0; + // const member function w/pointer + { + T const a; + ConstTuplePtr t{&a}; + assert(1 == std::apply(mem2, t)); + assert(count == 1); + } + count = 0; + // const member function w/base + { + Base const a; + ConstTupleBase t{a}; + assert(1 == std::apply(mem2, t)); + assert(count == 1); + } + count = 0; + // const member function w/wrapper + { + Wrap const a; + ConstTupleWrap t{a}; + assert(1 == std::apply(mem2, t)); + assert(1 == count); + } + // member object w/ref + { + T a{42}; + Tuple t{a}; + assert(42 == std::apply(obj1, t)); + } + // member object w/pointer + { + T a{42}; + TuplePtr t{&a}; + assert(42 == std::apply(obj1, t)); + } + // member object w/base + { + Base a{42}; + TupleBase t{a}; + assert(42 == std::apply(obj1, t)); + } + // member object w/wrapper + { + Wrap a{42}; + TupleWrap t{a}; + assert(42 == std::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 == std::apply(mem1, t)); + assert(count == 2); + } + count = 0; + // member function w/pointer + { + T a; + TuplePtr t{&a, 3}; + assert(3 == std::apply(mem1, t)); + assert(count == 3); + } + count = 0; + // member function w/base + { + Base a; + TupleBase t{a, 4}; + assert(4 == std::apply(mem1, t)); + assert(count == 4); + } + count = 0; + // member function w/wrap + { + Wrap a; + TupleWrap t{a, 5}; + assert(5 == std::apply(mem1, t)); + assert(count == 5); + } + count = 0; + // const member function w/ref + { + T const a; + ConstTuple t{a, 6}; + assert(6 == std::apply(mem2, t)); + assert(count == 6); + } + count = 0; + // const member function w/pointer + { + T const a; + ConstTuplePtr t{&a, 7}; + assert(7 == std::apply(mem2, t)); + assert(count == 7); + } + count = 0; + // const member function w/base + { + Base const a; + ConstTupleBase t{a, 8}; + assert(8 == std::apply(mem2, t)); + assert(count == 8); + } + count = 0; + // const member function w/wrapper + { + Wrap const a; + ConstTupleWrap t{a, 9}; + assert(9 == std::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 == std::apply(mem1, t)); + assert(count == 2); + } + count = 0; + // member function w/pointer + { + T a; + TuplePtr t{&a, 1, 2}; + assert(3 == std::apply(mem1, t)); + assert(count == 3); + } + count = 0; + // member function w/base + { + Base a; + TupleBase t{a, 2, 2}; + assert(4 == std::apply(mem1, t)); + assert(count == 4); + } + count = 0; + // member function w/wrap + { + Wrap a; + TupleWrap t{a, 2, 3}; + assert(5 == std::apply(mem1, t)); + assert(count == 5); + } + count = 0; + // const member function w/ref + { + T const a; + ConstTuple t{a, 3, 3}; + assert(6 == std::apply(mem2, t)); + assert(count == 6); + } + count = 0; + // const member function w/pointer + { + T const a; + ConstTuplePtr t{&a, 3, 4}; + assert(7 == std::apply(mem2, t)); + assert(count == 7); + } + count = 0; + // const member function w/base + { + Base const a; + ConstTupleBase t{a, 4, 4}; + assert(8 == std::apply(mem2, t)); + assert(count == 8); + } + count = 0; + // const member function w/wrapper + { + Wrap const a; + ConstTupleWrap t{a, 4, 5}; + assert(9 == std::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/utilities/tuple/tuple.tuple/tuple.apply/apply_large_arity.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply_large_arity.pass.cpp new file mode 100644 index 0000000000000..33c3ef5956e4e --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply_large_arity.pass.cpp @@ -0,0 +1,144 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <tuple> + +// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&) + +// Stress testing large arities with tuple and array. + +#include <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; } + + +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(std::apply(val_fn, a)); + assert(std::apply(ref_fn, a)); + assert(std::apply(cref_fn, a)); + assert(std::apply(rref_fn, std::move(a))); + } + { + ConstA a{}; + assert(std::apply(val_fn, a)); + assert(std::apply(cref_fn, a)); + } + { + Tuple a{}; + assert(std::apply(val_fn, a)); + assert(std::apply(ref_fn, a)); + assert(std::apply(cref_fn, a)); + assert(std::apply(rref_fn, std::move(a))); + } + { + CTuple a{}; + assert(std::apply(val_fn, a)); + assert(std::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(std::apply(val_fn, a)); + } + { + Tuple a{}; + assert(std::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 256 + test_one<256>(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp new file mode 100644 index 0000000000000..143ae195e6f44 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp @@ -0,0 +1,214 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <tuple> + +// template <class T, class Tuple> constexpr T make_from_tuple(Tuple&&); + +#include <tuple> +#include <array> +#include <utility> +#include <string> +#include <cassert> + +#include "test_macros.h" +#include "type_id.h" + +// std::array is explicitly allowed to be initialized with A a = { init-list };. +// Disable the missing braces warning for this reason. +#include "disable_missing_braces_warning.h" + +template <class Tuple> +struct ConstexprConstructibleFromTuple { + template <class ...Args> + explicit constexpr ConstexprConstructibleFromTuple(Args&&... xargs) + : args{std::forward<Args>(xargs)...} {} + Tuple args; +}; + +template <class TupleLike> +struct ConstructibleFromTuple; + +template <template <class ...> class Tuple, class ...Types> +struct ConstructibleFromTuple<Tuple<Types...>> { + template <class ...Args> + explicit ConstructibleFromTuple(Args&&... xargs) + : args(xargs...), + arg_types(&makeArgumentID<Args&&...>()) + {} + Tuple<std::decay_t<Types>...> args; + TypeID const* arg_types; +}; + +template <class Tp, size_t N> +struct ConstructibleFromTuple<std::array<Tp, N>> { +template <class ...Args> + explicit ConstructibleFromTuple(Args&&... xargs) + : args{xargs...}, + arg_types(&makeArgumentID<Args&&...>()) + {} + std::array<Tp, N> args; + TypeID const* arg_types; +}; + +template <class Tuple> +constexpr bool do_constexpr_test(Tuple&& tup) { + using RawTuple = std::decay_t<Tuple>; + using Tp = ConstexprConstructibleFromTuple<RawTuple>; + return std::make_from_tuple<Tp>(std::forward<Tuple>(tup)).args == tup; +} + +// Needed by do_forwarding_test() since it compare pairs of different types. +template <class T1, class T2, class U1, class U2> +inline bool operator==(const std::pair<T1, T2>& lhs, const std::pair<U1, U2>& rhs) { + return lhs.first == rhs.first && lhs.second == rhs.second; +} + +template <class ...ExpectTypes, class Tuple> +bool do_forwarding_test(Tuple&& tup) { + using RawTuple = std::decay_t<Tuple>; + using Tp = ConstructibleFromTuple<RawTuple>; + const Tp value = std::make_from_tuple<Tp>(std::forward<Tuple>(tup)); + return value.args == tup + && value.arg_types == &makeArgumentID<ExpectTypes...>(); +} + +void test_constexpr_construction() { + { + constexpr std::tuple<> tup; + static_assert(do_constexpr_test(tup), ""); + } + { + constexpr std::tuple<int> tup(42); + static_assert(do_constexpr_test(tup), ""); + } + { + constexpr std::tuple<int, long, void*> tup(42, 101, nullptr); + static_assert(do_constexpr_test(tup), ""); + } + { + constexpr std::pair<int, const char*> p(42, "hello world"); + static_assert(do_constexpr_test(p), ""); + } + { + using Tuple = std::array<int, 3>; + using ValueTp = ConstexprConstructibleFromTuple<Tuple>; + constexpr Tuple arr = {42, 101, -1}; + constexpr ValueTp value = std::make_from_tuple<ValueTp>(arr); + static_assert(value.args[0] == arr[0] && value.args[1] == arr[1] + && value.args[2] == arr[2], ""); + } +} + +void test_perfect_forwarding() { + { + using Tup = std::tuple<>; + Tup tup; + Tup const& ctup = tup; + assert(do_forwarding_test<>(tup)); + assert(do_forwarding_test<>(ctup)); + } + { + using Tup = std::tuple<int>; + Tup tup(42); + Tup const& ctup = tup; + assert(do_forwarding_test<int&>(tup)); + assert(do_forwarding_test<int const&>(ctup)); + assert(do_forwarding_test<int&&>(std::move(tup))); + assert(do_forwarding_test<int const&&>(std::move(ctup))); + } + { + using Tup = std::tuple<int&, const char*, unsigned&&>; + int x = 42; + unsigned y = 101; + Tup tup(x, "hello world", std::move(y)); + Tup const& ctup = tup; + assert((do_forwarding_test<int&, const char*&, unsigned&>(tup))); + assert((do_forwarding_test<int&, const char* const&, unsigned &>(ctup))); + assert((do_forwarding_test<int&, const char*&&, unsigned&&>(std::move(tup)))); + assert((do_forwarding_test<int&, const char* const&&, unsigned &&>(std::move(ctup)))); + } + // test with pair<T, U> + { + using Tup = std::pair<int&, const char*>; + int x = 42; + Tup tup(x, "hello world"); + Tup const& ctup = tup; + assert((do_forwarding_test<int&, const char*&>(tup))); + assert((do_forwarding_test<int&, const char* const&>(ctup))); + assert((do_forwarding_test<int&, const char*&&>(std::move(tup)))); + assert((do_forwarding_test<int&, const char* const&&>(std::move(ctup)))); + } + // test with array<T, I> + { + using Tup = std::array<int, 3>; + Tup tup = {42, 101, -1}; + Tup const& ctup = tup; + assert((do_forwarding_test<int&, int&, int&>(tup))); + assert((do_forwarding_test<int const&, int const&, int const&>(ctup))); + assert((do_forwarding_test<int&&, int&&, int&&>(std::move(tup)))); + assert((do_forwarding_test<int const&&, int const&&, int const&&>(std::move(ctup)))); + } +} + +void test_noexcept() { + struct NothrowMoveable { + NothrowMoveable() = default; + NothrowMoveable(NothrowMoveable const&) {} + NothrowMoveable(NothrowMoveable&&) noexcept {} + }; + struct TestType { + TestType(int, NothrowMoveable) noexcept {} + TestType(int, int, int) noexcept(false) {} + TestType(long, long, long) noexcept {} + }; + { + using Tuple = std::tuple<int, NothrowMoveable>; + Tuple tup; ((void)tup); + Tuple const& ctup = tup; ((void)ctup); + ASSERT_NOT_NOEXCEPT(std::make_from_tuple<TestType>(ctup)); + ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(std::move(tup))); + } + { + using Tuple = std::pair<int, NothrowMoveable>; + Tuple tup; ((void)tup); + Tuple const& ctup = tup; ((void)ctup); + ASSERT_NOT_NOEXCEPT(std::make_from_tuple<TestType>(ctup)); + ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(std::move(tup))); + } + { + using Tuple = std::tuple<int, int, int>; + Tuple tup; ((void)tup); + ASSERT_NOT_NOEXCEPT(std::make_from_tuple<TestType>(tup)); + } + { + using Tuple = std::tuple<long, long, long>; + Tuple tup; ((void)tup); + ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(tup)); + } + { + using Tuple = std::array<int, 3>; + Tuple tup; ((void)tup); + ASSERT_NOT_NOEXCEPT(std::make_from_tuple<TestType>(tup)); + } + { + using Tuple = std::array<long, 3>; + Tuple tup; ((void)tup); + ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(tup)); + } +} + +int main() +{ + test_constexpr_construction(); + test_perfect_forwarding(); + test_noexcept(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp index 2dde6b5521f2d..91892efaf1393 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp @@ -74,4 +74,16 @@ int main() assert(std::get<1>(t1) == int('a')); assert(std::get<2>(t1).id_ == 2); } + { + // Test that tuple evaluates correctly applies an lvalue reference + // before evaluating is_assignable (ie 'is_assignable<int&, int&>') + // instead of evaluating 'is_assignable<int&&, int&>' which is false. + int x = 42; + int y = 43; + std::tuple<int&&> t(std::move(x)); + std::tuple<int&> t2(y); + t = t2; + assert(std::get<0>(t) == 43); + assert(&std::get<0>(t) == &x); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp index 11bfdd0c94a98..afd3e0fdb8e3d 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp @@ -37,6 +37,13 @@ struct D explicit D(int i) : B(i) {} }; +struct E { + E() = default; + E& operator=(int val) { + return *this; + } +}; + int main() { { @@ -88,4 +95,16 @@ int main() assert(std::get<1>(t1) == int('a')); assert(std::get<2>(t1)->id_ == 3); } + { + // Test that tuple evaluates correctly applies an lvalue reference + // before evaluating is_assignable (ie 'is_assignable<int&, int&&>') + // instead of evaluating 'is_assignable<int&&, int&&>' which is false. + int x = 42; + int y = 43; + std::tuple<int&&, E> t(std::move(x), E{}); + std::tuple<int&&, int> t2(std::move(y), 44); + t = std::move(t2); + assert(std::get<0>(t) == 43); + assert(&std::get<0>(t) == &x); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR22806_constrain_tuple_like_ctor.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR22806_constrain_tuple_like_ctor.pass.cpp new file mode 100644 index 0000000000000..4ddfb463385c7 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR22806_constrain_tuple_like_ctor.pass.cpp @@ -0,0 +1,178 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <tuple> + +// template <class... Types> class tuple; + +// template <class TupleLike> +// tuple(TupleLike&&); +// template <class Alloc, class TupleLike> +// tuple(std::allocator_arg_t, Alloc const&, TupleLike&&); + +// Check that the tuple-like ctors are properly disabled when the UTypes... +// constructor should be selected. See PR22806. + +#include <tuple> +#include <memory> +#include <cassert> + +template <class Tp> +using uncvref_t = typename std::remove_cv<typename std::remove_reference<Tp>::type>::type; + +template <class Tuple, class = uncvref_t<Tuple>> +struct IsTuple : std::false_type {}; + +template <class Tuple, class ...Args> +struct IsTuple<Tuple, std::tuple<Args...>> : std::true_type {}; + +struct ConstructibleFromTupleAndInt { + enum State { FromTuple, FromInt, Copied, Moved }; + State state; + + ConstructibleFromTupleAndInt(ConstructibleFromTupleAndInt const&) : state(Copied) {} + ConstructibleFromTupleAndInt(ConstructibleFromTupleAndInt &&) : state(Moved) {} + + template <class Tuple, class = typename std::enable_if<IsTuple<Tuple>::value>::type> + explicit ConstructibleFromTupleAndInt(Tuple&&) : state(FromTuple) {} + + explicit ConstructibleFromTupleAndInt(int) : state(FromInt) {} +}; + +struct ConvertibleFromTupleAndInt { + enum State { FromTuple, FromInt, Copied, Moved }; + State state; + + ConvertibleFromTupleAndInt(ConvertibleFromTupleAndInt const&) : state(Copied) {} + ConvertibleFromTupleAndInt(ConvertibleFromTupleAndInt &&) : state(Moved) {} + + template <class Tuple, class = typename std::enable_if<IsTuple<Tuple>::value>::type> + ConvertibleFromTupleAndInt(Tuple&&) : state(FromTuple) {} + + ConvertibleFromTupleAndInt(int) : state(FromInt) {} +}; + +struct ConstructibleFromInt { + enum State { FromInt, Copied, Moved }; + State state; + + ConstructibleFromInt(ConstructibleFromInt const&) : state(Copied) {} + ConstructibleFromInt(ConstructibleFromInt &&) : state(Moved) {} + + explicit ConstructibleFromInt(int) : state(FromInt) {} +}; + +struct ConvertibleFromInt { + enum State { FromInt, Copied, Moved }; + State state; + + ConvertibleFromInt(ConvertibleFromInt const&) : state(Copied) {} + ConvertibleFromInt(ConvertibleFromInt &&) : state(Moved) {} + ConvertibleFromInt(int) : state(FromInt) {} +}; + +int main() +{ + // Test for the creation of dangling references when a tuple is used to + // store a reference to another tuple as its only element. + // Ex std::tuple<std::tuple<int>&&>. + // In this case the constructors 1) 'tuple(UTypes&&...)' + // and 2) 'tuple(TupleLike&&)' need to be manually disambiguated because + // when both #1 and #2 participate in partial ordering #2 will always + // be chosen over #1. + // See PR22806 and LWG issue #2549 for more information. + // (https://llvm.org/bugs/show_bug.cgi?id=22806) + using T = std::tuple<int>; + std::allocator<int> A; + { // rvalue reference + T t1(42); + std::tuple< T&& > t2(std::move(t1)); + assert(&std::get<0>(t2) == &t1); + } + { // const lvalue reference + T t1(42); + + std::tuple< T const & > t2(t1); + assert(&std::get<0>(t2) == &t1); + + std::tuple< T const & > t3(static_cast<T const&>(t1)); + assert(&std::get<0>(t3) == &t1); + } + { // lvalue reference + T t1(42); + + std::tuple< T & > t2(t1); + assert(&std::get<0>(t2) == &t1); + } + { // const rvalue reference + T t1(42); + + std::tuple< T const && > t2(std::move(t1)); + assert(&std::get<0>(t2) == &t1); + } + { // rvalue reference via uses-allocator + T t1(42); + std::tuple< T&& > t2(std::allocator_arg, A, std::move(t1)); + assert(&std::get<0>(t2) == &t1); + } + { // const lvalue reference via uses-allocator + T t1(42); + + std::tuple< T const & > t2(std::allocator_arg, A, t1); + assert(&std::get<0>(t2) == &t1); + + std::tuple< T const & > t3(std::allocator_arg, A, static_cast<T const&>(t1)); + assert(&std::get<0>(t3) == &t1); + } + { // lvalue reference via uses-allocator + T t1(42); + + std::tuple< T & > t2(std::allocator_arg, A, t1); + assert(&std::get<0>(t2) == &t1); + } + { // const rvalue reference via uses-allocator + T const t1(42); + std::tuple< T const && > t2(std::allocator_arg, A, std::move(t1)); + assert(&std::get<0>(t2) == &t1); + } + // Test constructing a 1-tuple of the form tuple<UDT> from another 1-tuple + // 'tuple<T>' where UDT *can* be constructed from 'tuple<T>' In this case + // the 'tuple(UTypes...)' ctor should be choosen and 'UDT' constructed frow + // 'tuple<T>'. + { + using VT = ConstructibleFromTupleAndInt; + std::tuple<int> t1(42); + std::tuple<VT> t2(t1); + assert(std::get<0>(t2).state == VT::FromTuple); + } + { + using VT = ConvertibleFromTupleAndInt; + std::tuple<int> t1(42); + std::tuple<VT> t2 = {t1}; + assert(std::get<0>(t2).state == VT::FromTuple); + } + // Test constructing a 1-tuple of the form tuple<UDT> from another 1-tuple + // 'tuple<T>' where UDT cannot be constructed from 'tuple<T>' but can + // be constructed from 'T'. In this case the tuple-like ctor should be + // chosen and 'UDT' constructed from 'T' + { + using VT = ConstructibleFromInt; + std::tuple<int> t1(42); + std::tuple<VT> t2(t1); + assert(std::get<0>(t2).state == VT::FromInt); + } + { + using VT = ConvertibleFromInt; + std::tuple<int> t1(42); + std::tuple<VT> t2 = {t1}; + assert(std::get<0>(t2).state == VT::FromInt); + } +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR23256_constrain_UTypes_ctor.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR23256_constrain_UTypes_ctor.pass.cpp new file mode 100644 index 0000000000000..ed3cafadbf08d --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR23256_constrain_UTypes_ctor.pass.cpp @@ -0,0 +1,96 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <tuple> + +// template <class... Types> class tuple; + +// template <class ...UTypes> +// EXPLICIT(...) tuple(UTypes&&...) + +// Check that the UTypes... ctor is properly disabled before evaluating any +// SFINAE when the tuple-like copy/move ctor should *clearly* be selected +// instead. This happens 'sizeof...(UTypes) == 1' and the first element of +// 'UTypes...' is an instance of the tuple itself. See PR23256. + +#include <tuple> +#include <memory> +#include <type_traits> + + +struct UnconstrainedCtor { + int value_; + + UnconstrainedCtor() : value_(0) {} + + // Blows up when instantiated for any type other than int. Because the ctor + // is constexpr it is instantiated by 'is_constructible' and 'is_convertible' + // for Clang based compilers. GCC does not instantiate the ctor body + // but it does instantiate the noexcept specifier and it will blow up there. + template <typename T> + constexpr UnconstrainedCtor(T value) noexcept(noexcept(value_ = value)) + : value_(static_cast<int>(value)) + { + static_assert(std::is_same<int, T>::value, ""); + } +}; + +struct ExplicitUnconstrainedCtor { + int value_; + + ExplicitUnconstrainedCtor() : value_(0) {} + + template <typename T> + constexpr explicit ExplicitUnconstrainedCtor(T value) + noexcept(noexcept(value_ = value)) + : value_(static_cast<int>(value)) + { + static_assert(std::is_same<int, T>::value, ""); + } + +}; + +int main() { + typedef UnconstrainedCtor A; + typedef ExplicitUnconstrainedCtor ExplicitA; + { + static_assert(std::is_copy_constructible<std::tuple<A>>::value, ""); + static_assert(std::is_move_constructible<std::tuple<A>>::value, ""); + static_assert(std::is_copy_constructible<std::tuple<ExplicitA>>::value, ""); + static_assert(std::is_move_constructible<std::tuple<ExplicitA>>::value, ""); + } + { + static_assert(std::is_constructible< + std::tuple<A>, + std::allocator_arg_t, std::allocator<void>, + std::tuple<A> const& + >::value, ""); + static_assert(std::is_constructible< + std::tuple<A>, + std::allocator_arg_t, std::allocator<void>, + std::tuple<A> && + >::value, ""); + static_assert(std::is_constructible< + std::tuple<ExplicitA>, + std::allocator_arg_t, std::allocator<void>, + std::tuple<ExplicitA> const& + >::value, ""); + static_assert(std::is_constructible< + std::tuple<ExplicitA>, + std::allocator_arg_t, std::allocator<void>, + std::tuple<ExplicitA> && + >::value, ""); + } + { + std::tuple<A&&> t(std::forward_as_tuple(A{})); + std::tuple<ExplicitA&&> t2(std::forward_as_tuple(ExplicitA{})); + } +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR27684_contains_ref_to_incomplete_type.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR27684_contains_ref_to_incomplete_type.pass.cpp new file mode 100644 index 0000000000000..c8b722f836c17 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR27684_contains_ref_to_incomplete_type.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <tuple> + +// template <class... Types> class tuple; + +// template <class Alloc> tuple(allocator_arg_t, Alloc const&) + +// Libc++ has to deduce the 'allocator_arg_t' parameter for this constructor +// as 'AllocArgT'. Previously libc++ has tried to support tags derived from +// 'allocator_arg_t' by using 'is_base_of<AllocArgT, allocator_arg_t>'. +// However this breaks whenever a 2-tuple contains a reference to an incomplete +// type as its first parameter. See PR27684. + +#include <tuple> +#include <cassert> + +struct IncompleteType; +extern IncompleteType inc1; +extern IncompleteType inc2; +IncompleteType const& cinc1 = inc1; +IncompleteType const& cinc2 = inc2; + +int main() { + using IT = IncompleteType; + { // try calling tuple(Tp const&...) + using Tup = std::tuple<const IT&, const IT&>; + Tup t(cinc1, cinc2); + assert(&std::get<0>(t) == &inc1); + assert(&std::get<1>(t) == &inc2); + } + { // try calling tuple(Up&&...) + using Tup = std::tuple<const IT&, const IT&>; + Tup t(inc1, inc2); + assert(&std::get<0>(t) == &inc1); + assert(&std::get<1>(t) == &inc2); + } +} + +struct IncompleteType {}; +IncompleteType inc1; +IncompleteType inc2; diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp index 817cc8f109905..6ab303c735bec 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp @@ -82,6 +82,8 @@ void test_default_constructible_extension_sfinae() MoveOnly, Tuple, MoveOnly, MoveOnly >::value, ""); } + // testing extensions +#ifdef _LIBCPP_VERSION { typedef std::tuple<MoveOnly, int> Tuple; typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple; @@ -96,6 +98,7 @@ void test_default_constructible_extension_sfinae() MoveOnly, Tuple, MoveOnly, MoveOnly >::value, ""); } +#endif } int main() @@ -118,6 +121,7 @@ int main() assert(std::get<2>(t) == 2); } // extensions +#ifdef _LIBCPP_VERSION { std::tuple<MoveOnly, MoveOnly, MoveOnly> t(MoveOnly(0), MoveOnly(1)); @@ -131,7 +135,8 @@ int main() assert(std::get<1>(t) == MoveOnly()); assert(std::get<2>(t) == MoveOnly()); } -#if _LIBCPP_STD_VER > 11 +#endif +#if TEST_STD_VER > 11 { constexpr std::tuple<Empty> t0{Empty()}; } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp index 39776822cbda4..4da5fc7f83979 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <tuple> // template <class... Types> class tuple; @@ -14,7 +16,9 @@ // template <class Alloc> // tuple(allocator_arg_t, const Alloc& a); -// UNSUPPORTED: c++98, c++03 +// NOTE: this constructor does not currently support tags derived from +// allocator_arg_t because libc++ has to deduce the parameter as a template +// argument. See PR27684 (https://llvm.org/bugs/show_bug.cgi?id=27684) #include <tuple> #include <cassert> @@ -24,6 +28,18 @@ #include "../alloc_first.h" #include "../alloc_last.h" +template <class T = void> +struct NonDefaultConstructible { + constexpr NonDefaultConstructible() { + static_assert(!std::is_same<T, T>::value, "Default Ctor instantiated"); + } + + explicit constexpr NonDefaultConstructible(int) {} +}; + + +struct DerivedFromAllocArgT : std::allocator_arg_t {}; + int main() { { @@ -78,4 +94,14 @@ int main() assert(!alloc_last::allocator_constructed); assert(std::get<2>(t) == alloc_last()); } + { + // Test that the uses-allocator default constructor does not evaluate + // it's SFINAE when it otherwise shouldn't be selected. Do this by + // using 'NonDefaultConstructible' which will cause a compile error + // if std::is_default_constructible is evaluated on it. + using T = NonDefaultConstructible<>; + T v(42); + std::tuple<T, T> t(v, v); + std::tuple<T, T> t2(42, 42); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp index 3929965cd2735..e174e9b321b8d 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp @@ -24,16 +24,29 @@ #include "../alloc_first.h" #include "../alloc_last.h" -struct NoDefault { NoDefault() = delete; }; +template <class T = void> +struct DefaultCtorBlowsUp { + constexpr DefaultCtorBlowsUp() { + static_assert(!std::is_same<T, T>::value, "Default Ctor instantiated"); + } -// Make sure the _Up... constructor SFINAEs out when the types that -// are not explicitly initialized are not all default constructible. -// Otherwise, std::is_constructible would return true but instantiating -// the constructor would fail. -void test_default_constructible_extension_sfinae() + explicit constexpr DefaultCtorBlowsUp(int x) : value(x) {} + + int value; +}; + + +struct DerivedFromAllocArgT : std::allocator_arg_t {}; + + +// Make sure the _Up... constructor SFINAEs out when the number of initializers +// is less that the number of elements in the tuple. Previously libc++ would +// offer these constructers as an extension but they broke conforming code. +void test_uses_allocator_sfinae_evaluation() { + using BadDefault = DefaultCtorBlowsUp<>; { - typedef std::tuple<MoveOnly, NoDefault> Tuple; + typedef std::tuple<MoveOnly, MoveOnly, BadDefault> Tuple; static_assert(!std::is_constructible< Tuple, @@ -42,11 +55,11 @@ void test_default_constructible_extension_sfinae() static_assert(std::is_constructible< Tuple, - std::allocator_arg_t, A1<int>, MoveOnly, NoDefault + std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, BadDefault >::value, ""); } { - typedef std::tuple<MoveOnly, MoveOnly, NoDefault> Tuple; + typedef std::tuple<MoveOnly, MoveOnly, BadDefault, BadDefault> Tuple; static_assert(!std::is_constructible< Tuple, @@ -55,53 +68,44 @@ void test_default_constructible_extension_sfinae() static_assert(std::is_constructible< Tuple, - std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, NoDefault - >::value, ""); - } - { - // Same idea as above but with a nested tuple - typedef std::tuple<MoveOnly, NoDefault> Tuple; - typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple; - - static_assert(!std::is_constructible< - NestedTuple, - std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, MoveOnly, MoveOnly - >::value, ""); - - static_assert(std::is_constructible< - NestedTuple, - std::allocator_arg_t, A1<int>, MoveOnly, Tuple, MoveOnly, MoveOnly - >::value, ""); - } - { - typedef std::tuple<MoveOnly, int> Tuple; - typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple; - - static_assert(std::is_constructible< - NestedTuple, - std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, MoveOnly, MoveOnly - >::value, ""); - - static_assert(std::is_constructible< - NestedTuple, - std::allocator_arg_t, A1<int>, MoveOnly, Tuple, MoveOnly, MoveOnly + std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, BadDefault, BadDefault >::value, ""); } } +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + int main() { { + std::tuple<Explicit> t{std::allocator_arg, std::allocator<void>{}, 42}; + assert(std::get<0>(t).value == 42); + } + { std::tuple<MoveOnly> t(std::allocator_arg, A1<int>(), MoveOnly(0)); assert(std::get<0>(t) == 0); } { + using T = DefaultCtorBlowsUp<>; + std::tuple<T> t(std::allocator_arg, A1<int>(), T(42)); + assert(std::get<0>(t).value == 42); + } + { std::tuple<MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(), MoveOnly(0), MoveOnly(1)); assert(std::get<0>(t) == 0); assert(std::get<1>(t) == 1); } { + using T = DefaultCtorBlowsUp<>; + std::tuple<T, T> t(std::allocator_arg, A1<int>(), T(42), T(43)); + assert(std::get<0>(t).value == 42); + assert(std::get<1>(t).value == 43); + } + { std::tuple<MoveOnly, MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(), MoveOnly(0), 1, 2); @@ -110,6 +114,13 @@ int main() assert(std::get<2>(t) == 2); } { + using T = DefaultCtorBlowsUp<>; + std::tuple<T, T, T> t(std::allocator_arg, A1<int>(), T(1), T(2), T(3)); + assert(std::get<0>(t).value == 1); + assert(std::get<1>(t).value == 2); + assert(std::get<2>(t).value == 3); + } + { alloc_first::allocator_constructed = false; alloc_last::allocator_constructed = false; std::tuple<int, alloc_first, alloc_last> t(std::allocator_arg, @@ -120,22 +131,22 @@ int main() assert(alloc_last::allocator_constructed); assert(std::get<2>(t) == alloc_last(3)); } - // extensions - { - std::tuple<MoveOnly, MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(), - 0, 1); - assert(std::get<0>(t) == 0); - assert(std::get<1>(t) == 1); - assert(std::get<2>(t) == MoveOnly()); - } { - std::tuple<MoveOnly, MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(), - 0); - assert(std::get<0>(t) == 0); - assert(std::get<1>(t) == MoveOnly()); - assert(std::get<2>(t) == MoveOnly()); + // Check that uses-allocator construction is still selected when + // given a tag type that derives from allocator_arg_t. + DerivedFromAllocArgT tag; + alloc_first::allocator_constructed = false; + alloc_last::allocator_constructed = false; + std::tuple<int, alloc_first, alloc_last> t(tag, + A1<int>(5), 1, 2, 3); + assert(std::get<0>(t) == 1); + assert(alloc_first::allocator_constructed); + assert(std::get<1>(t) == alloc_first(2)); + assert(alloc_last::allocator_constructed); + assert(std::get<2>(t) == alloc_last(3)); } - // Check that SFINAE is properly applied with the default reduced arity - // constructor extensions. - test_default_constructible_extension_sfinae(); + // Stress test the SFINAE on the uses-allocator constructors and + // ensure that the "reduced-arity-initialization" extension is not offered + // for these constructors. + test_uses_allocator_sfinae_evaluation(); } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.cpp new file mode 100644 index 0000000000000..b28ad6dab5ab7 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.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. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class Alloc> +// EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...); + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <memory> +#include <cassert> + +struct ExplicitCopy { + explicit ExplicitCopy(ExplicitCopy const&) {} + explicit ExplicitCopy(int) {} +}; + +std::tuple<ExplicitCopy> const_explicit_copy_test() { + const ExplicitCopy e(42); + return {std::allocator_arg, std::allocator<void>{}, e}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +std::tuple<ExplicitCopy> non_const_explicity_copy_test() { + ExplicitCopy e(42); + return {std::allocator_arg, std::allocator<void>{}, e}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} +int main() +{ + const_explicit_copy_test(); + non_const_explicity_copy_test(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp index 0f68926376f24..73d53a4c0e261 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp @@ -17,15 +17,37 @@ // UNSUPPORTED: c++98, c++03 #include <tuple> +#include <memory> #include <cassert> #include "allocators.h" #include "../alloc_first.h" #include "../alloc_last.h" +struct ImplicitCopy { + explicit ImplicitCopy(int) {} + ImplicitCopy(ImplicitCopy const&) {} +}; + +// Test that tuple(std::allocator_arg, Alloc, Types const&...) allows implicit +// copy conversions in return value expressions. +std::tuple<ImplicitCopy> testImplicitCopy1() { + ImplicitCopy i(42); + return {std::allocator_arg, std::allocator<void>{}, i}; +} + +std::tuple<ImplicitCopy> testImplicitCopy2() { + const ImplicitCopy i(42); + return {std::allocator_arg, std::allocator<void>{}, i}; +} + int main() { { + // check that the literal '0' can implicitly initialize a stored pointer. + std::tuple<int*> t = {std::allocator_arg, std::allocator<void>{}, 0}; + } + { std::tuple<int> t(std::allocator_arg, A1<int>(), 3); assert(std::get<0>(t) == 3); } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.cpp new file mode 100644 index 0000000000000..ccf08833b537e --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.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. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class Alloc, class ...UTypes> +// tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...> const&); + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <memory> + +struct ExplicitCopy { + explicit ExplicitCopy(int) {} + explicit ExplicitCopy(ExplicitCopy const&) {} + +}; + +std::tuple<ExplicitCopy> const_explicit_copy_test() { + const std::tuple<int> t1(42); + return {std::allocator_arg, std::allocator<void>{}, t1}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +std::tuple<ExplicitCopy> non_const_explicit_copy_test() { + std::tuple<int> t1(42); + return {std::allocator_arg, std::allocator<void>{}, t1}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +int main() +{ + +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp index 8acfde7a98eb1..36d9f32879cbb 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp @@ -17,12 +17,23 @@ // UNSUPPORTED: c++98, c++03 #include <tuple> +#include <memory> #include <cassert> #include "allocators.h" #include "../alloc_first.h" #include "../alloc_last.h" +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + +struct Implicit { + int value; + Implicit(int x) : value(x) {} +}; + int main() { { @@ -66,4 +77,14 @@ int main() assert(std::get<1>(t1) == 2); assert(std::get<2>(t1) == 3); } + { + const std::tuple<int> t1(42); + std::tuple<Explicit> t2{std::allocator_arg, std::allocator<void>{}, t1}; + assert(std::get<0>(t2).value == 42); + } + { + const std::tuple<int> t1(42); + std::tuple<Implicit> t2 = {std::allocator_arg, std::allocator<void>{}, t1}; + assert(std::get<0>(t2).value == 42); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.fail.cpp new file mode 100644 index 0000000000000..d3539cebf9500 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.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. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class Alloc, class ...UTypes> +// tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&); + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <memory> + +struct ExplicitCopy { + explicit ExplicitCopy(int) {} + explicit ExplicitCopy(ExplicitCopy const&) {} +}; + +std::tuple<ExplicitCopy> explicit_move_test() { + std::tuple<int> t1(42); + return {std::allocator_arg, std::allocator<void>{}, std::move(t1)}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +int main() +{ + +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp index c862d3b64d56f..d3a6add5da6a8 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp @@ -40,6 +40,16 @@ struct D explicit D(int i) : B(i) {} }; +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + +struct Implicit { + int value; + Implicit(int x) : value(x) {} +}; + int main() { { @@ -81,4 +91,14 @@ int main() assert(std::get<1>(t1) == 2); assert(std::get<2>(t1)->id_ == 3); } + { + std::tuple<int> t1(42); + std::tuple<Explicit> t2{std::allocator_arg, std::allocator<void>{}, std::move(t1)}; + assert(std::get<0>(t2).value == 42); + } + { + std::tuple<int> t1(42); + std::tuple<Implicit> t2 = {std::allocator_arg, std::allocator<void>{}, std::move(t1)}; + assert(std::get<0>(t2).value == 42); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_copy.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_copy.pass.cpp index 14e127e59ba91..7c9f60cbf901b 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_copy.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_copy.pass.cpp @@ -52,6 +52,8 @@ int main() assert(alloc_last::allocator_constructed); assert(std::get<0>(t) == 2); } +// testing extensions +#ifdef _LIBCPP_VERSION { typedef std::tuple<alloc_first, alloc_last> T; T t0(2, 3); @@ -75,4 +77,5 @@ int main() assert(std::get<1>(t) == 2); assert(std::get<2>(t) == 3); } +#endif } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_move.pass.cpp index 54d3f7ee0c079..a3e1a9de61958 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_move.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_move.pass.cpp @@ -53,6 +53,8 @@ int main() assert(alloc_last::allocator_constructed); assert(std::get<0>(t) == 1); } +// testing extensions +#ifdef _LIBCPP_VERSION { typedef std::tuple<MoveOnly, alloc_first> T; T t0(0 ,1); @@ -74,4 +76,5 @@ int main() assert(std::get<1>(t) == 2); assert(std::get<2>(t) == 3); } +#endif } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp index 00e2af265b360..b72f0fc2efec4 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp @@ -19,9 +19,30 @@ #include <string> #include <cassert> +struct ExplicitCopy { + ExplicitCopy(int) {} + explicit ExplicitCopy(ExplicitCopy const&) {} +}; + +std::tuple<ExplicitCopy> const_explicit_copy() { + const ExplicitCopy e(42); + return {e}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + + +std::tuple<ExplicitCopy> non_const_explicit_copy() { + ExplicitCopy e(42); + return {e}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +std::tuple<ExplicitCopy> const_explicit_copy_no_brace() { + const ExplicitCopy e(42); + return e; + // expected-error@-1 {{no viable conversion}} +} + int main() { - { - std::tuple<int*> t = 0; - } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp index bbadf8de16001..367f19e5d8dd6 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp @@ -53,13 +53,40 @@ struct NoValueCtorEmpty { static_assert(never<T>::value, "This should not be instantiated"); } }; + +struct ImplicitCopy { + explicit ImplicitCopy(int) {} + ImplicitCopy(ImplicitCopy const&) {} +}; + +// Test that tuple(std::allocator_arg, Alloc, Types const&...) allows implicit +// copy conversions in return value expressions. +std::tuple<ImplicitCopy> testImplicitCopy1() { + ImplicitCopy i(42); + return {i}; +} + +std::tuple<ImplicitCopy> testImplicitCopy2() { + const ImplicitCopy i(42); + return {i}; +} + +std::tuple<ImplicitCopy> testImplicitCopy3() { + const ImplicitCopy i(42); + return i; +} + int main() { { + // check that the literal '0' can implicitly initialize a stored pointer. + std::tuple<int*> t = 0; + } + { std::tuple<int> t(2); assert(std::get<0>(t) == 2); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { constexpr std::tuple<int> t(2); static_assert(std::get<0>(t) == 2, ""); @@ -74,7 +101,7 @@ int main() assert(std::get<0>(t) == 2); assert(std::get<1>(t) == nullptr); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { constexpr std::tuple<int, char*> t(2, nullptr); static_assert(std::get<0>(t) == 2, ""); @@ -109,7 +136,8 @@ int main() assert(std::get<2>(t) == 2); assert(std::get<3>(t) == 3); } - // extensions +// extensions +#ifdef _LIBCPP_VERSION { std::tuple<int, char*, std::string> t(2); assert(std::get<0>(t) == 2); @@ -129,4 +157,5 @@ int main() assert(std::get<2>(t) == "text"); assert(std::get<3>(t) == 0.0); } +#endif } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_pair.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_pair.pass.cpp index 740b6589e5114..d6d489fd0ea44 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_pair.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_pair.pass.cpp @@ -29,7 +29,7 @@ int main() assert(std::get<0>(t1) == 2); assert(std::get<1>(t1) == short('a')); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { typedef std::pair<double, char> P0; typedef std::tuple<int, short> T1; diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp index 5ad4f9227f481..b7fa2e3a03cc5 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp @@ -20,6 +20,16 @@ #include <string> #include <cassert> +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + +struct Implicit { + int value; + Implicit(int x) : value(x) {} +}; + struct B { int id_; @@ -33,7 +43,7 @@ struct D explicit D(int i) : B(i) {} }; -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 struct A { @@ -62,7 +72,7 @@ int main() T1 t1 = t0; assert(std::get<0>(t1) == 2); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { typedef std::tuple<double> T0; typedef std::tuple<A> T1; @@ -115,4 +125,14 @@ int main() assert(std::get<1>(t1) == int('a')); assert(std::get<2>(t1).id_ == 3); } + { + const std::tuple<int> t1(42); + std::tuple<Explicit> t2(t1); + assert(std::get<0>(t2).value == 42); + } + { + const std::tuple<int> t1(42); + std::tuple<Implicit> t2 = t1; + assert(std::get<0>(t2).value == 42); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp index 3a6abd3a95af4..8423f5d0145fc 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp @@ -20,6 +20,16 @@ #include <memory> #include <cassert> +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + +struct Implicit { + int value; + Implicit(int x) : value(x) {} +}; + struct B { int id_; @@ -81,4 +91,14 @@ int main() assert(std::get<1>(t1) == int('a')); assert(std::get<2>(t1)->id_ == 3); } + { + std::tuple<int> t1(42); + std::tuple<Explicit> t2(std::move(t1)); + assert(std::get<0>(t2).value == 42); + } + { + std::tuple<int> t1(42); + std::tuple<Implicit> t2 = std::move(t1); + assert(std::get<0>(t2).value == 42); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp index 0cda96846f717..1bd7d6d4e8a87 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp @@ -29,8 +29,10 @@ struct ConstructsWithTupleLeaf ConstructsWithTupleLeaf(ConstructsWithTupleLeaf &&) {} template <class T> - ConstructsWithTupleLeaf(T t) - { assert(false); } + ConstructsWithTupleLeaf(T t) { + static_assert(!std::is_same<T, T>::value, + "Constructor instantiated for type other than int"); + } }; int main() diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/test_lazy_sfinae.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/test_lazy_sfinae.pass.cpp new file mode 100644 index 0000000000000..76f7e794a8e81 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/test_lazy_sfinae.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. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <utility> +#include <cassert> + +template <class ConstructFrom> +struct ConstructibleFromT { + ConstructibleFromT() = default; + ConstructibleFromT(ConstructFrom v) : value(v) {} + ConstructFrom value; +}; + +template <class AssertOn> +struct CtorAssertsT { + bool defaulted; + CtorAssertsT() : defaulted(true) {} + template <class T> + constexpr CtorAssertsT(T) : defaulted(false) { + static_assert(!std::is_same<T, AssertOn>::value, ""); + } +}; + +template <class AllowT, class AssertT> +struct AllowAssertT { + AllowAssertT() = default; + AllowAssertT(AllowT) {} + template <class U> + constexpr AllowAssertT(U) { + static_assert(!std::is_same<U, AssertT>::value, ""); + } +}; + +// Construct a tuple<T1, T2> from pair<int, int> where T1 and T2 +// are not constructible from ints but T1 is constructible from std::pair. +// This considers the following constructors: +// (1) tuple(TupleLike) -> checks is_constructible<Tn, int> +// (2) tuple(UTypes...) -> checks is_constructible<T1, pair<int, int>> +// and is_default_constructible<T2> +// The point of this test is to ensure that the consideration of (1) +// short circuits before evaluating is_constructible<T2, int>, which +// will cause a static assertion. +void test_tuple_like_lazy_sfinae() { +#if defined(_LIBCPP_VERSION) + // This test requires libc++'s reduced arity initialization. + using T1 = ConstructibleFromT<std::pair<int, int>>; + using T2 = CtorAssertsT<int>; + std::pair<int, int> p(42, 100); + std::tuple<T1, T2> t(p); + assert(std::get<0>(t).value == p); + assert(std::get<1>(t).defaulted); +#endif +} + + +struct NonConstCopyable { + NonConstCopyable() = default; + explicit NonConstCopyable(int v) : value(v) {} + NonConstCopyable(NonConstCopyable&) = default; + NonConstCopyable(NonConstCopyable const&) = delete; + int value; +}; + +template <class T> +struct BlowsUpOnConstCopy { + BlowsUpOnConstCopy() = default; + constexpr BlowsUpOnConstCopy(BlowsUpOnConstCopy const&) { + static_assert(!std::is_same<T, T>::value, ""); + } + BlowsUpOnConstCopy(BlowsUpOnConstCopy&) = default; +}; + +// Test the following constructors: +// (1) tuple(Types const&...) +// (2) tuple(UTypes&&...) +// Test that (1) short circuits before evaluating the copy constructor of the +// second argument. Constructor (2) should be selected. +void test_const_Types_lazy_sfinae() +{ + NonConstCopyable v(42); + BlowsUpOnConstCopy<int> b; + std::tuple<NonConstCopyable, BlowsUpOnConstCopy<int>> t(v, b); + assert(std::get<0>(t).value == 42); +} + +int main() { + test_tuple_like_lazy_sfinae(); + test_const_Types_lazy_sfinae(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp index 0e556b1b6c8e0..2dbe81513a1a3 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp @@ -20,7 +20,7 @@ template <class Tuple> void -test0(const Tuple& t) +test0(const Tuple&) { static_assert(std::tuple_size<Tuple>::value == 0, ""); } @@ -56,8 +56,8 @@ test2a(const Tuple& t) #if _LIBCPP_STD_VER > 11 template <class Tuple> -constexpr int -test3(const Tuple& t) +constexpr int +test3(const Tuple&) { return std::tuple_size<Tuple>::value; } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp index 2ee96dc7ebf45..f27e8a09fb974 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp @@ -40,7 +40,7 @@ int main() assert(i == 0); assert(j == 0); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { constexpr auto t1 = std::make_tuple(0, 1, 3.14); constexpr int i1 = std::get<1>(t1); diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.pass.cpp index e21768cb6f5fd..002ad148ad6df 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.pass.cpp @@ -36,7 +36,7 @@ int main() assert(std::get<0>(t) == "high"); assert(std::get<1>(t) == 5); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { typedef std::tuple<double, int> T; constexpr T t(2.718, 5); diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_non_const.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_non_const.pass.cpp index 1c2b17ad88325..86d1191db5564 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_non_const.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_non_const.pass.cpp @@ -21,7 +21,9 @@ #include <string> #include <cassert> -#if __cplusplus > 201103L +#include "test_macros.h" + +#if TEST_STD_VER > 11 struct Empty {}; @@ -69,7 +71,7 @@ int main() assert(std::get<2>(t) == 4); assert(d == 2.5); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { // get on an rvalue tuple static_assert ( std::get<0> ( std::make_tuple ( 0.0f, 1, 2.0, 3L )) == 0, "" ); static_assert ( std::get<1> ( std::make_tuple ( 0.0f, 1, 2.0, 3L )) == 1, "" ); diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp new file mode 100644 index 0000000000000..74e6efd983bd4 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.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 + +#include <tuple> +#include <string> + +struct UserType {}; + +void test_bad_index() { + std::tuple<long, long, char, std::string, char, UserType, char> t1; + (void)std::get<int>(t1); // expected-error@tuple:* {{type not found}} + (void)std::get<long>(t1); // expected-note {{requested here}} + (void)std::get<char>(t1); // expected-note {{requested here}} + // expected-error@tuple:* 2 {{type occurs more than once}} + std::tuple<> t0; + (void)std::get<char*>(t0); // expected-node {{requested here}} + // expected-error@tuple:* 1 {{type not in empty type list}} +} + +void test_bad_return_type() { + typedef std::unique_ptr<int> upint; + std::tuple<upint> t; + upint p = std::get<upint>(t); // expected-error{{deleted copy constructor}} +} + +int main() +{ + test_bad_index(); + test_bad_return_type(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.pass.cpp index b661a78de8dba..01ee1ca1f4342 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.pass.cpp @@ -11,6 +11,7 @@ #include <tuple> #include <utility> +#include <memory> #include <string> #include <complex> #include <type_traits> diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.array.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.array.pass.cpp index d8a72c617cb5c..57da4b04cdfd9 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.array.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.array.pass.cpp @@ -18,7 +18,7 @@ // typedef Ti type; // }; // -// LWG #2212 says that tuple_size and tuple_element must be +// LWG #2212 says that tuple_size and tuple_element must be // available after including <utility> #include <array> diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.utility.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.utility.pass.cpp index 8c8357d95d994..bd015ab5bbd6e 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.utility.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.utility.pass.cpp @@ -15,9 +15,10 @@ // class tuple_size<tuple<Types...>> // : public integral_constant<size_t, sizeof...(Types)> { }; // -// LWG #2212 says that tuple_size and tuple_element must be +// LWG #2212 says that tuple_size and tuple_element must be // available after including <utility> +#include <cstddef> #include <utility> #include <type_traits> diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_element.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_element.fail.cpp new file mode 100644 index 0000000000000..4cb73573e7c9d --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_element.fail.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. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <size_t I, class... Types> +// class tuple_element<I, tuple<Types...> > +// { +// public: +// typedef Ti type; +// }; + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <type_traits> + +int main() +{ + using T = std::tuple<int, long, void*>; + using E1 = typename std::tuple_element<1, T &>::type; // expected-error{{undefined template}} + using E2 = typename std::tuple_element<3, T>::type; + using E3 = typename std::tuple_element<4, T const>::type; + // expected-error@__tuple:* 2 {{static_assert failed}} + +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.fail.cpp new file mode 100644 index 0000000000000..3f132e47b626c --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.fail.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <tuple> + +// template <class... Types> +// class tuple_size<tuple<Types...>> +// : public integral_constant<size_t, sizeof...(Types)> { }; + +// Expect failures with a reference type, pointer type, and a non-tuple type. + +#include <tuple> + +int main() +{ + (void)std::tuple_size<std::tuple<> &>::value; // expected-error {{implicit instantiation of undefined template}} + (void)std::tuple_size<int>::value; // expected-error {{implicit instantiation of undefined template}} + (void)std::tuple_size<std::tuple<>*>::value; // expected-error {{implicit instantiation of undefined template}} +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.fail.cpp new file mode 100644 index 0000000000000..957a683b47f85 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.fail.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <tuple> + +// template <class T> constexpr size_t tuple_size_v = tuple_size<T>::value; + +// Expect failures with a reference type, pointer type, and a non-tuple type. + +#include <tuple> + +int main() +{ + (void)std::tuple_size_v<std::tuple<> &>; // expected-note {{requested here}} + (void)std::tuple_size_v<int>; // expected-note {{requested here}} + (void)std::tuple_size_v<std::tuple<>*>; // expected-note {{requested here}} + // expected-error@tuple:* 3 {{implicit instantiation of undefined template}} +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.pass.cpp new file mode 100644 index 0000000000000..24878a1d560e0 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <tuple> + +// template <class T> constexpr size_t tuple_size_v = tuple_size<T>::value; + +#include <tuple> +#include <utility> +#include <array> + +template <class Tuple, int Expect> +void test() +{ + static_assert(std::tuple_size_v<Tuple> == Expect, ""); + static_assert(std::tuple_size_v<Tuple> == std::tuple_size<Tuple>::value, ""); + static_assert(std::tuple_size_v<Tuple const> == std::tuple_size<Tuple>::value, ""); + static_assert(std::tuple_size_v<Tuple volatile> == std::tuple_size<Tuple>::value, ""); + static_assert(std::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/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp index 0d25edc4547b1..e5991df636f8b 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp @@ -143,7 +143,7 @@ int main() assert(!(t1 == t2)); assert(t1 != t2); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { typedef std::tuple<char, int, double> T1; typedef std::tuple<double, char, int> T2; diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp index eac84a9c35f6a..34aafb1e1347a 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp @@ -195,7 +195,7 @@ int main() assert(!(t1 > t2)); assert(!(t1 >= t2)); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { typedef std::tuple<char, int, double> T1; typedef std::tuple<double, char, int> T2; diff --git a/test/std/utilities/utility/as_const/as_const.pass.cpp b/test/std/utilities/utility/as_const/as_const.pass.cpp index ff3f84a5532fb..7bb5849d0bd05 100644 --- a/test/std/utilities/utility/as_const/as_const.pass.cpp +++ b/test/std/utilities/utility/as_const/as_const.pass.cpp @@ -27,7 +27,7 @@ void test(T& t) static_assert(std::is_const<typename std::remove_reference<decltype(std::as_const<const T>(t))>::type>::value, ""); static_assert(std::is_const<typename std::remove_reference<decltype(std::as_const<volatile T>(t))>::type>::value, ""); static_assert(std::is_const<typename std::remove_reference<decltype(std::as_const<const volatile T>(t))>::type>::value, ""); - + assert(std::as_const(t) == t); assert(std::as_const< T>(t) == t); assert(std::as_const<const T>(t) == t); diff --git a/test/std/utilities/utility/exchange/exchange.pass.cpp b/test/std/utilities/utility/exchange/exchange.pass.cpp index 620b4149d1d0b..5ef0ac3b09f52 100644 --- a/test/std/utilities/utility/exchange/exchange.pass.cpp +++ b/test/std/utilities/utility/exchange/exchange.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // utilities // exchange @@ -17,7 +18,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 { int v = 12; assert ( std::exchange ( v, 23 ) == 12 ); @@ -27,7 +27,7 @@ int main() assert ((std::exchange<int, float> ( v, {} )) == 67 ); assert ( v == 0 ); - + } { @@ -48,11 +48,9 @@ int main() s3 = s2; // Dad assert ( std::exchange ( s3, {} ) == s2 ); assert ( s3.size () == 0 ); - + s3 = s2; // Dad assert ( std::exchange ( s3, "" ) == s2 ); assert ( s3.size () == 0 ); } - -#endif } diff --git a/test/std/utilities/utility/forward/forward.pass.cpp b/test/std/utilities/utility/forward/forward.pass.cpp index 357b36fafa960..94575485df047 100644 --- a/test/std/utilities/utility/forward/forward.pass.cpp +++ b/test/std/utilities/utility/forward/forward.pass.cpp @@ -39,6 +39,9 @@ int main() A a; const A ca = A(); + ((void)a); // Prevent unused warning + ((void)ca); // Prevent unused warning + #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES static_assert(sizeof(test(std::forward<A&>(a))) == 1, ""); static_assert(sizeof(test(std::forward<A>(a))) == 4, ""); diff --git a/test/std/utilities/utility/pairs/pair.astuple/get_const.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/get_const.pass.cpp index fcda3664d9b62..9ef7bcff2ba83 100644 --- a/test/std/utilities/utility/pairs/pair.astuple/get_const.pass.cpp +++ b/test/std/utilities/utility/pairs/pair.astuple/get_const.pass.cpp @@ -18,6 +18,8 @@ #include <utility> #include <cassert> +#include "test_macros.h" + int main() { { @@ -27,7 +29,7 @@ int main() assert(std::get<1>(p) == 4); } -#if __cplusplus > 201103L +#if TEST_STD_VER > 11 { typedef std::pair<int, short> P; constexpr P p1(3, 4); diff --git a/test/std/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp index 6d61c47ffbf03..47b4c06134d97 100644 --- a/test/std/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp +++ b/test/std/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp @@ -18,7 +18,9 @@ #include <utility> #include <cassert> -#if __cplusplus > 201103L +#include "test_macros.h" + +#if TEST_STD_VER > 11 struct S { std::pair<int, int> a; int k; @@ -41,7 +43,7 @@ int main() assert(std::get<1>(p) == 6); } -#if __cplusplus > 201103L +#if TEST_STD_VER > 11 { static_assert(S().k == 1, ""); static_assert(std::get<1>(getP()) == 4, ""); diff --git a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type1.fail.cpp b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type1.fail.cpp index 27194effe5c32..f0d55a6618227 100644 --- a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type1.fail.cpp +++ b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type1.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <utility> #include <complex> @@ -14,11 +15,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 typedef std::complex<float> cf; auto t1 = std::make_pair<int, double> ( 42, 3.4 ); assert (( std::get<cf>(t1) == cf {1,2} )); // no such type -#else -#error -#endif } diff --git a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type2.fail.cpp b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type2.fail.cpp index f9e3942d7e773..72e637592483f 100644 --- a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type2.fail.cpp +++ b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type2.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <utility> #include <complex> @@ -14,11 +15,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 typedef std::complex<float> cf; auto t1 = std::make_pair<int, int> ( 42, 43 ); assert ( std::get<int>(t1) == 42 ); // two ints -#else -#error -#endif } diff --git a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type3.fail.cpp b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type3.fail.cpp index 484347345747d..d5179e4355b90 100644 --- a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type3.fail.cpp +++ b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type3.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <utility> #include <complex> @@ -14,11 +15,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 typedef std::unique_ptr<int> upint; std::pair<upint, int> t(upint(new int(4)), 23); upint p = std::get<upint>(t); -#else -#error -#endif } diff --git a/test/std/utilities/utility/pairs/pairs.pair/copy_ctor.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/copy_ctor.pass.cpp index 4b54f717045ad..1117db3297b85 100644 --- a/test/std/utilities/utility/pairs/pairs.pair/copy_ctor.pass.cpp +++ b/test/std/utilities/utility/pairs/pairs.pair/copy_ctor.pass.cpp @@ -16,6 +16,8 @@ #include <utility> #include <cassert> +#include "test_macros.h" + int main() { { @@ -25,10 +27,7 @@ int main() assert(p2.first == 3); assert(p2.second == 4); } - - static_assert((std::is_trivially_copy_constructible<std::pair<int, int> >::value), ""); - -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 { typedef std::pair<int, short> P1; constexpr P1 p1(3, 4); diff --git a/test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp index d83328b8f2d0c..97182d24d0217 100644 --- a/test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp +++ b/test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp @@ -13,9 +13,15 @@ // constexpr pair(); +// This test doesn't pass due to a constexpr bug in GCC 4.9 that fails +// to initialize any type without a user provided constructor in a constant +// expression (ie float). +// XFAIL: gcc-4.9 + // NOTE: The SFINAE on the default constructor is tested in // default-sfinae.pass.cpp + #include <utility> #include <type_traits> #include <cassert> diff --git a/test/std/utilities/utility/pairs/pairs.pair/move_ctor.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/move_ctor.pass.cpp new file mode 100644 index 0000000000000..06cb5e5658c90 --- /dev/null +++ b/test/std/utilities/utility/pairs/pairs.pair/move_ctor.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <utility> + +// template <class T1, class T2> struct pair + +// pair(pair&&) = default; + +#include <utility> +#include <memory> +#include <cassert> + +#include "test_macros.h" + +struct Dummy { + Dummy(Dummy const&) = delete; + Dummy(Dummy &&) = default; +}; + +int main() +{ + { + typedef std::pair<int, short> P1; + static_assert(std::is_move_constructible<P1>::value, ""); + P1 p1(3, 4); + P1 p2 = std::move(p1); + assert(p2.first == 3); + assert(p2.second == 4); + } + { + using P = std::pair<Dummy, int>; + static_assert(!std::is_copy_constructible<P>::value, ""); + static_assert(std::is_move_constructible<P>::value, ""); + } +} diff --git a/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp index 0ad5786bce29d..dfea61eeacdb0 100644 --- a/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp +++ b/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp @@ -17,7 +17,7 @@ #include <cassert> struct S { - int i; + int i; S() : i(0) {} S(int j) : i(j) {} S * operator& () { assert(false); return this; } diff --git a/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp new file mode 100644 index 0000000000000..53cf56700df88 --- /dev/null +++ b/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.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. +// +//===----------------------------------------------------------------------===// + +// <utility> + +// template <class T1, class T2> struct pair + +// pair(pair const&) = default; +// pair(pair&&) = default; + +// Doesn't pass due to use of is_trivially_* trait. +// XFAIL: gcc-4.9 + +#include <utility> +#include <cassert> + +#include "test_macros.h" + +struct Dummy { + Dummy(Dummy const&) = delete; + Dummy(Dummy &&) = default; +}; + +int main() +{ + typedef std::pair<int, short> P; + { + static_assert(std::is_copy_constructible<P>::value, ""); + static_assert(std::is_trivially_copy_constructible<P>::value, ""); + } +#if TEST_STD_VER >= 11 + { + static_assert(std::is_move_constructible<P>::value, ""); + static_assert(std::is_trivially_move_constructible<P>::value, ""); + } + { + using P1 = std::pair<Dummy, int>; + static_assert(!std::is_copy_constructible<P1>::value, ""); + static_assert(!std::is_trivially_copy_constructible<P1>::value, ""); + static_assert(std::is_move_constructible<P1>::value, ""); + static_assert(std::is_trivially_move_constructible<P1>::value, ""); + } +#endif +} diff --git a/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp b/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp index 48e09735abb02..4a6d71e7b9c85 100644 --- a/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp +++ b/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp @@ -23,7 +23,7 @@ int main() assert(p1.first == 3); assert(p1.second == 4); } - + #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::pair<std::unique_ptr<int>, short> P1; diff --git a/test/std/utilities/utility/synopsis.pass.cpp b/test/std/utilities/utility/synopsis.pass.cpp new file mode 100644 index 0000000000000..5f5b4eeaad524 --- /dev/null +++ b/test/std/utilities/utility/synopsis.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <utility> +// XFAIL: c++98, c++03 + +// #include <initializer_list> + +#include <utility> + +int main() +{ + std::initializer_list<int> x; +} + diff --git a/test/std/utilities/utility/utility.swap/swap.pass.cpp b/test/std/utilities/utility/utility.swap/swap.pass.cpp index 8606611f6603c..c9c9f3b527605 100644 --- a/test/std/utilities/utility/utility.swap/swap.pass.cpp +++ b/test/std/utilities/utility/utility.swap/swap.pass.cpp @@ -16,38 +16,88 @@ #include <utility> #include <cassert> -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES #include <memory> -#endif -void -test() -{ - int i = 1; - int j = 2; - std::swap(i, j); - assert(i == 2); - assert(j == 1); -} +#include "test_macros.h" -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if TEST_STD_VER >= 11 +struct CopyOnly { + CopyOnly() {} + CopyOnly(CopyOnly const&) noexcept {} + CopyOnly& operator=(CopyOnly const&) { return *this; } +}; -void -test1() -{ - std::unique_ptr<int> i(new int(1)); - std::unique_ptr<int> j(new int(2)); - std::swap(i, j); - assert(*i == 2); - assert(*j == 1); -} +struct MoveOnly { + MoveOnly() {} + MoveOnly(MoveOnly&&) {} + MoveOnly& operator=(MoveOnly&&) noexcept { return *this; } +}; + +struct NoexceptMoveOnly { + NoexceptMoveOnly() {} + NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {} + NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; } +}; + +struct NotMoveConstructible { + NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; } +private: + NotMoveConstructible(NotMoveConstructible&&); +}; + +struct NotMoveAssignable { + NotMoveAssignable(NotMoveAssignable&&); +private: + NotMoveAssignable& operator=(NotMoveAssignable&&); +}; + +template <class Tp> +auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>())); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +template <class Tp> +auto can_swap_test(...) -> std::false_type; + +template <class Tp> +constexpr bool can_swap() { + return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value; +} +#endif int main() { - test(); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - test1(); + + { + int i = 1; + int j = 2; + std::swap(i, j); + assert(i == 2); + assert(j == 1); + } +#if TEST_STD_VER >= 11 + { + + std::unique_ptr<int> i(new int(1)); + std::unique_ptr<int> j(new int(2)); + std::swap(i, j); + assert(*i == 2); + assert(*j == 1); + + } + { + // test that the swap + static_assert(can_swap<CopyOnly&>(), ""); + static_assert(can_swap<MoveOnly&>(), ""); + static_assert(can_swap<NoexceptMoveOnly&>(), ""); + + static_assert(!can_swap<NotMoveConstructible&>(), ""); + static_assert(!can_swap<NotMoveAssignable&>(), ""); + + CopyOnly c; + MoveOnly m; + NoexceptMoveOnly nm; + static_assert(!noexcept(std::swap(c, c)), ""); + static_assert(!noexcept(std::swap(m, m)), ""); + static_assert(noexcept(std::swap(nm, nm)), ""); + } #endif } diff --git a/test/std/utilities/utility/utility.swap/swap_array.pass.cpp b/test/std/utilities/utility/utility.swap/swap_array.pass.cpp index b1209c3c3651b..ad39934b20cac 100644 --- a/test/std/utilities/utility/utility.swap/swap_array.pass.cpp +++ b/test/std/utilities/utility/utility.swap/swap_array.pass.cpp @@ -16,50 +16,86 @@ #include <utility> #include <cassert> -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES #include <memory> -#endif -void -test() -{ - int i[3] = {1, 2, 3}; - int j[3] = {4, 5, 6}; - std::swap(i, j); - assert(i[0] == 4); - assert(i[1] == 5); - assert(i[2] == 6); - assert(j[0] == 1); - assert(j[1] == 2); - assert(j[2] == 3); -} +#include "test_macros.h" -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -void -test1() -{ - std::unique_ptr<int> i[3]; - for (int k = 0; k < 3; ++k) - i[k].reset(new int(k+1)); - std::unique_ptr<int> j[3]; - for (int k = 0; k < 3; ++k) - j[k].reset(new int(k+4)); - std::swap(i, j); - assert(*i[0] == 4); - assert(*i[1] == 5); - assert(*i[2] == 6); - assert(*j[0] == 1); - assert(*j[1] == 2); - assert(*j[2] == 3); +#if TEST_STD_VER >= 11 +struct CopyOnly { + CopyOnly() {} + CopyOnly(CopyOnly const&) noexcept {} + CopyOnly& operator=(CopyOnly const&) { return *this; } +}; + + +struct NoexceptMoveOnly { + NoexceptMoveOnly() {} + NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {} + NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; } +}; + +struct NotMoveConstructible { + NotMoveConstructible() {} + NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; } +private: + NotMoveConstructible(NotMoveConstructible&&); +}; + +template <class Tp> +auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>())); + +template <class Tp> +auto can_swap_test(...) -> std::false_type; + +template <class Tp> +constexpr bool can_swap() { + return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value; } +#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES int main() { - test(); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - test1(); + { + int i[3] = {1, 2, 3}; + int j[3] = {4, 5, 6}; + std::swap(i, j); + assert(i[0] == 4); + assert(i[1] == 5); + assert(i[2] == 6); + assert(j[0] == 1); + assert(j[1] == 2); + assert(j[2] == 3); + } +#if TEST_STD_VER >= 11 + { + std::unique_ptr<int> i[3]; + for (int k = 0; k < 3; ++k) + i[k].reset(new int(k+1)); + std::unique_ptr<int> j[3]; + for (int k = 0; k < 3; ++k) + j[k].reset(new int(k+4)); + std::swap(i, j); + assert(*i[0] == 4); + assert(*i[1] == 5); + assert(*i[2] == 6); + assert(*j[0] == 1); + assert(*j[1] == 2); + assert(*j[2] == 3); + } + { + using CA = CopyOnly[42]; + using MA = NoexceptMoveOnly[42]; + using NA = NotMoveConstructible[42]; + static_assert(can_swap<CA&>(), ""); + static_assert(can_swap<MA&>(), ""); + static_assert(!can_swap<NA&>(), ""); + + CA ca; + MA ma; + static_assert(!noexcept(std::swap(ca, ca)), ""); + static_assert(noexcept(std::swap(ma, ma)), ""); + } #endif } diff --git a/test/support/Counter.h b/test/support/Counter.h index 2bc3642f50594..eb6e04e72ef62 100644 --- a/test/support/Counter.h +++ b/test/support/Counter.h @@ -13,7 +13,7 @@ #include <functional> // for std::hash struct Counter_base { static int gConstructed; }; - + template <typename T> class Counter : public Counter_base { @@ -27,7 +27,7 @@ public: Counter& operator=(Counter&& rhs) { ++gConstructed; data_ = std::move(rhs.data_); return *this; } #endif ~Counter() { --gConstructed; } - + const T& get() const {return data_;} bool operator==(const Counter& x) const {return data_ == x.data_;} diff --git a/test/support/MoveOnly.h b/test/support/MoveOnly.h index ee6ae7c7e5f9e..a3e9cca89ee50 100644 --- a/test/support/MoveOnly.h +++ b/test/support/MoveOnly.h @@ -10,6 +10,8 @@ #ifndef MOVEONLY_H #define MOVEONLY_H +#include "test_macros.h" + #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES #include <cstddef> diff --git a/test/support/allocators.h b/test/support/allocators.h index 7c2103ff27216..4aa467f824aa6 100644 --- a/test/support/allocators.h +++ b/test/support/allocators.h @@ -101,7 +101,7 @@ public: A2& operator=(const A2& a) TEST_NOEXCEPT { id_ = a.id(); copy_called = true; return *this;} A2& operator=(A2&& a) TEST_NOEXCEPT { id_ = a.id(); move_called = true; return *this;} - T* allocate(std::size_t n, const void* hint) + T* allocate(std::size_t, const void* hint) { allocate_called = true; return (T*)hint; diff --git a/test/support/asan_testing.h b/test/support/asan_testing.h index 45ad04b1bb2ca..678f12a91b65a 100644 --- a/test/support/asan_testing.h +++ b/test/support/asan_testing.h @@ -10,12 +10,12 @@ #ifndef ASAN_TESTING_H #define ASAN_TESTING_H -#include <__config> +#include "test_macros.h" -#ifndef _LIBCPP_HAS_NO_ASAN +#if TEST_HAS_FEATURE(address_sanitizer) extern "C" int __sanitizer_verify_contiguous_container ( const void *beg, const void *mid, const void *end ); - + template <typename T, typename Alloc> bool is_contiguous_container_asan_correct ( const std::vector<T, Alloc> &c ) { @@ -27,11 +27,11 @@ bool is_contiguous_container_asan_correct ( const std::vector<T, Alloc> &c ) #else template <typename T, typename Alloc> -bool is_contiguous_container_asan_correct ( const std::vector<T, Alloc> &c ) +bool is_contiguous_container_asan_correct ( const std::vector<T, Alloc> &) { return true; } #endif - + #endif // ASAN_TESTING_H diff --git a/test/support/assert_checkpoint.h b/test/support/assert_checkpoint.h new file mode 100644 index 0000000000000..6627b35eb30d1 --- /dev/null +++ b/test/support/assert_checkpoint.h @@ -0,0 +1,73 @@ +#ifndef SUPPORT_ASSERT_CHECKPOINT_H +#define SUPPORT_ASSERT_CHECKPOINT_H + +#include <csignal> +#include <iostream> +#include <cstdlib> + +struct Checkpoint { + const char* file; + const char* func; + int line; + const char* msg; + + Checkpoint() : file(nullptr), func(nullptr), line(-1), msg(nullptr) {} + Checkpoint(const char* xfile, const char* xfunc, int xline, const char* xmsg) + : file(xfile), func(xfunc), line(xline), msg(xmsg) + {} + + template <class Stream> + void print(Stream& s) const { + if (!file) { + s << "NO CHECKPOINT\n"; + return; + } + s << file << ":" << line << " " << func << ": Checkpoint"; + if (msg) + s << " '" << msg << "'"; + s << std::endl; + } +}; + +inline Checkpoint& globalCheckpoint() { + static Checkpoint C; + return C; +} + +inline void clearCheckpoint() { + globalCheckpoint() = Checkpoint(); +} + +#if defined(__GNUC__) +#define CHECKPOINT_FUNCTION_NAME __PRETTY_FUNCTION__ +#else +#define CHECKPOINT_FUNCTION_NAME __func__ +#endif + +#define CHECKPOINT(msg) globalCheckpoint() = Checkpoint(__FILE__, CHECKPOINT_FUNCTION_NAME, __LINE__, msg); + +inline void checkpointSignalHandler(int signal) { + if (signal == SIGABRT) { + globalCheckpoint().print(std::cerr); + } else { + std::cerr << "Unexpected signal " << signal << " received\n"; + } + std::_Exit(EXIT_FAILURE); +} + +inline bool initCheckpointHandler() { + typedef void(*HandlerT)(int); + static bool isInit = false; + if (isInit) return true; + HandlerT prev_h = std::signal(SIGABRT, checkpointSignalHandler); + if (prev_h == SIG_ERR) { + std::cerr << "Setup failed.\n"; + std::_Exit(EXIT_FAILURE); + } + isInit = true; + return false; +} + +static bool initDummy = initCheckpointHandler(); + +#endif diff --git a/test/support/constexpr_char_traits.hpp b/test/support/constexpr_char_traits.hpp index b069c90076a2c..0a73d3ad1eadd 100644 --- a/test/support/constexpr_char_traits.hpp +++ b/test/support/constexpr_char_traits.hpp @@ -11,9 +11,9 @@ #ifndef _CONSTEXPR_CHAR_TRAITS #define _CONSTEXPR_CHAR_TRAITS -#include <__config> #include <string> +#include "test_macros.h" template <class _CharT> struct constexpr_char_traits @@ -24,41 +24,41 @@ struct constexpr_char_traits typedef std::streampos pos_type; typedef std::mbstate_t state_type; - static _LIBCPP_CONSTEXPR_AFTER_CXX11 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT + static TEST_CONSTEXPR_CXX14 void assign(char_type& __c1, const char_type& __c2) TEST_NOEXCEPT {__c1 = __c2;} - static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT + static TEST_CONSTEXPR bool eq(char_type __c1, char_type __c2) TEST_NOEXCEPT {return __c1 == __c2;} - static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT + static TEST_CONSTEXPR bool lt(char_type __c1, char_type __c2) TEST_NOEXCEPT {return __c1 < __c2;} - static _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(const char_type* __s1, const char_type* __s2, size_t __n); - static _LIBCPP_CONSTEXPR_AFTER_CXX11 size_t length(const char_type* __s); - static _LIBCPP_CONSTEXPR_AFTER_CXX11 const char_type* find(const char_type* __s, size_t __n, const char_type& __a); - static _LIBCPP_CONSTEXPR_AFTER_CXX11 char_type* move(char_type* __s1, const char_type* __s2, size_t __n); - static _LIBCPP_CONSTEXPR_AFTER_CXX11 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); - static _LIBCPP_CONSTEXPR_AFTER_CXX11 char_type* assign(char_type* __s, size_t __n, char_type __a); + static TEST_CONSTEXPR_CXX14 int compare(const char_type* __s1, const char_type* __s2, size_t __n); + static TEST_CONSTEXPR_CXX14 size_t length(const char_type* __s); + static TEST_CONSTEXPR_CXX14 const char_type* find(const char_type* __s, size_t __n, const char_type& __a); + static TEST_CONSTEXPR_CXX14 char_type* move(char_type* __s1, const char_type* __s2, size_t __n); + static TEST_CONSTEXPR_CXX14 char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); + static TEST_CONSTEXPR_CXX14 char_type* assign(char_type* __s, size_t __n, char_type __a); - static _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT + static TEST_CONSTEXPR int_type not_eof(int_type __c) TEST_NOEXCEPT {return eq_int_type(__c, eof()) ? ~eof() : __c;} - static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT + static TEST_CONSTEXPR char_type to_char_type(int_type __c) TEST_NOEXCEPT {return char_type(__c);} - static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT + static TEST_CONSTEXPR int_type to_int_type(char_type __c) TEST_NOEXCEPT {return int_type(__c);} - static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT + static TEST_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) TEST_NOEXCEPT {return __c1 == __c2;} - static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT + static TEST_CONSTEXPR int_type eof() TEST_NOEXCEPT {return int_type(EOF);} }; template <class _CharT> -_LIBCPP_CONSTEXPR_AFTER_CXX11 int +TEST_CONSTEXPR_CXX14 int constexpr_char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n) { for (; __n; --__n, ++__s1, ++__s2) @@ -72,7 +72,7 @@ constexpr_char_traits<_CharT>::compare(const char_type* __s1, const char_type* _ } template <class _CharT> -_LIBCPP_CONSTEXPR_AFTER_CXX11 size_t +TEST_CONSTEXPR_CXX14 size_t constexpr_char_traits<_CharT>::length(const char_type* __s) { size_t __len = 0; @@ -82,7 +82,7 @@ constexpr_char_traits<_CharT>::length(const char_type* __s) } template <class _CharT> -_LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT* +TEST_CONSTEXPR_CXX14 const _CharT* constexpr_char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a) { for (; __n; --__n) @@ -95,7 +95,7 @@ constexpr_char_traits<_CharT>::find(const char_type* __s, size_t __n, const char } template <class _CharT> -_LIBCPP_CONSTEXPR_AFTER_CXX11 _CharT* +TEST_CONSTEXPR_CXX14 _CharT* constexpr_char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n) { char_type* __r = __s1; @@ -115,7 +115,7 @@ constexpr_char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size } template <class _CharT> -_LIBCPP_CONSTEXPR_AFTER_CXX11 _CharT* +TEST_CONSTEXPR_CXX14 _CharT* constexpr_char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n) { _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); @@ -126,7 +126,7 @@ constexpr_char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size } template <class _CharT> -_LIBCPP_CONSTEXPR_AFTER_CXX11 _CharT* +TEST_CONSTEXPR_CXX14 _CharT* constexpr_char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a) { char_type* __r = __s; diff --git a/test/support/container_test_types.h b/test/support/container_test_types.h new file mode 100644 index 0000000000000..0b97f2e94e75a --- /dev/null +++ b/test/support/container_test_types.h @@ -0,0 +1,492 @@ +//===----------------------------------------------------------------------===// +// +// 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_CONTAINER_TEST_TYPES_H +#define SUPPORT_CONTAINER_TEST_TYPES_H + +// container_test_types.h - A set of types used for testing STL containers. +// The types container within this header are used to test the requirements in +// [container.requirements.general]. The header is made up of 3 main components: +// +// * test-types: 'CopyInsertable', 'MoveInsertable' and 'EmplaceConstructible' - +// These test types are used to test the container requirements of the same +// name. These test types use the global 'AllocatorConstructController' to +// assert that they are only constructed by the containers allocator. +// +// * test-allocator: 'ContainerTestAllocator' - This test allocator is used to +// test the portions of [container.requirements.general] that pertain to the +// containers allocator. The three primary jobs of the test allocator are: +// 1. Enforce that 'a.construct(...)' and 'a.destroy(...)' are only ever +// instantiated for 'Container::value_type'. +// 2. Provide a mechanism of checking calls to 'a.construct(Args...)'. +// Including controlling when and with what types 'a.construct(...)' +// may be called with. +// 3. Support the test types internals by controlling the global +// 'AllocatorConstructController' object. +// +// * 'AllocatorConstructController' - This type defines an interface for testing +// the construction of types using an allocator. This type is used to communicate +// between the test author, the containers allocator, and the types +// being constructed by the container. +// The controllers primary functions are: +// 1. Allow calls to 'a.construct(p, args...)' to be checked by a test. +// The test uses 'cc->expect<Args...>()' to specify that the allocator +// should expect one call to 'a.construct' with the specified argument +// types. +// 2. Controlling the value of 'cc->isInAllocatorConstruct()' within the +// 'construct' method. The test-types use this value to assert that +// they are being constructed by the allocator. +// +// 'AllocatorConstructController' enforces the Singleton pattern since the +// test-types, test-allocator and test need to share the same controller +// object. A pointer to the global controller is returned by +// 'getConstructController()'. +// +//---------------------------------------------------------------------------- +/* + * Usage: The following example checks that 'unordered_map::emplace(Args&&...)' + * with 'Args = [CopyInsertable<1> const&, CopyInsertible<2>&&]' + * calls 'alloc.construct(value_type*, Args&&...)' with the same types. + * + * // Typedefs for container + * using Key = CopyInsertible<1>; + * using Value = CopyInsertible<2>; + * using ValueTp = std::pair<const Key, Value>; + * using Alloc = ContainerTestAllocator<ValueTp, ValueTp>; + * using Map = std::unordered_map<Key, Value, std::hash<Key>, std::equal_to<Key>, Alloc>; + * + * // Get the global controller, reset it, and construct an allocator with + * // the controller. + * ConstructController* cc = getConstructController(); + * cc->reset(); + * + * // Create a Map and a Key and Value to insert. Note that the test-allocator + * // does not need to be given 'cc'. + * Map m; + * const Key k(1); + * Value v(1); + * + * // Tell the controller to expect a construction from the specified types. + * cc->expect<Key const&, Value&&>(); + * + * // Emplace the objects into the container. 'Alloc.construct(p, UArgs...)' + * // will assert 'cc->check<UArgs&&>()' is true which will consume + * // the call to 'cc->expect<...>()'. + * m.emplace(k, std::move(v)); + * + * // Assert that the "expect" was consumed by a matching "check" call within + * // Alloc. + * assert(!cc->unexpected()); + * + */ + +#include <functional> +#include <cassert> + +#include "test_macros.h" + +#if TEST_STD_VER < 11 +#error This header requires C++11 or greater +#endif + +namespace detail { +// TypeID - Represent a unique identifier for a type. TypeID allows equality +// comparisons between different types. +struct TypeID { + friend bool operator==(TypeID const& LHS, TypeID const& RHS) + {return LHS.m_id == RHS.m_id; } + friend bool operator!=(TypeID const& LHS, TypeID const& RHS) + {return LHS.m_id != RHS.m_id; } +private: + explicit constexpr TypeID(const int* xid) : m_id(xid) {} + const int* const m_id; + template <class T> friend class TypeInfo; +}; + +// TypeInfo - Represent information for the specified type 'T', including a +// unique TypeID. +template <class T> +class TypeInfo { +public: + typedef T value_type; + typedef TypeID ID; + static ID const& GetID() { static ID id(&dummy_addr); return id; } + +private: + static const int dummy_addr; +}; + +template <class L, class R> +inline bool operator==(TypeInfo<L> const&, TypeInfo<R> const&) +{ return std::is_same<L, R>::value; } + +template <class L, class R> +inline bool operator!=(TypeInfo<L> const& lhs, TypeInfo<R> const& rhs) +{ return !(lhs == rhs); } + +template <class T> +const int TypeInfo<T>::dummy_addr = 42; + +// makeTypeID - Return the TypeID for the specified type 'T'. +template <class T> +inline constexpr TypeID const& makeTypeID() { return TypeInfo<T>::GetID(); } + +template <class ...Args> +struct ArgumentListID {}; + +// makeArgumentID - Create and return a unique identifier for a given set +// of arguments. +template <class ...Args> +inline constexpr TypeID const& makeArgumentID() { + return makeTypeID<ArgumentListID<Args...>>(); +} + +} // namespace detail + +//===----------------------------------------------------------------------===// +// AllocatorConstructController +//===----------------------------------------------------------------------===// + +struct AllocatorConstructController { + const detail::TypeID* m_expected_args; + bool m_allow_constructions; + bool m_allow_unchecked; + int m_expected_count; + + void clear() { + m_expected_args = nullptr; + m_expected_count = -1; + } + + // Check for and consume an expected construction added by 'expect'. + // Return true if the construction was expected and false otherwise. + // This should only be called by 'Allocator.construct'. + bool check(detail::TypeID const& tid) { + if (!m_expected_args) + assert(m_allow_unchecked); + bool res = *m_expected_args == tid; + if (m_expected_count == -1 || --m_expected_count == -1) + m_expected_args = nullptr; + return res; + } + + // Return true iff there is an unchecked construction expression. + bool unchecked() { + return m_expected_args != nullptr; + } + + // Expect a call to Allocator::construct with Args that match 'tid'. + void expect(detail::TypeID const& tid) { + assert(!unchecked()); + m_expected_args = &tid; + } + + template <class ...Args> + void expect(int times = 1) { + assert(!unchecked()); + assert(times > 0); + m_expected_count = times - 1; + m_expected_args = &detail::makeArgumentID<Args...>(); + } + template <class ...Args> + bool check() { + return check(detail::makeArgumentID<Args...>()); + } + + + // Return true iff the program is currently within a call to "Allocator::construct" + bool isInAllocatorConstruct() const { + return m_allow_constructions; + } + + void inAllocatorConstruct(bool value = true) { + m_allow_constructions = value; + } + + void allowUnchecked(bool value = true) { + m_allow_unchecked = value; + } + + void reset() { + m_allow_constructions = false; + m_expected_args = nullptr; + m_allow_unchecked = false; + m_expected_count = -1; + } + +private: + friend AllocatorConstructController* getConstructController(); + AllocatorConstructController() { reset(); } + AllocatorConstructController(AllocatorConstructController const&); + AllocatorConstructController& operator=(AllocatorConstructController const&); +}; + +typedef AllocatorConstructController ConstructController; + +// getConstructController - Return the global allocator construction controller. +inline ConstructController* getConstructController() { + static ConstructController c; + return &c; +} + +//===----------------------------------------------------------------------===// +// ContainerTestAllocator +//===----------------------------------------------------------------------===// + +// ContainerTestAllocator - A STL allocator type that only allows 'construct' +// and 'destroy' to be called for 'AllowConstructT' types. ContainerTestAllocator +// uses the 'AllocatorConstructionController' interface. +template <class T, class AllowConstructT> +class ContainerTestAllocator +{ + struct InAllocatorConstructGuard { + ConstructController *m_cc; + bool m_old; + InAllocatorConstructGuard(ConstructController* cc) : m_cc(cc) { + if (m_cc) { + m_old = m_cc->isInAllocatorConstruct(); + m_cc->inAllocatorConstruct(true); + } + } + ~InAllocatorConstructGuard() { + if (m_cc) m_cc->inAllocatorConstruct(m_old); + } + private: + InAllocatorConstructGuard(InAllocatorConstructGuard const&); + InAllocatorConstructGuard& operator=(InAllocatorConstructGuard const&); + }; + +public: + typedef T value_type; + + int construct_called; + int destroy_called; + ConstructController* controller; + + ContainerTestAllocator() TEST_NOEXCEPT + : controller(getConstructController()) {} + + explicit ContainerTestAllocator(ConstructController* c) + : controller(c) + {} + + template <class U> + ContainerTestAllocator(ContainerTestAllocator<U, AllowConstructT> other) TEST_NOEXCEPT + : controller(other.controller) + {} + + T* allocate(std::size_t n) + { + return static_cast<T*>(::operator new(n*sizeof(T))); + } + + void deallocate(T* p, std::size_t) + { + return ::operator delete(static_cast<void*>(p)); + } + + template <class Up, class ...Args> + void construct(Up* p, Args&&... args) { + static_assert((std::is_same<Up, AllowConstructT>::value), + "Only allowed to construct Up"); + assert(controller->check<Args&&...>()); + { + InAllocatorConstructGuard g(controller); + ::new ((void*)p) Up(std::forward<Args>(args)...); + } + } + + template <class Up> + void destroy(Up* p) { + static_assert((std::is_same<Up, AllowConstructT>::value), + "Only allowed to destroy Up"); + { + InAllocatorConstructGuard g(controller); + p->~Up(); + } + } + + friend bool operator==(ContainerTestAllocator, ContainerTestAllocator) {return true;} + friend bool operator!=(ContainerTestAllocator x, ContainerTestAllocator y) {return !(x == y);} +}; + + +namespace test_detail { +typedef ContainerTestAllocator<int, int> A1; +typedef std::allocator_traits<A1> A1T; +typedef ContainerTestAllocator<float, int> A2; +typedef std::allocator_traits<A2> A2T; + +static_assert(std::is_same<A1T::rebind_traits<float>, A2T>::value, ""); +static_assert(std::is_same<A2T::rebind_traits<int>, A1T>::value, ""); +} // end namespace test_detail + +//===----------------------------------------------------------------------===// +// 'CopyInsertable', 'MoveInsertable' and 'EmplaceConstructible' test types +//===----------------------------------------------------------------------===// + +template <int Dummy = 0> +struct CopyInsertable { + int data; + mutable bool copied_once; + bool constructed_under_allocator; + + explicit CopyInsertable(int val) : data(val), copied_once(false), + constructed_under_allocator(false) { + if (getConstructController()->isInAllocatorConstruct()) { + copied_once = true; + constructed_under_allocator = true; + } + } + + CopyInsertable() : data(0), copied_once(false), constructed_under_allocator(true) + { + assert(getConstructController()->isInAllocatorConstruct()); + } + + CopyInsertable(CopyInsertable const& other) : data(other.data), + copied_once(true), + constructed_under_allocator(true) { + assert(getConstructController()->isInAllocatorConstruct()); + assert(other.copied_once == false); + other.copied_once = true; + } + + CopyInsertable(CopyInsertable& other) : data(other.data), copied_once(true), + constructed_under_allocator(true) { + assert(getConstructController()->isInAllocatorConstruct()); + assert(other.copied_once == false); + other.copied_once = true; + } + + CopyInsertable(CopyInsertable&& other) : CopyInsertable(other) {} + + // Forgive pair for not downcasting this to an lvalue it its constructors. + CopyInsertable(CopyInsertable const && other) : CopyInsertable(other) {} + + + template <class ...Args> + CopyInsertable(Args&&... args) { + assert(false); + } + + ~CopyInsertable() { + assert(constructed_under_allocator == getConstructController()->isInAllocatorConstruct()); + } + + void reset(int value) { + data = value; + copied_once = false; + constructed_under_allocator = false; + } +}; + +template <int ID> +bool operator==(CopyInsertable<ID> const& L, CopyInsertable<ID> const& R) { + return L.data == R.data; +} + + +template <int ID> +bool operator!=(CopyInsertable<ID> const& L, CopyInsertable<ID> const& R) { + return L.data != R.data; +} + +template <int ID> +bool operator <(CopyInsertable<ID> const& L, CopyInsertable<ID> const& R) { + return L.data < R.data; +} + + +#ifdef _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_STD +#else +namespace std { +#endif + template <int ID> + struct hash< ::CopyInsertable<ID> > { + typedef ::CopyInsertable<ID> argument_type; + typedef size_t result_type; + + size_t operator()(argument_type const& arg) const { + return arg.data; + } + }; + + template <class _Key, class _Value, class _Less, class _Alloc> + class map; + template <class _Key, class _Value, class _Less, class _Alloc> + class multimap; + template <class _Value, class _Less, class _Alloc> + class set; + template <class _Value, class _Less, class _Alloc> + class multiset; + template <class _Key, class _Value, class _Hash, class _Equals, class _Alloc> + class unordered_map; + template <class _Key, class _Value, class _Hash, class _Equals, class _Alloc> + class unordered_multimap; + template <class _Value, class _Hash, class _Equals, class _Alloc> + class unordered_set; + template <class _Value, class _Hash, class _Equals, class _Alloc> + class unordered_multiset; + +#ifdef _LIBCPP_END_NAMESPACE_STD +_LIBCPP_END_NAMESPACE_STD +#else +} // end namespace std +#endif + +// TCT - Test container type +namespace TCT { + +template <class Key = CopyInsertable<1>, class Value = CopyInsertable<2>, + class ValueTp = std::pair<const Key, Value> > +using unordered_map = + std::unordered_map<Key, Value, std::hash<Key>, std::equal_to<Key>, + ContainerTestAllocator<ValueTp, ValueTp> >; + +template <class Key = CopyInsertable<1>, class Value = CopyInsertable<2>, + class ValueTp = std::pair<const Key, Value> > +using map = + std::map<Key, Value, std::less<Key>, + ContainerTestAllocator<ValueTp, ValueTp> >; + +template <class Key = CopyInsertable<1>, class Value = CopyInsertable<2>, + class ValueTp = std::pair<const Key, Value> > +using unordered_multimap = + std::unordered_multimap<Key, Value, std::hash<Key>, std::equal_to<Key>, + ContainerTestAllocator<ValueTp, ValueTp> >; + +template <class Key = CopyInsertable<1>, class Value = CopyInsertable<2>, + class ValueTp = std::pair<const Key, Value> > +using multimap = + std::multimap<Key, Value, std::less<Key>, + ContainerTestAllocator<ValueTp, ValueTp> >; + +template <class Value = CopyInsertable<1> > +using unordered_set = + std::unordered_set<Value, std::hash<Value>, std::equal_to<Value>, + ContainerTestAllocator<Value, Value> >; + +template <class Value = CopyInsertable<1> > +using set = + std::set<Value, std::less<Value>, ContainerTestAllocator<Value, Value> >; + +template <class Value = CopyInsertable<1> > +using unordered_multiset = + std::unordered_multiset<Value, std::hash<Value>, std::equal_to<Value>, + ContainerTestAllocator<Value, Value> >; + +template <class Value = CopyInsertable<1> > +using multiset = + std::multiset<Value, std::less<Value>, ContainerTestAllocator<Value, Value> >; + +} // end namespace TCT + + +#endif // SUPPORT_CONTAINER_TEST_TYPES_H diff --git a/test/support/count_new.hpp b/test/support/count_new.hpp index e8968a93de980..923e495134871 100644 --- a/test/support/count_new.hpp +++ b/test/support/count_new.hpp @@ -14,16 +14,24 @@ # include <cassert> # include <new> -#ifndef __has_feature -# define __has_feature(x) 0 -#endif +#include "test_macros.h" -#if __has_feature(address_sanitizer) \ - || __has_feature(memory_sanitizer) \ - || __has_feature(thread_sanitizer) +#if defined(TEST_HAS_SANITIZERS) #define DISABLE_NEW_COUNT #endif +namespace detail +{ + TEST_NORETURN + inline void throw_bad_alloc_helper() { +#ifndef TEST_HAS_NO_EXCEPTIONS + throw std::bad_alloc(); +#else + std::abort(); +#endif + } +} + class MemCounter { public: @@ -43,6 +51,11 @@ public: // code doesn't perform any allocations. bool disable_allocations; + // number of allocations to throw after. Default (unsigned)-1. If + // throw_after has the default value it will never be decremented. + static const unsigned never_throw_value = static_cast<unsigned>(-1); + unsigned throw_after; + int outstanding_new; int new_called; int delete_called; @@ -58,6 +71,12 @@ public: { assert(disable_allocations == false); assert(s); + if (throw_after == 0) { + throw_after = never_throw_value; + detail::throw_bad_alloc_helper(); + } else if (throw_after != never_throw_value) { + --throw_after; + } ++new_called; ++outstanding_new; last_new_size = s; @@ -74,6 +93,12 @@ public: { assert(disable_allocations == false); assert(s); + if (throw_after == 0) { + throw_after = never_throw_value; + detail::throw_bad_alloc_helper(); + } else { + // don't decrement throw_after here. newCalled will end up doing that. + } ++outstanding_array_new; ++new_array_called; last_new_array_size = s; @@ -96,9 +121,11 @@ public: disable_allocations = false; } + void reset() { disable_allocations = false; + throw_after = never_throw_value; outstanding_new = 0; new_called = 0; @@ -132,6 +159,11 @@ public: return disable_checking || n != new_called; } + bool checkNewCalledGreaterThan(int n) const + { + return disable_checking || new_called > n; + } + bool checkDeleteCalledEq(int n) const { return disable_checking || n == delete_called; @@ -205,7 +237,10 @@ MemCounter globalMemCounter((MemCounter::MemCounterCtorArg_())); void* operator new(std::size_t s) throw(std::bad_alloc) { globalMemCounter.newCalled(s); - return std::malloc(s); + void* ret = std::malloc(s); + if (ret == nullptr) + detail::throw_bad_alloc_helper(); + return ret; } void operator delete(void* p) throw() @@ -255,4 +290,33 @@ private: DisableAllocationGuard& operator=(DisableAllocationGuard const&); }; + +struct RequireAllocationGuard { + explicit RequireAllocationGuard(std::size_t RequireAtLeast = 1) + : m_req_alloc(RequireAtLeast), + m_new_count_on_init(globalMemCounter.new_called), + m_outstanding_new_on_init(globalMemCounter.outstanding_new), + m_exactly(false) + { + } + + void requireAtLeast(std::size_t N) { m_req_alloc = N; m_exactly = false; } + void requireExactly(std::size_t N) { m_req_alloc = N; m_exactly = true; } + + ~RequireAllocationGuard() { + assert(globalMemCounter.checkOutstandingNewEq(m_outstanding_new_on_init)); + std::size_t Expect = m_new_count_on_init + m_req_alloc; + assert(globalMemCounter.checkNewCalledEq(Expect) || + (!m_exactly && globalMemCounter.checkNewCalledGreaterThan(Expect))); + } + +private: + std::size_t m_req_alloc; + const std::size_t m_new_count_on_init; + const std::size_t m_outstanding_new_on_init; + bool m_exactly; + RequireAllocationGuard(RequireAllocationGuard const&); + RequireAllocationGuard& operator=(RequireAllocationGuard const&); +}; + #endif /* COUNT_NEW_HPP */ diff --git a/test/support/counting_predicates.hpp b/test/support/counting_predicates.hpp index aab6a9785772c..2bd1426934e51 100644 --- a/test/support/counting_predicates.hpp +++ b/test/support/counting_predicates.hpp @@ -16,11 +16,11 @@ struct unary_counting_predicate : public std::unary_function<Arg, bool> { public: unary_counting_predicate(Predicate p) : p_(p), count_(0) {} ~unary_counting_predicate() {} - + bool operator () (const Arg &a) const { ++count_; return p_(a); } size_t count() const { return count_; } void reset() { count_ = 0; } - + private: Predicate p_; mutable size_t count_; @@ -33,7 +33,7 @@ public: binary_counting_predicate ( Predicate p ) : p_(p), count_(0) {} ~binary_counting_predicate() {} - + bool operator () (const Arg1 &a1, const Arg2 &a2) const { ++count_; return p_(a1, a2); } size_t count() const { return count_; } void reset() { count_ = 0; } diff --git a/test/support/disable_missing_braces_warning.h b/test/support/disable_missing_braces_warning.h index 97fd8a89a51a3..c53eef8a951d1 100644 --- a/test/support/disable_missing_braces_warning.h +++ b/test/support/disable_missing_braces_warning.h @@ -11,6 +11,8 @@ // std::array is explicitly allowed to be initialized with A a = { init-list };. // Disable the missing braces warning for this reason. +#if defined(__GNUC__) #pragma GCC diagnostic ignored "-Wmissing-braces" +#endif #endif // SUPPORT_DISABLE_MISSING_BRACES_WARNING_H diff --git a/test/support/filesystem_dynamic_test_helper.py b/test/support/filesystem_dynamic_test_helper.py new file mode 100644 index 0000000000000..1f48c95279829 --- /dev/null +++ b/test/support/filesystem_dynamic_test_helper.py @@ -0,0 +1,85 @@ +import sys +import os +import stat + +# Ensure that this is being run on a specific platform +assert sys.platform.startswith('linux') or sys.platform.startswith('darwin') \ + or sys.platform.startswith('cygwin') or sys.platform.startswith('freebsd') + +def env_path(): + ep = os.environ.get('LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT') + assert ep is not None + ep = os.path.realpath(ep) + assert os.path.isdir(ep) + return ep + +env_path_global = env_path() + +# Make sure we don't try and write outside of env_path. +# All paths used should be sanitized +def sanitize(p): + p = os.path.realpath(p) + if os.path.commonprefix([env_path_global, p]): + return p + assert False + +""" +Some of the tests restrict permissions to induce failures. +Before we delete the test enviroment, we have to walk it and re-raise the +permissions. +""" +def clean_recursive(root_p): + if not os.path.islink(root_p): + os.chmod(root_p, 0o777) + for ent in os.listdir(root_p): + p = os.path.join(root_p, ent) + if os.path.islink(p) or not os.path.isdir(p): + os.remove(p) + else: + assert os.path.isdir(p) + clean_recursive(p) + os.rmdir(p) + + +def init_test_directory(root_p): + root_p = sanitize(root_p) + assert not os.path.exists(root_p) + os.makedirs(root_p) + + +def destroy_test_directory(root_p): + root_p = sanitize(root_p) + clean_recursive(root_p) + os.rmdir(root_p) + + +def create_file(fname, size): + with open(sanitize(fname), 'w') as f: + f.write('c' * size) + + +def create_dir(dname): + os.mkdir(sanitize(dname)) + + +def create_symlink(source, link): + os.symlink(sanitize(source), sanitize(link)) + + +def create_hardlink(source, link): + os.link(sanitize(source), sanitize(link)) + + +def create_fifo(source): + os.mkfifo(sanitize(source)) + + +def create_socket(source): + mode = 0600|stat.S_IFSOCK + os.mknod(sanitize(source), mode) + + +if __name__ == '__main__': + command = " ".join(sys.argv[1:]) + eval(command) + sys.exit(0) diff --git a/test/support/filesystem_test_helper.hpp b/test/support/filesystem_test_helper.hpp new file mode 100644 index 0000000000000..7150f79739b61 --- /dev/null +++ b/test/support/filesystem_test_helper.hpp @@ -0,0 +1,403 @@ +#ifndef FILESYSTEM_TEST_HELPER_HPP +#define FILESYSTEM_TEST_HELPER_HPP + +#include <experimental/filesystem> +#include <cassert> +#include <cstdio> // for printf +#include <string> +#include <fstream> +#include <random> +#include <chrono> + +namespace fs = std::experimental::filesystem; + +// static test helpers + +#ifndef LIBCXX_FILESYSTEM_STATIC_TEST_ROOT +#warning "STATIC TESTS DISABLED" +#else // LIBCXX_FILESYSTEM_STATIC_TEST_ROOT + +namespace StaticEnv { + +inline fs::path makePath(fs::path const& p) { + // env_path is expected not to contain symlinks. + static const fs::path env_path = LIBCXX_FILESYSTEM_STATIC_TEST_ROOT; + return env_path / p; +} + +static const fs::path Root = LIBCXX_FILESYSTEM_STATIC_TEST_ROOT; + +static const fs::path TestFileList[] = { + makePath("empty_file"), + makePath("non_empty_file"), + makePath("dir1/file1"), + makePath("dir1/file2") +}; +const std::size_t TestFileListSize = sizeof(TestFileList) / sizeof(fs::path); + +static const fs::path TestDirList[] = { + makePath("dir1"), + makePath("dir1/dir2"), + makePath("dir1/dir2/dir3") +}; +const std::size_t TestDirListSize = sizeof(TestDirList) / sizeof(fs::path); + +static const fs::path File = TestFileList[0]; +static const fs::path Dir = TestDirList[0]; +static const fs::path Dir2 = TestDirList[1]; +static const fs::path Dir3 = TestDirList[2]; +static const fs::path SymlinkToFile = makePath("symlink_to_empty_file"); +static const fs::path SymlinkToDir = makePath("symlink_to_dir"); +static const fs::path BadSymlink = makePath("bad_symlink"); +static const fs::path DNE = makePath("DNE"); +static const fs::path EmptyFile = TestFileList[0]; +static const fs::path NonEmptyFile = TestFileList[1]; +static const fs::path CharFile = "/dev/null"; // Hopefully this exists + +static const fs::path DirIterationList[] = { + makePath("dir1/dir2"), + makePath("dir1/file1"), + makePath("dir1/file2") +}; +const std::size_t DirIterationListSize = sizeof(DirIterationList) + / sizeof(fs::path); + +static const fs::path DirIterationListDepth1[] = { + makePath("dir1/dir2/afile3"), + makePath("dir1/dir2/dir3"), + makePath("dir1/dir2/symlink_to_dir3"), + makePath("dir1/dir2/file4"), +}; + +static const fs::path RecDirIterationList[] = { + makePath("dir1/dir2"), + makePath("dir1/file1"), + makePath("dir1/file2"), + makePath("dir1/dir2/afile3"), + makePath("dir1/dir2/dir3"), + makePath("dir1/dir2/symlink_to_dir3"), + makePath("dir1/dir2/file4"), + makePath("dir1/dir2/dir3/file5") +}; + +static const fs::path RecDirFollowSymlinksIterationList[] = { + makePath("dir1/dir2"), + makePath("dir1/file1"), + makePath("dir1/file2"), + makePath("dir1/dir2/afile3"), + makePath("dir1/dir2/dir3"), + makePath("dir1/dir2/file4"), + makePath("dir1/dir2/dir3/file5"), + makePath("dir1/dir2/symlink_to_dir3"), + makePath("dir1/dir2/symlink_to_dir3/file5"), +}; + +} // namespace StaticEnv + +#endif // LIBCXX_FILESYSTEM_STATIC_TEST_ROOT + +#ifndef LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT +#warning LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT must be defined +#else // LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT + +#ifndef LIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER +#error LIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER must be defined +#endif + +struct scoped_test_env +{ + scoped_test_env() : test_root(random_env_path()) + { fs_helper_run(fs_make_cmd("init_test_directory", test_root)); } + + ~scoped_test_env() + { fs_helper_run(fs_make_cmd("destroy_test_directory", test_root)); } + + scoped_test_env(scoped_test_env const &) = delete; + scoped_test_env & operator=(scoped_test_env const &) = delete; + + fs::path make_env_path(std::string p) { return sanitize_path(p); } + + std::string sanitize_path(std::string raw) { + assert(raw.find("..") == std::string::npos); + std::string const& root = test_root.native(); + if (root.compare(0, root.size(), raw, 0, root.size()) != 0) { + assert(raw.front() != '\\'); + fs::path tmp(test_root); + tmp /= raw; + return std::move(const_cast<std::string&>(tmp.native())); + } + return raw; + } + + std::string create_file(std::string filename, std::size_t size = 0) { + filename = sanitize_path(std::move(filename)); + std::string out_str(size, 'a'); + { + std::ofstream out(filename.c_str()); + out << out_str; + } + return filename; + } + + std::string create_dir(std::string filename) { + filename = sanitize_path(std::move(filename)); + fs_helper_run(fs_make_cmd("create_dir", filename)); + return filename; + } + + std::string create_symlink(std::string source, std::string to) { + source = sanitize_path(std::move(source)); + to = sanitize_path(std::move(to)); + fs_helper_run(fs_make_cmd("create_symlink", source, to)); + return to; + } + + std::string create_hardlink(std::string source, std::string to) { + source = sanitize_path(std::move(source)); + to = sanitize_path(std::move(to)); + fs_helper_run(fs_make_cmd("create_hardlink", source, to)); + return to; + } + + std::string create_fifo(std::string file) { + file = sanitize_path(std::move(file)); + fs_helper_run(fs_make_cmd("create_fifo", file)); + return file; + } + + // OS X and FreeBSD doesn't support socket files so we shouldn't even + // allow tests to call this unguarded. +#if !defined(__FreeBSD__) && !defined(__APPLE__) + std::string create_socket(std::string file) { + file = sanitize_path(std::move(file)); + fs_helper_run(fs_make_cmd("create_socket", file)); + return file; + } +#endif + + fs::path const test_root; + +private: + static char to_hex(int ch) { + return ch < 10 ? static_cast<char>('0' + ch) + : static_cast<char>('a' + (ch - 10)); + } + + static char random_hex_char() { + static std::mt19937 rd { std::random_device{}() }; + static std::uniform_int_distribution<int> mrand{0, 15}; + return to_hex( mrand(rd) ); + } + + static std::string unique_path_suffix() { + std::string model = "test.%%%%%%"; + for (auto & ch : model) { + if (ch == '%') ch = random_hex_char(); + } + return model; + } + + // This could potentially introduce a filesystem race with other tests + // running at the same time, but oh well, it's just test code. + static inline fs::path random_env_path() { + static const char* env_path = LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT; + fs::path p = fs::path(env_path) / unique_path_suffix(); + assert(p.parent_path() == env_path); + return p; + } + + static inline std::string make_arg(std::string const& arg) { + return "'" + arg + "'"; + } + + static inline std::string make_arg(std::size_t arg) { + return std::to_string(arg); + } + + template <class T> + static inline std::string + fs_make_cmd(std::string const& cmd_name, T const& arg) { + return cmd_name + "(" + make_arg(arg) + ")"; + } + + template <class T, class U> + static inline std::string + fs_make_cmd(std::string const& cmd_name, T const& arg1, U const& arg2) { + return cmd_name + "(" + make_arg(arg1) + ", " + make_arg(arg2) + ")"; + } + + static inline void fs_helper_run(std::string const& raw_cmd) { + // check that the fs test root in the enviroment matches what we were + // compiled with. + static bool checked = checkDynamicTestRoot(); + std::string cmd = LIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER; + cmd += " \"" + raw_cmd + "\""; + int ret = std::system(cmd.c_str()); + assert(ret == 0); + } + + static bool checkDynamicTestRoot() { + // LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT is expected not to contain symlinks. + char* fs_root = std::getenv("LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT"); + if (!fs_root) { + std::printf("ERROR: LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT must be a defined " + "environment variable when running the test.\n"); + std::abort(); + } + if (std::string(fs_root) != LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT) { + std::printf("ERROR: LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT enviroment variable" + " must have the same value as when the test was compiled.\n"); + std::printf(" Current Value: '%s'\n", fs_root); + std::printf(" Expected Value: '%s'\n", LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT); + std::abort(); + } + return true; + } + +}; + +#endif // LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT + +// Misc test types + +#define CONCAT2(LHS, RHS) LHS##RHS +#define CONCAT(LHS, RHS) CONCAT2(LHS, RHS) +#define MKSTR(Str) {Str, CONCAT(L, Str), CONCAT(u, Str), CONCAT(U, Str)} + +struct MultiStringType { + const char* s; + const wchar_t* w; + const char16_t* u16; + const char32_t* u32; + + operator const char* () const { return s; } + operator const wchar_t* () const { return w; } + operator const char16_t* () const { return u16; } + operator const char32_t* () const { return u32; } +}; + +const MultiStringType PathList[] = { + MKSTR(""), + MKSTR(" "), + MKSTR("//"), + MKSTR("."), + MKSTR(".."), + MKSTR("foo"), + MKSTR("/"), + MKSTR("/foo"), + MKSTR("foo/"), + MKSTR("/foo/"), + MKSTR("foo/bar"), + MKSTR("/foo/bar"), + MKSTR("//net"), + MKSTR("//net/foo"), + MKSTR("///foo///"), + MKSTR("///foo///bar"), + MKSTR("/."), + MKSTR("./"), + MKSTR("/.."), + MKSTR("../"), + MKSTR("foo/."), + MKSTR("foo/.."), + MKSTR("foo/./"), + MKSTR("foo/./bar"), + MKSTR("foo/../"), + MKSTR("foo/../bar"), + MKSTR("c:"), + MKSTR("c:/"), + MKSTR("c:foo"), + MKSTR("c:/foo"), + MKSTR("c:foo/"), + MKSTR("c:/foo/"), + MKSTR("c:/foo/bar"), + MKSTR("prn:"), + MKSTR("c:\\"), + MKSTR("c:\\foo"), + MKSTR("c:foo\\"), + MKSTR("c:\\foo\\"), + MKSTR("c:\\foo/"), + MKSTR("c:/foo\\bar"), + MKSTR("//"), + MKSTR("/finally/we/need/one/really/really/really/really/really/really/really/long/string") +}; +const unsigned PathListSize = sizeof(PathList) / sizeof(MultiStringType); + +template <class Iter> +Iter IterEnd(Iter B) { + using VT = typename std::iterator_traits<Iter>::value_type; + for (; *B != VT{}; ++B) + ; + return B; +} + +template <class CharT> +const CharT* StrEnd(CharT const* P) { + return IterEnd(P); +} + +template <class CharT> +std::size_t StrLen(CharT const* P) { + return StrEnd(P) - P; +} + +// Testing the allocation behavior of the code_cvt functions requires +// *knowing* that the allocation was not done by "path::__str_". +// This hack forces path to allocate enough memory. +inline void PathReserve(fs::path& p, std::size_t N) { + auto const& native_ref = p.native(); + const_cast<std::string&>(native_ref).reserve(N); +} + +template <class Iter1, class Iter2> +bool checkCollectionsEqual( + Iter1 start1, Iter1 const end1 + , Iter2 start2, Iter2 const end2 + ) +{ + while (start1 != end1 && start2 != end2) { + if (*start1 != *start2) { + return false; + } + ++start1; ++start2; + } + return (start1 == end1 && start2 == end2); +} + + +template <class Iter1, class Iter2> +bool checkCollectionsEqualBackwards( + Iter1 const start1, Iter1 end1 + , Iter2 const start2, Iter2 end2 + ) +{ + while (start1 != end1 && start2 != end2) { + --end1; --end2; + if (*end1 != *end2) { + return false; + } + } + return (start1 == end1 && start2 == end2); +} + +// We often need to test that the error_code was cleared if no error occurs +// this function returns a error_code which is set to an error that will +// never be returned by the filesystem functions. +inline std::error_code GetTestEC() { + return std::make_error_code(std::errc::address_family_not_supported); +} + +// Provide our own Sleep routine since std::this_thread::sleep_for is not +// available in single-threaded mode. +void SleepFor(std::chrono::seconds dur) { + using namespace std::chrono; +#if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) + using Clock = system_clock; +#else + using Clock = steady_clock; +#endif + const auto wake_time = Clock::now() + dur; + while (Clock::now() < wake_time) + ; +} + +#endif /* FILESYSTEM_TEST_HELPER_HPP */ diff --git a/test/support/hexfloat.h b/test/support/hexfloat.h index 7ef093714fed0..19008d1d54abb 100644 --- a/test/support/hexfloat.h +++ b/test/support/hexfloat.h @@ -15,7 +15,6 @@ #ifndef HEXFLOAT_H #define HEXFLOAT_H -#include <algorithm> #include <cmath> #include <climits> @@ -23,13 +22,26 @@ template <class T> class hexfloat { T value_; + + static int CountLeadingZeros(unsigned long long n) { + const std::size_t Digits = sizeof(unsigned long long) * CHAR_BIT; + const unsigned long long TopBit = 1ull << (Digits - 1); + if (n == 0) return Digits; + int LeadingZeros = 0; + while ((n & TopBit) == 0) { + ++LeadingZeros; + n <<= 1; + } + return LeadingZeros; + } + public: hexfloat(long long m1, unsigned long long m0, int exp) { - const std::size_t n = sizeof(unsigned long long) * CHAR_BIT; + const std::size_t Digits = sizeof(unsigned long long) * CHAR_BIT; int s = m1 < 0 ? -1 : 1; - value_ = std::ldexp(m1 + s * std::ldexp(T(m0), -static_cast<int>(n - - std::__clz(m0)/4*4)), exp); + int exp2 = -static_cast<int>(Digits - CountLeadingZeros(m0)/4*4); + value_ = std::ldexp(m1 + s * std::ldexp(T(m0), exp2), exp); } operator T() const {return value_;} diff --git a/test/support/is_transparent.h b/test/support/is_transparent.h index 58255248abc9c..d76b00536b526 100644 --- a/test/support/is_transparent.h +++ b/test/support/is_transparent.h @@ -10,7 +10,7 @@ #ifndef TRANSPARENT_H #define TRANSPARENT_H -// testing transparent +// testing transparent #if _LIBCPP_STD_VER > 11 struct transparent_less @@ -63,7 +63,7 @@ struct C2Int { // comparable to int 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; } diff --git a/test/support/min_allocator.h b/test/support/min_allocator.h index 5e3ae5d2a136b..701159e0481a2 100644 --- a/test/support/min_allocator.h +++ b/test/support/min_allocator.h @@ -11,6 +11,9 @@ #define MIN_ALLOCATOR_H #include <cstddef> +#include <cstdlib> +#include <cstddef> +#include <cassert> #include "test_macros.h" @@ -39,8 +42,59 @@ public: friend bool operator!=(bare_allocator x, bare_allocator y) {return !(x == y);} }; +struct malloc_allocator_base { + static size_t alloc_count; + static size_t dealloc_count; + static bool disable_default_constructor; + + static size_t outstanding_alloc() { + assert(alloc_count >= dealloc_count); + return (alloc_count - dealloc_count); + } + + static void reset() { + assert(outstanding_alloc() == 0); + disable_default_constructor = false; + alloc_count = 0; + dealloc_count = 0; + } +}; + + +size_t malloc_allocator_base::alloc_count = 0; +size_t malloc_allocator_base::dealloc_count = 0; +bool malloc_allocator_base::disable_default_constructor = false; + + +template <class T> +class malloc_allocator : public malloc_allocator_base +{ +public: + typedef T value_type; + + malloc_allocator() TEST_NOEXCEPT { assert(!disable_default_constructor); } + + template <class U> + malloc_allocator(malloc_allocator<U>) TEST_NOEXCEPT {} + + T* allocate(std::size_t n) + { + ++alloc_count; + return static_cast<T*>(std::malloc(n*sizeof(T))); + } + + void deallocate(T* p, std::size_t) + { + ++dealloc_count; + std::free(static_cast<void*>(p)); + } + + friend bool operator==(malloc_allocator, malloc_allocator) {return true;} + friend bool operator!=(malloc_allocator x, malloc_allocator y) {return !(x == y);} +}; + -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 #include <memory> @@ -286,6 +340,6 @@ public: friend bool operator!=(min_allocator x, min_allocator y) {return !(x == y);} }; -#endif // __cplusplus >= 201103L +#endif // TEST_STD_VER >= 11 #endif // MIN_ALLOCATOR_H diff --git a/test/support/nasty_containers.hpp b/test/support/nasty_containers.hpp index 5a2e19505424b..b571469227d41 100644 --- a/test/support/nasty_containers.hpp +++ b/test/support/nasty_containers.hpp @@ -7,9 +7,10 @@ // //===----------------------------------------------------------------------===// -#ifndef NASTY_VECTOR_H -#define NASTY_VECTOR_H +#ifndef NASTY_CONTAINERS_H +#define NASTY_CONTAINERS_H +#include <cassert> #include <vector> #include <list> @@ -99,7 +100,7 @@ public: { return v_.emplace(pos, std::forward<Args>(args)...); } #endif #endif - + iterator insert(const_iterator pos, const value_type& x) { return v_.insert(pos, x); } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES iterator insert(const_iterator pos, value_type&& x) { return v_.insert(pos, std::forward<value_type>(x)); } @@ -123,10 +124,10 @@ public: void swap(nasty_vector &nv) _NOEXCEPT_(std::__is_nothrow_swappable<nested_container>::value) { v_.swap(nv.v_); } - - nasty_vector *operator &() { return nullptr; } // nasty - const nasty_vector *operator &() const { return nullptr; } // nasty - + + nasty_vector *operator &() { assert(false); return nullptr; } // nasty + const nasty_vector *operator &() const { assert(false); return nullptr; } // nasty + nested_container v_; }; @@ -220,7 +221,7 @@ public: { return l_.emplace(pos, std::forward<Args>(args)...); } #endif #endif - + iterator insert(const_iterator pos, const value_type& x) { return l_.insert(pos, x); } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES iterator insert(const_iterator pos, value_type&& x) { return l_.insert(pos, std::forward<value_type>(x)); } @@ -242,7 +243,7 @@ public: void swap(nasty_list &nl) _NOEXCEPT_(std::__is_nothrow_swappable<nested_container>::value) { l_.swap(nl.l_); } - + void clear() _NOEXCEPT { l_.clear(); } // void splice(const_iterator position, list& x); @@ -253,7 +254,7 @@ public: // const_iterator last); // void splice(const_iterator position, list&& x, const_iterator first, // const_iterator last); -// +// // void remove(const value_type& value); // template <class Pred> void remove_if(Pred pred); // void unique(); @@ -270,8 +271,8 @@ public: // void sort(Compare comp); // void reverse() noexcept; - nasty_list *operator &() { return nullptr; } // nasty - const nasty_list *operator &() const { return nullptr; } // nasty + nasty_list *operator &() { assert(false); return nullptr; } // nasty + const nasty_list *operator &() const { assert(false); return nullptr; } // nasty nested_container l_; }; @@ -279,4 +280,30 @@ public: template <class T> bool operator==(const nasty_list<T>& x, const nasty_list<T>& y) { return x.l_ == y.l_; } +// Not really a mutex, but can play one in tests +class nasty_mutex +{ +public: + nasty_mutex() _NOEXCEPT {} + ~nasty_mutex() {} + + nasty_mutex *operator& () { assert(false); return nullptr; } + template <typename T> + void operator, (const T &) { assert(false); } + +private: + nasty_mutex(const nasty_mutex&) { assert(false); } + nasty_mutex& operator=(const nasty_mutex&) { assert(false); return *this; } + +public: + void lock() {} + bool try_lock() _NOEXCEPT { return true; } + void unlock() _NOEXCEPT {} + + // Shared ownership + void lock_shared() {} + bool try_lock_shared() { return true; } + void unlock_shared() {} +}; + #endif diff --git a/test/support/platform_support.h b/test/support/platform_support.h index 233e721ff5155..f4c2247e0dfbc 100644 --- a/test/support/platform_support.h +++ b/test/support/platform_support.h @@ -15,8 +15,6 @@ #ifndef PLATFORM_SUPPORT_H #define PLATFORM_SUPPORT_H -#include <__config> - // locale names #ifdef _WIN32 // WARNING: Windows does not support UTF-8 codepages. @@ -54,8 +52,8 @@ #include <stdio.h> #include <stdlib.h> #include <string> -#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) -#include <io.h> // _mktemp +#if defined(_WIN32) || defined(__MINGW32__) +#include <io.h> // _mktemp_s #else #include <unistd.h> // close #endif @@ -67,17 +65,20 @@ extern "C" { } #endif -#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +#ifndef __CloudABI__ inline -std::string -get_temp_file_name() +std::string get_temp_file_name() { -#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) - char Path[MAX_PATH+1]; - char FN[MAX_PATH+1]; +#if defined(__MINGW32__) + char Path[MAX_PATH + 1]; + char FN[MAX_PATH + 1]; do { } while (0 == GetTempPath(MAX_PATH+1, Path)); do { } while (0 == GetTempFileName(Path, "libcxx", 0, FN)); return FN; +#elif defined(_WIN32) + char Name[] = "libcxx.XXXXXX"; + if (_mktemp_s(Name, sizeof(Name)) != 0) abort(); + return Name; #else std::string Name; int FD = -1; @@ -93,6 +94,6 @@ get_temp_file_name() return Name; #endif } -#endif // _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +#endif // __CloudABI__ #endif // PLATFORM_SUPPORT_H diff --git a/test/support/propagate_const_helpers.h b/test/support/propagate_const_helpers.h new file mode 100644 index 0000000000000..581565a342708 --- /dev/null +++ b/test/support/propagate_const_helpers.h @@ -0,0 +1,119 @@ + // A lightweight class, with pointer-like methods, that contains an int +struct X +{ + int i_; + + constexpr const int &operator*() const { return i_; } + constexpr int &operator*() { return i_; } + constexpr const int *get() const { return &i_; } + constexpr int *get() { return &i_; } + constexpr const int *operator->() const { return &i_; } + constexpr int *operator->() { return &i_; } + + constexpr X(int i) : i_(i) {} +}; + +struct XWithImplicitIntStarConversion +{ + int i_; + + constexpr const int &operator*() const { return i_; } + constexpr int &operator*() { return i_; } + constexpr const int *get() const { return &i_; } + constexpr int *get() { return &i_; } + constexpr const int *operator->() const { return &i_; } + constexpr int *operator->() { return &i_; } + constexpr operator int* () { return &i_; } + + constexpr XWithImplicitIntStarConversion(int i) : i_(i) {} +}; + +struct XWithImplicitConstIntStarConversion +{ + int i_; + + constexpr const int &operator*() const { return i_; } + constexpr int &operator*() { return i_; } + constexpr const int *get() const { return &i_; } + constexpr int *get() { return &i_; } + constexpr const int *operator->() const { return &i_; } + constexpr int *operator->() { return &i_; } + constexpr operator const int* () const { return &i_; } + + constexpr XWithImplicitConstIntStarConversion(int i) : i_(i) {} +}; + +struct ExplicitX +{ + int i_; + + constexpr const int &operator*() const { return i_; } + constexpr int &operator*() { return i_; } + constexpr const int *get() const { return &i_; } + constexpr int *get() { return &i_; } + constexpr const int *operator->() const { return &i_; } + constexpr int *operator->() { return &i_; } + + constexpr explicit ExplicitX(int i) : i_(i) {} +}; + +struct MoveConstructibleFromX +{ + int i_; + + constexpr const int &operator*() const { return i_; } + constexpr int &operator*() { return i_; } + constexpr const int *get() const { return &i_; } + constexpr int *get() { return &i_; } + constexpr const int *operator->() const { return &i_; } + constexpr int *operator->() { return &i_; } + + constexpr MoveConstructibleFromX(int i) : i_(i) {} + constexpr MoveConstructibleFromX(X&& x) : i_(x.i_) {} +}; + +struct ExplicitMoveConstructibleFromX +{ + int i_; + + constexpr const int &operator*() const { return i_; } + constexpr int &operator*() { return i_; } + constexpr const int *get() const { return &i_; } + constexpr int *get() { return &i_; } + constexpr const int *operator->() const { return &i_; } + constexpr int *operator->() { return &i_; } + + constexpr ExplicitMoveConstructibleFromX(int i) : i_(i) {} + constexpr explicit ExplicitMoveConstructibleFromX(X&& x) : i_(x.i_) {} +}; + +struct CopyConstructibleFromX +{ + int i_; + + constexpr const int &operator*() const { return i_; } + constexpr int &operator*() { return i_; } + constexpr const int *get() const { return &i_; } + constexpr int *get() { return &i_; } + constexpr const int *operator->() const { return &i_; } + constexpr int *operator->() { return &i_; } + + constexpr CopyConstructibleFromX(int i) : i_(i) {} + constexpr CopyConstructibleFromX(const X& x) : i_(x.i_) {} +}; + +struct ExplicitCopyConstructibleFromX +{ + int i_; + + constexpr const int &operator*() const { return i_; } + constexpr int &operator*() { return i_; } + constexpr const int *get() const { return &i_; } + constexpr int *get() { return &i_; } + constexpr const int *operator->() const { return &i_; } + constexpr int *operator->() { return &i_; } + + constexpr ExplicitCopyConstructibleFromX(int i) : i_(i) {} + constexpr explicit ExplicitCopyConstructibleFromX(const X& x) : i_(x.i_) {} +}; + diff --git a/test/support/rapid-cxx-test.hpp b/test/support/rapid-cxx-test.hpp new file mode 100644 index 0000000000000..a25bda53109cf --- /dev/null +++ b/test/support/rapid-cxx-test.hpp @@ -0,0 +1,847 @@ +#ifndef RAPID_CXX_TEST_HPP +#define RAPID_CXX_TEST_HPP + +# include <cstddef> +# include <cstdlib> +# include <cstdio> +# include <cstring> +# include <cassert> + +#include "test_macros.h" + +#if !defined(RAPID_CXX_TEST_NO_SYSTEM_HEADER) || !defined(__GNUC__) +#pragma GCC system_header +#endif + +# define RAPID_CXX_TEST_PP_CAT(x, y) RAPID_CXX_TEST_PP_CAT_2(x, y) +# define RAPID_CXX_TEST_PP_CAT_2(x, y) x##y + +# define RAPID_CXX_TEST_PP_STR(...) RAPID_CXX_TEST_PP_STR_2(__VA_ARGS__) +# define RAPID_CXX_TEST_PP_STR_2(...) #__VA_ARGS__ + +# if defined(__GNUC__) +# define TEST_FUNC_NAME() __PRETTY_FUNCTION__ +# define RAPID_CXX_TEST_UNUSED __attribute__((unused)) +# else +# define TEST_FUNC_NAME() __func__ +# define RAPID_CXX_TEST_UNUSED +# endif + +//////////////////////////////////////////////////////////////////////////////// +// TEST_SUITE +//////////////////////////////////////////////////////////////////////////////// +# define TEST_SUITE(Name) \ +namespace Name \ +{ \ + inline ::rapid_cxx_test::test_suite & get_test_suite() \ + { \ + static ::rapid_cxx_test::test_suite m_suite(#Name); \ + return m_suite; \ + } \ + \ + inline int unit_test_main(int, char**) \ + { \ + ::rapid_cxx_test::test_runner runner(get_test_suite()); \ + return runner.run(); \ + } \ +} \ +int main(int argc, char **argv) \ +{ \ + return Name::unit_test_main(argc, argv); \ +} \ +namespace Name \ +{ /* namespace closed in TEST_SUITE_END */ +# + +//////////////////////////////////////////////////////////////////////////////// +// TEST_SUITE_END +//////////////////////////////////////////////////////////////////////////////// +# define TEST_SUITE_END() \ +} /* namespace opened in TEST_SUITE(...) */ +# + +//////////////////////////////////////////////////////////////////////////////// +// TEST_CASE +//////////////////////////////////////////////////////////////////////////////// + +# if !defined(__clang__) +# +# define TEST_CASE(Name) \ + void Name(); \ + static void RAPID_CXX_TEST_PP_CAT(Name, _invoker)() \ + { \ + Name(); \ + } \ + static ::rapid_cxx_test::registrar \ + RAPID_CXX_TEST_PP_CAT(rapid_cxx_test_registrar_, Name)( \ + get_test_suite() \ + , ::rapid_cxx_test::test_case(__FILE__, #Name, __LINE__, & RAPID_CXX_TEST_PP_CAT(Name, _invoker)) \ + ); \ + void Name() +# +# else /* __clang__ */ +# +# define TEST_CASE(Name) \ + void Name(); \ + static void RAPID_CXX_TEST_PP_CAT(Name, _invoker)() \ + { \ + Name(); \ + } \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \ + static ::rapid_cxx_test::registrar \ + RAPID_CXX_TEST_PP_CAT(rapid_cxx_test_registrar_, Name)( \ + get_test_suite() \ + , ::rapid_cxx_test::test_case(__FILE__, #Name, __LINE__, & RAPID_CXX_TEST_PP_CAT(Name, _invoker)) \ + ); \ + _Pragma("clang diagnostic pop") \ + void Name() +# +# endif /* !defined(__clang__) */ + + +# define TEST_SET_CHECKPOINT() ::rapid_cxx_test::set_checkpoint(__FILE__, TEST_FUNC_NAME(), __LINE__) + +#define RAPID_CXX_TEST_OUTCOME() + +//////////////////////////////////////////////////////////////////////////////// +// TEST_UNSUPPORTED +//////////////////////////////////////////////////////////////////////////////// +# define TEST_UNSUPPORTED() \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::unsupported, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "", "" \ + ); \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + return; \ + } while (false) +# + + +//////////////////////////////////////////////////////////////////////////////// +// BASIC ASSERTIONS +//////////////////////////////////////////////////////////////////////////////// +# define TEST_WARN(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_WARN(" #__VA_ARGS__ ")", "" \ + ); \ + if (not (__VA_ARGS__)) { \ + m_f.type = ::rapid_cxx_test::failure_type::warn; \ + } \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + } while (false) +# + +# define TEST_CHECK(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_CHECK(" #__VA_ARGS__ ")", "" \ + ); \ + if (not (__VA_ARGS__)) { \ + m_f.type = ::rapid_cxx_test::failure_type::check; \ + } \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + } while (false) +# + +# define TEST_REQUIRE(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_REQUIRE(" #__VA_ARGS__ ")", "" \ + ); \ + if (not (__VA_ARGS__)) { \ + m_f.type = ::rapid_cxx_test::failure_type::require; \ + } \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + if (m_f.type != ::rapid_cxx_test::failure_type::none) { \ + return; \ + } \ + } while (false) +# + +# define TEST_ASSERT(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_ASSERT(" #__VA_ARGS__ ")", "" \ + ); \ + if (not (__VA_ARGS__)) { \ + m_f.type = ::rapid_cxx_test::failure_type::assert; \ + } \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + if (m_f.type != ::rapid_cxx_test::failure_type::none) { \ + std::abort(); \ + } \ + } while (false) +# + +//////////////////////////////////////////////////////////////////////////////// +// TEST_CHECK_NO_THROW / TEST_CHECK_THROW +//////////////////////////////////////////////////////////////////////////////// +#ifndef TEST_HAS_NO_EXCEPTIONS + +# define TEST_CHECK_NO_THROW(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_CHECK_NO_THROW(" #__VA_ARGS__ ")", "" \ + ); \ + try { \ + (static_cast<void>(__VA_ARGS__)); \ + } catch (...) { \ + m_f.type = ::rapid_cxx_test::failure_type::check; \ + } \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + } while (false) +# + +# define TEST_CHECK_THROW(Except, ...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_CHECK_THROW(" #Except "," #__VA_ARGS__ ")", "" \ + ); \ + try { \ + (static_cast<void>(__VA_ARGS__)); \ + m_f.type = ::rapid_cxx_test::failure_type::check; \ + } catch (Except const &) {} \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + } while (false) +# + +#else // TEST_HAS_NO_EXCEPTIONS + +# define TEST_CHECK_NO_THROW(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_CHECK_NO_THROW(" #__VA_ARGS__ ")", "" \ + ); \ + (static_cast<void>(__VA_ARGS__)); \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + } while (false) +# + +#define TEST_CHECK_THROW(Except, ...) ((void)0) + +#endif // TEST_HAS_NO_EXCEPTIONS + + +//////////////////////////////////////////////////////////////////////////////// +// TEST_REQUIRE_NO_THROW / TEST_REQUIRE_THROWs +//////////////////////////////////////////////////////////////////////////////// +#ifndef TEST_HAS_NO_EXCEPTIONS + +# define TEST_REQUIRE_NO_THROW(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_REQUIRE_NO_THROW(" #__VA_ARGS__ ")", "" \ + ); \ + try { \ + (static_cast<void>(__VA_ARGS__)); \ + } catch (...) { \ + m_f.type = ::rapid_cxx_test::failure_type::require; \ + } \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + if (m_f.type != ::rapid_cxx_test::failure_type::none) { \ + return; \ + } \ + } while (false) +# + +# define TEST_REQUIRE_THROW(Except, ...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_REQUIRE_THROW(" #Except "," #__VA_ARGS__ ")", "" \ + ); \ + try { \ + (static_cast<void>(__VA_ARGS__)); \ + m_f.type = ::rapid_cxx_test::failure_type::require; \ + } catch (Except const &) {} \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + if (m_f.type != ::rapid_cxx_test::failure_type::none) { \ + return; \ + } \ + } while (false) +# + +#else // TEST_HAS_NO_EXCEPTIONS + +# define TEST_REQUIRE_NO_THROW(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_REQUIRE_NO_THROW(" #__VA_ARGS__ ")", "" \ + ); \ + (static_cast<void>(__VA_ARGS__)); \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + } while (false) +# + +#define TEST_REQUIRE_THROW(Except, ...) ((void)0) + +#endif // TEST_HAS_NO_EXCEPTIONS + +//////////////////////////////////////////////////////////////////////////////// +// TEST_ASSERT_NO_THROW / TEST_ASSERT_THROW +//////////////////////////////////////////////////////////////////////////////// +#ifndef TEST_HAS_NO_EXCEPTIONS + +# define TEST_ASSERT_NO_THROW(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_ASSERT_NO_THROW(" #__VA_ARGS__ ")", "" \ + ); \ + try { \ + (static_cast<void>(__VA_ARGS__)); \ + } catch (...) { \ + m_f.type = ::rapid_cxx_test::failure_type::assert; \ + } \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + if (m_f.type != ::rapid_cxx_test::failure_type::none) { \ + std::abort(); \ + } \ + } while (false) +# + +# define TEST_ASSERT_THROW(Except, ...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_ASSERT_THROW(" #Except "," #__VA_ARGS__ ")", "" \ + ); \ + try { \ + (static_cast<void>(__VA_ARGS__)); \ + m_f.type = ::rapid_cxx_test::failure_type::assert; \ + } catch (Except const &) {} \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + if (m_f.type != ::rapid_cxx_test::failure_type::none) { \ + std::abort(); \ + } \ + } while (false) +# + +#else // TEST_HAS_NO_EXCEPTIONS + +# define TEST_ASSERT_NO_THROW(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_ASSERT_NO_THROW(" #__VA_ARGS__ ")", "" \ + ); \ + (static_cast<void>(__VA_ARGS__)); \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + } while (false) +# + +#define TEST_ASSERT_THROW(Except, ...) ((void)0) + +#endif // TEST_HAS_NO_EXCEPTIONS + +//////////////////////////////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////////////////////////////// + +# define TEST_WARN_EQUAL_COLLECTIONS(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_WARN_EQUAL_COLLECTIONS(" #__VA_ARGS__ ")", "" \ + ); \ + if (not ::rapid_cxx_test::detail::check_equal_collections_impl(__VA_ARGS__)) { \ + m_f.type = ::rapid_cxx_test::failure_type::warn; \ + } \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + } while (false) +# + +# define TEST_CHECK_EQUAL_COLLECTIONS(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_CHECK_EQUAL_COLLECTIONS(" #__VA_ARGS__ ")", "" \ + ); \ + if (not ::rapid_cxx_test::detail::check_equal_collections_impl(__VA_ARGS__)) { \ + m_f.type = ::rapid_cxx_test::failure_type::check; \ + } \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + } while (false) +# + +# define TEST_REQUIRE_EQUAL_COLLECTIONS(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_REQUIRE_EQUAL_COLLECTIONS(" #__VA_ARGS__ ")", "" \ + ); \ + if (not ::rapid_cxx_test::detail::check_equal_collections_impl(__VA_ARGS__)) { \ + m_f.type = ::rapid_cxx_test::failure_type::require; \ + } \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + if (m_f.type != ::rapid_cxx_test::failure_type::none) { \ + return; \ + } \ + } while (false) +# + +# define TEST_ASSERT_EQUAL_COLLECTIONS(...) \ + do { \ + TEST_SET_CHECKPOINT(); \ + ::rapid_cxx_test::test_outcome m_f( \ + ::rapid_cxx_test::failure_type::none, __FILE__, TEST_FUNC_NAME(), __LINE__ \ + , "TEST_ASSERT_EQUAL_COLLECTIONS(" #__VA_ARGS__ ")", "" \ + ); \ + if (not ::rapid_cxx_test::detail::check_equal_collections_impl(__VA_ARGS__)) { \ + m_f.type = ::rapid_cxx_test::failure_type::assert; \ + } \ + ::rapid_cxx_test::get_reporter().report(m_f); \ + if (m_f.type != ::rapid_cxx_test::failure_type::none) { \ + ::std::abort(); \ + } \ + } while (false) +# + +namespace rapid_cxx_test +{ + typedef void (*invoker_t)(); + + //////////////////////////////////////////////////////////////////////////// + struct test_case + { + test_case() + : file(""), func(""), line(0), invoke(NULL) + {} + + test_case(const char* file1, const char* func1, std::size_t line1, + invoker_t invoke1) + : file(file1), func(func1), line(line1), invoke(invoke1) + {} + + const char *file; + const char *func; + std::size_t line; + invoker_t invoke; + }; + + //////////////////////////////////////////////////////////////////////////// + struct failure_type + { + enum enum_type { + none, + unsupported, + warn, + check, + require, + assert, + uncaught_exception + }; + }; + + typedef failure_type::enum_type failure_type_t; + + //////////////////////////////////////////////////////////////////////////// + struct test_outcome + { + test_outcome() + : type(failure_type::none), + file(""), func(""), line(0), + expression(""), message("") + {} + + test_outcome(failure_type_t type1, const char* file1, const char* func1, + std::size_t line1, const char* expression1, + const char* message1) + : type(type1), file(file1), func(func1), line(line1), + expression(expression1), message(message1) + { + trim_func_string(); + } + + failure_type_t type; + const char *file; + const char *func; + std::size_t line; + const char *expression; + const char *message; + + private: + void trim_file_string() { + const char* f_start = file; + const char* prev_start = f_start; + const char* last_start = f_start; + char last; + while ((last = *f_start) != '\0') { + ++f_start; + if (last == '/' && *f_start) { + prev_start = last_start; + last_start = f_start; + } + } + file = prev_start; + } + void trim_func_string() { + const char* void_loc = ::strstr(func, "void "); + if (void_loc == func) { + func += strlen("void "); + } + const char* namespace_loc = ::strstr(func, "::"); + if (namespace_loc) { + func = namespace_loc + 2; + } + } + }; + + //////////////////////////////////////////////////////////////////////////// + struct checkpoint + { + const char *file; + const char *func; + std::size_t line; + }; + + namespace detail + { + inline checkpoint & global_checkpoint() + { + static checkpoint cp = {"", "", 0}; + return cp; + } + } + + //////////////////////////////////////////////////////////////////////////// + inline void set_checkpoint(const char* file, const char* func, std::size_t line) + { + checkpoint& cp = detail::global_checkpoint(); + cp.file = file; + cp.func = func; + cp.line = line; + } + + //////////////////////////////////////////////////////////////////////////// + inline checkpoint const & get_checkpoint() + { + return detail::global_checkpoint(); + } + + //////////////////////////////////////////////////////////////////////////// + class test_suite + { + public: + typedef test_case const* iterator; + typedef iterator const_iterator; + + public: + test_suite(const char *xname) + : m_name(xname), m_tests(), m_size(0) + { + assert(xname); + } + + public: + const char *name() const { return m_name; } + + std::size_t size() const { return m_size; } + + test_case const & operator[](std::size_t i) const + { + assert(i < m_size); + return m_tests[i]; + } + + const_iterator begin() const + { return m_tests; } + + const_iterator end() const + { + return m_tests + m_size; + } + + public: + std::size_t register_test(test_case tc) + { + static std::size_t test_case_max = sizeof(m_tests) / sizeof(test_case); + assert(m_size < test_case_max); + m_tests[m_size] = tc; + return m_size++; + } + + private: + test_suite(test_suite const &); + test_suite & operator=(test_suite const &); + + private: + const char* m_name; + // Since fast compile times in a priority, we use simple containers + // with hard limits. + test_case m_tests[256]; + std::size_t m_size; + }; + + //////////////////////////////////////////////////////////////////////////// + class registrar + { + public: + registrar(test_suite & st, test_case tc) + { + st.register_test(tc); + } + }; + + //////////////////////////////////////////////////////////////////////////// + class test_reporter + { + public: + test_reporter() + : m_testcases(0), m_testcase_failures(0), m_unsupported(0), + m_assertions(0), m_warning_failures(0), m_check_failures(0), + m_require_failures(0), m_uncaught_exceptions(0), m_failure() + { + } + + void test_case_begin() + { + ++m_testcases; + clear_failure(); + } + + void test_case_end() + { + if (m_failure.type != failure_type::none + && m_failure.type != failure_type::unsupported) { + ++m_testcase_failures; + } + } + +# if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wswitch-default" +# endif + // Each assertion and failure is reported through this function. + void report(test_outcome o) + { + ++m_assertions; + switch (o.type) + { + case failure_type::none: + break; + case failure_type::unsupported: + ++m_unsupported; + m_failure = o; + break; + case failure_type::warn: + ++m_warning_failures; + report_error(o); + break; + case failure_type::check: + ++m_check_failures; + report_error(o); + m_failure = o; + break; + case failure_type::require: + ++m_require_failures; + report_error(o); + m_failure = o; + break; + case failure_type::assert: + report_error(o); + break; + case failure_type::uncaught_exception: + ++m_uncaught_exceptions; + std::fprintf(stderr + , "Test case FAILED with uncaught exception:\n" + " last checkpoint near %s::%lu %s\n\n" + , o.file, o.line, o.func + ); + m_failure = o; + break; + } + } +# if defined(__GNUC__) +# pragma GCC diagnostic pop +# endif + + test_outcome current_failure() const + { + return m_failure; + } + + void clear_failure() + { + m_failure.type = failure_type::none; + m_failure.file = ""; + m_failure.func = ""; + m_failure.line = 0; + m_failure.expression = ""; + m_failure.message = ""; + } + + std::size_t test_case_count() const + { return m_testcases; } + + std::size_t test_case_failure_count() const + { return m_testcase_failures; } + + std::size_t unsupported_count() const + { return m_unsupported; } + + std::size_t assertion_count() const + { return m_assertions; } + + std::size_t warning_failure_count() const + { return m_warning_failures; } + + std::size_t check_failure_count() const + { return m_check_failures; } + + std::size_t require_failure_count() const + { return m_require_failures; } + + std::size_t failure_count() const + { return m_check_failures + m_require_failures + m_uncaught_exceptions; } + + // Print a summary of what was run and the outcome. + void print_summary(const char* suitename) const + { + FILE* out = failure_count() ? stderr : stdout; + std::size_t testcases_run = m_testcases - m_unsupported; + std::fprintf(out, "Summary for testsuite %s:\n", suitename); + std::fprintf(out, " %lu of %lu test cases passed.\n", testcases_run - m_testcase_failures, testcases_run); + std::fprintf(out, " %lu of %lu assertions passed.\n", m_assertions - (m_warning_failures + m_check_failures + m_require_failures), m_assertions); + std::fprintf(out, " %lu unsupported test case%s.\n", m_unsupported, (m_unsupported != 1 ? "s" : "")); + } + + private: + test_reporter(test_reporter const &); + test_reporter const & operator=(test_reporter const &); + + void report_error(test_outcome o) const + { + std::fprintf(stderr, "In %s:%lu Assertion %s failed.\n in file: %s\n %s\n" + , o.func, o.line, o.expression, o.file, o.message ? o.message : "" + ); + } + + private: + // counts of testcases, failed testcases, and unsupported testcases. + std::size_t m_testcases; + std::size_t m_testcase_failures; + std::size_t m_unsupported; + + // counts of assertions and assertion failures. + std::size_t m_assertions; + std::size_t m_warning_failures; + std::size_t m_check_failures; + std::size_t m_require_failures; + std::size_t m_uncaught_exceptions; + + // The last failure. This is cleared between testcases. + test_outcome m_failure; + }; + + //////////////////////////////////////////////////////////////////////////// + inline test_reporter & get_reporter() + { + static test_reporter o; + return o; + } + + //////////////////////////////////////////////////////////////////////////// + class test_runner + { + public: + test_runner(test_suite & ts) + : m_ts(ts) + {} + + public: + int run() + { + // for each testcase + for (test_suite::const_iterator b = m_ts.begin(), e = m_ts.end(); + b != e; ++b) + { + test_case const& tc = *b; + set_checkpoint(tc.file, tc.func, tc.line); + get_reporter().test_case_begin(); +#ifndef TEST_HAS_NO_EXCEPTIONS + try { +#endif + tc.invoke(); +#ifndef TEST_HAS_NO_EXCEPTIONS + } catch (...) { + test_outcome o; + o.type = failure_type::uncaught_exception; + o.file = get_checkpoint().file; + o.func = get_checkpoint().func; + o.line = get_checkpoint().line; + o.expression = ""; + o.message = ""; + get_reporter().report(o); + } +#endif + get_reporter().test_case_end(); + } + auto exit_code = get_reporter().failure_count() ? EXIT_FAILURE : EXIT_SUCCESS; + if (exit_code == EXIT_FAILURE) + get_reporter().print_summary(m_ts.name()); + return exit_code; + } + + private: + test_runner(test_runner const &); + test_runner operator=(test_runner const &); + + test_suite & m_ts; + }; + + namespace detail + { + template <class Iter1, class Iter2> + bool check_equal_collections_impl( + Iter1 start1, Iter1 const end1 + , Iter2 start2, Iter2 const end2 + ) + { + while (start1 != end1 && start2 != end2) { + if (*start1 != *start2) { + return false; + } + ++start1; ++start2; + } + return (start1 == end1 && start2 == end2); + } + } // namespace detail + +} // namespace rapid_cxx_test + + +# if defined(__GNUC__) +# pragma GCC diagnostic pop +# endif + +#endif /* RAPID_CXX_TEST_HPP */ diff --git a/test/support/test.support/test_convertible_header.pass.cpp b/test/support/test.support/test_convertible_header.pass.cpp new file mode 100644 index 0000000000000..a56b84b4739c5 --- /dev/null +++ b/test/support/test.support/test_convertible_header.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: c++98, c++03 + +// "support/test_convertible.hpp" + +#include "test_convertible.hpp" + +struct ImplicitDefault { + ImplicitDefault() {} +}; +static_assert(test_convertible<ImplicitDefault>(), "Must be convertible"); + +struct ExplicitDefault { + explicit ExplicitDefault() {} +}; +static_assert(!test_convertible<ExplicitDefault>(), "Must not be convertible"); + +struct ImplicitInt { + ImplicitInt(int) {} +}; +static_assert(test_convertible<ImplicitInt, int>(), "Must be convertible"); + +struct ExplicitInt { + explicit ExplicitInt(int) {} +}; +static_assert(!test_convertible<ExplicitInt, int>(), "Must not be convertible"); + +struct ImplicitCopy { + ImplicitCopy(ImplicitCopy const&) {} +}; +static_assert(test_convertible<ImplicitCopy, ImplicitCopy>(), "Must be convertible"); + +struct ExplicitCopy { + explicit ExplicitCopy(ExplicitCopy const&) {} +}; +static_assert(!test_convertible<ExplicitCopy, ExplicitCopy>(), "Must not be convertible"); + +struct ImplicitMove { + ImplicitMove(ImplicitMove&&) {} +}; +static_assert(test_convertible<ImplicitMove, ImplicitMove>(), "Must be convertible"); + +struct ExplicitMove { + explicit ExplicitMove(ExplicitMove&&) {} +}; +static_assert(!test_convertible<ExplicitMove, ExplicitMove>(), "Must not be convertible"); + +struct ImplicitArgs { + ImplicitArgs(int, int, int) {} +}; +static_assert(test_convertible<ImplicitArgs, int, int, int>(), "Must be convertible"); + +struct ExplicitArgs { + explicit ExplicitArgs(int, int, int) {} +}; +static_assert(!test_convertible<ExplicitArgs, int, int, int>(), "Must not be convertible"); + +int main() { + // Nothing to do +} diff --git a/test/support/test.support/test_macros_header_exceptions.fail.cpp b/test/support/test.support/test_macros_header_exceptions.fail.cpp new file mode 100644 index 0000000000000..ade2cd98fe08c --- /dev/null +++ b/test/support/test.support/test_macros_header_exceptions.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// "support/test_macros.hpp" + +// #define TEST_HAS_NO_EXCEPTIONS + +#include "test_macros.h" + +int main() { +#if defined(TEST_HAS_NO_EXCEPTIONS) + try { ((void)0); } catch (...) {} // expected-error {{exceptions disabled}} +#else + try { ((void)0); } catch (...) {} +#error exceptions enabled +// expected-error@-1 {{exceptions enabled}} +#endif +} diff --git a/test/support/test.support/test_macros_header_exceptions.pass.cpp b/test/support/test.support/test_macros_header_exceptions.pass.cpp new file mode 100644 index 0000000000000..589e148a00320 --- /dev/null +++ b/test/support/test.support/test_macros_header_exceptions.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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-no-exceptions + +// "support/test_macros.hpp" + +// #define TEST_HAS_NO_EXCEPTIONS + +#include "test_macros.h" + +#if defined(TEST_HAS_NO_EXCEPTIONS) +#error macro defined unexpectedly +#endif + +int main() { + try { ((void)0); } catch (...) {} +} diff --git a/test/support/test.support/test_macros_header_rtti.fail.cpp b/test/support/test.support/test_macros_header_rtti.fail.cpp new file mode 100644 index 0000000000000..851a6c6014164 --- /dev/null +++ b/test/support/test.support/test_macros_header_rtti.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. +// +//===----------------------------------------------------------------------===// + +// "support/test_macros.hpp" + +// #define TEST_HAS_NO_RTTI + +#include "test_macros.h" + +struct A { virtual ~A() {} }; +struct B : A {}; + +int main() { +#if defined(TEST_HAS_NO_RTTI) + A* ptr = new B; + (void)dynamic_cast<B*>(ptr); // expected-error{{cannot use dynamic_cast}} +#else + A* ptr = new B; + (void)dynamic_cast<B*>(ptr); +#error RTTI enabled +// expected-error@-1{{RTTI enabled}} +#endif +} diff --git a/test/support/test.support/test_macros_header_rtti.pass.cpp b/test/support/test.support/test_macros_header_rtti.pass.cpp new file mode 100644 index 0000000000000..d189a0efc2fcb --- /dev/null +++ b/test/support/test.support/test_macros_header_rtti.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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-no-rtti + +// "support/test_macros.hpp" + +// #define TEST_HAS_NO_RTTI + +#include "test_macros.h" + +#if defined(TEST_HAS_NO_RTTI) +#error Macro defined unexpectedly +#endif + +struct A { virtual ~A() {} }; +struct B : A {}; + +int main() { + A* ptr = new B; + (void)dynamic_cast<B*>(ptr); +} diff --git a/test/support/test_allocator.h b/test/support/test_allocator.h index 3ca672f89a9be..466c7fabc66d7 100644 --- a/test/support/test_allocator.h +++ b/test/support/test_allocator.h @@ -76,18 +76,22 @@ public: ++alloc_count; return (pointer)::operator new(n * sizeof(T)); } - void deallocate(pointer p, size_type n) + void deallocate(pointer p, size_type) {assert(data_ >= 0); --alloc_count; ::operator delete((void*)p);} size_type max_size() const throw() {return UINT_MAX / sizeof(T);} +#if TEST_STD_VER < 11 void construct(pointer p, const T& val) - {::new(p) T(val);} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - void construct(pointer p, T&& val) - {::new(p) T(std::move(val));} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - void destroy(pointer p) {p->~T();} - + {::new(static_cast<void*>(p)) T(val);} +#else + template <class U> void construct(pointer p, U&& val) + {::new(static_cast<void*>(p)) T(std::forward<U>(val));} +#endif + void destroy(pointer p) + { + p->~T(); + ((void)p); // Prevent MSVC's spurious unused warning + } friend bool operator==(const test_allocator& x, const test_allocator& y) {return x.data_ == y.data_;} friend bool operator!=(const test_allocator& x, const test_allocator& y) @@ -136,16 +140,17 @@ public: ++alloc_count; return (pointer)::operator new (n * sizeof(T)); } - void deallocate(pointer p, size_type n) + void deallocate(pointer p, size_type) {assert(data_ >= 0); --alloc_count; ::operator delete((void*)p); } size_type max_size() const throw() {return UINT_MAX / sizeof(T);} +#if TEST_STD_VER < 11 void construct(pointer p, const T& val) - {::new(p) T(val);} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - void construct(pointer p, T&& val) - {::new(p) T(std::move(val));} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + {::new(static_cast<void*>(p)) T(val);} +#else + template <class U> void construct(pointer p, U&& val) + {::new(static_cast<void*>(p)) T(std::forward<U>(val));} +#endif void destroy(pointer p) {p->~T();} friend bool operator==(const non_default_test_allocator& x, const non_default_test_allocator& y) @@ -201,7 +206,7 @@ public: : data_(a.data_) {} T* allocate(std::size_t n) {return (T*)::operator new(n * sizeof(T));} - void deallocate(T* p, std::size_t n) + void deallocate(T* p, std::size_t) {::operator delete((void*)p);} other_allocator select_on_container_copy_construction() const @@ -223,4 +228,82 @@ public: }; +#if TEST_STD_VER >= 11 + +struct Ctor_Tag {}; + +template <typename T> class TaggingAllocator; + +struct Tag_X { + // All constructors must be passed the Tag type. + + // DefaultInsertable into vector<X, TaggingAllocator<X>>, + Tag_X(Ctor_Tag) {} + // CopyInsertable into vector<X, TaggingAllocator<X>>, + Tag_X(Ctor_Tag, const Tag_X&) {} + // MoveInsertable into vector<X, TaggingAllocator<X>>, and + Tag_X(Ctor_Tag, Tag_X&&) {} + + // EmplaceConstructible into vector<X, TaggingAllocator<X>> from args. + template<typename... Args> + Tag_X(Ctor_Tag, Args&&...) { } + + // not DefaultConstructible, CopyConstructible or MoveConstructible. + Tag_X() = delete; + Tag_X(const Tag_X&) = delete; + Tag_X(Tag_X&&) = delete; + + // CopyAssignable. + Tag_X& operator=(const Tag_X&) { return *this; } + + // MoveAssignable. + Tag_X& operator=(Tag_X&&) { return *this; } + +private: + // Not Destructible. + ~Tag_X() { } + + // Erasable from vector<X, TaggingAllocator<X>>. + friend class TaggingAllocator<Tag_X>; +}; + + +template<typename T> +class TaggingAllocator { +public: + using value_type = T; + TaggingAllocator() = default; + + template<typename U> + TaggingAllocator(const TaggingAllocator<U>&) { } + + T* allocate(std::size_t n) { return std::allocator<T>{}.allocate(n); } + + void deallocate(T* p, std::size_t n) { std::allocator<T>{}.deallocate(p, n); } + + template<typename... Args> + void construct(Tag_X* p, Args&&... args) + { ::new((void*)p) Tag_X(Ctor_Tag{}, std::forward<Args>(args)...); } + + template<typename U, typename... Args> + void construct(U* p, Args&&... args) + { ::new((void*)p) U(std::forward<Args>(args)...); } + + template<typename U, typename... Args> + void destroy(U* p) + { p->~U(); } +}; + +template<typename T, typename U> +bool +operator==(const TaggingAllocator<T>&, const TaggingAllocator<U>&) +{ return true; } + +template<typename T, typename U> +bool +operator!=(const TaggingAllocator<T>&, const TaggingAllocator<U>&) +{ return false; } +#endif + + #endif // TEST_ALLOCATOR_H diff --git a/test/support/test_convertible.hpp b/test/support/test_convertible.hpp new file mode 100644 index 0000000000000..787cef6568f28 --- /dev/null +++ b/test/support/test_convertible.hpp @@ -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. +// +//===----------------------------------------------------------------------===// + +#ifndef SUPPORT_TEST_CONVERTIBLE_HPP +#define SUPPORT_TEST_CONVERTIBLE_HPP + +// "test_convertible<Tp, Args...>()" is a metafunction used to check if 'Tp' +// is implicitly convertible from 'Args...' for any number of arguments, +// Unlike 'std::is_convertible' which only allows checking for single argument +// conversions. + +#include <type_traits> + +#include "test_macros.h" + +#if TEST_STD_VER < 11 +#error test_convertible.hpp requires C++11 or newer +#endif + +namespace detail { + template <class Tp> void eat_type(Tp); + + template <class Tp, class ...Args> + constexpr auto test_convertible_imp(int) + -> decltype(eat_type<Tp>({std::declval<Args>()...}), true) + { return true; } + + template <class Tp, class ...Args> + constexpr auto test_convertible_imp(long) -> bool { return false; } +} + +template <class Tp, class ...Args> +constexpr bool test_convertible() +{ return detail::test_convertible_imp<Tp, Args...>(0); } + +#endif // SUPPORT_TEST_CONVERTIBLE_HPP
\ No newline at end of file diff --git a/test/support/test_iterators.h b/test/support/test_iterators.h index d814879fa2727..d4a079971b15a 100644 --- a/test/support/test_iterators.h +++ b/test/support/test_iterators.h @@ -12,6 +12,7 @@ #include <iterator> #include <stdexcept> +#include <cstddef> #include <cassert> #include "test_macros.h" @@ -335,116 +336,137 @@ struct ThrowingIterator { typedef const T * pointer; typedef const T & reference; - enum ThrowingAction { TAIncrement, TADecrement, TADereference, TAAssignment, TAComparison }; - -// Constructors - ThrowingIterator () - : begin_(nullptr), end_(nullptr), current_(nullptr), action_(TADereference), index_(0) {} - ThrowingIterator (const T *first, const T *last, size_t index = 0, ThrowingAction action = TADereference) - : begin_(first), end_(last), current_(first), action_(action), index_(index) {} - ThrowingIterator (const ThrowingIterator &rhs) - : begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_), action_(rhs.action_), index_(rhs.index_) {} - ThrowingIterator & operator= (const ThrowingIterator &rhs) - { - if (action_ == TAAssignment) - { - if (index_ == 0) - throw std::runtime_error ("throw from iterator assignment"); - else - --index_; - } - begin_ = rhs.begin_; - end_ = rhs.end_; - current_ = rhs.current_; - action_ = rhs.action_; - index_ = rhs.index_; - return *this; - } - -// iterator operations - reference operator*() const - { - if (action_ == TADereference) - { - if (index_ == 0) - throw std::runtime_error ("throw from iterator dereference"); - else - --index_; - } - return *current_; - } - - ThrowingIterator & operator++() - { - if (action_ == TAIncrement) - { - if (index_ == 0) - throw std::runtime_error ("throw from iterator increment"); - else - --index_; - } - ++current_; - return *this; - } - - ThrowingIterator operator++(int) - { - ThrowingIterator temp = *this; - ++(*this); - return temp; - } - - ThrowingIterator & operator--() - { - if (action_ == TADecrement) - { - if (index_ == 0) - throw std::runtime_error ("throw from iterator decrement"); - else - --index_; - } - --current_; - return *this; - } - - ThrowingIterator operator--(int) { - ThrowingIterator temp = *this; - --(*this); - return temp; - } - - bool operator== (const ThrowingIterator &rhs) const - { - if (action_ == TAComparison) - { - if (index_ == 0) - throw std::runtime_error ("throw from iterator comparison"); - else - --index_; - } - bool atEndL = current_ == end_; - bool atEndR = rhs.current_ == rhs.end_; - if (atEndL != atEndR) return false; // one is at the end (or empty), the other is not. - if (atEndL) return true; // both are at the end (or empty) - return current_ == rhs.current_; - } + enum ThrowingAction { TAIncrement, TADecrement, TADereference, TAAssignment, TAComparison }; + +// Constructors + ThrowingIterator () + : begin_(nullptr), end_(nullptr), current_(nullptr), action_(TADereference), index_(0) {} + ThrowingIterator (const T *first, const T *last, size_t index = 0, ThrowingAction action = TADereference) + : begin_(first), end_(last), current_(first), action_(action), index_(index) {} + ThrowingIterator (const ThrowingIterator &rhs) + : begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_), action_(rhs.action_), index_(rhs.index_) {} + ThrowingIterator & operator= (const ThrowingIterator &rhs) + { + if (action_ == TAAssignment) + { + if (index_ == 0) +#ifndef TEST_HAS_NO_EXCEPTIONS + throw std::runtime_error ("throw from iterator assignment"); +#else + assert(false); +#endif + + else + --index_; + } + begin_ = rhs.begin_; + end_ = rhs.end_; + current_ = rhs.current_; + action_ = rhs.action_; + index_ = rhs.index_; + return *this; + } + +// iterator operations + reference operator*() const + { + if (action_ == TADereference) + { + if (index_ == 0) +#ifndef TEST_HAS_NO_EXCEPTIONS + throw std::runtime_error ("throw from iterator dereference"); +#else + assert(false); +#endif + else + --index_; + } + return *current_; + } + + ThrowingIterator & operator++() + { + if (action_ == TAIncrement) + { + if (index_ == 0) +#ifndef TEST_HAS_NO_EXCEPTIONS + throw std::runtime_error ("throw from iterator increment"); +#else + assert(false); +#endif + else + --index_; + } + ++current_; + return *this; + } + + ThrowingIterator operator++(int) + { + ThrowingIterator temp = *this; + ++(*this); + return temp; + } + + ThrowingIterator & operator--() + { + if (action_ == TADecrement) + { + if (index_ == 0) +#ifndef TEST_HAS_NO_EXCEPTIONS + throw std::runtime_error ("throw from iterator decrement"); +#else + assert(false); +#endif + else + --index_; + } + --current_; + return *this; + } + + ThrowingIterator operator--(int) { + ThrowingIterator temp = *this; + --(*this); + return temp; + } + + bool operator== (const ThrowingIterator &rhs) const + { + if (action_ == TAComparison) + { + if (index_ == 0) +#ifndef TEST_HAS_NO_EXCEPTIONS + throw std::runtime_error ("throw from iterator comparison"); +#else + assert(false); +#endif + else + --index_; + } + bool atEndL = current_ == end_; + bool atEndR = rhs.current_ == rhs.end_; + if (atEndL != atEndR) return false; // one is at the end (or empty), the other is not. + if (atEndL) return true; // both are at the end (or empty) + return current_ == rhs.current_; + } private: - const T* begin_; - const T* end_; - const T* current_; - ThrowingAction action_; - mutable size_t index_; + const T* begin_; + const T* end_; + const T* current_; + ThrowingAction action_; + mutable size_t index_; }; template <typename T> bool operator== (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b) -{ return a.operator==(b); } +{ return a.operator==(b); } template <typename T> bool operator!= (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b) -{ return !a.operator==(b); } - +{ return !a.operator==(b); } + template <typename T> struct NonThrowingIterator { typedef std::bidirectional_iterator_tag iterator_category; @@ -453,75 +475,75 @@ struct NonThrowingIterator { typedef const T * pointer; typedef const T & reference; -// Constructors - NonThrowingIterator () - : begin_(nullptr), end_(nullptr), current_(nullptr) {} - NonThrowingIterator (const T *first, const T* last) - : begin_(first), end_(last), current_(first) {} - NonThrowingIterator (const NonThrowingIterator &rhs) - : begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_) {} - NonThrowingIterator & operator= (const NonThrowingIterator &rhs) TEST_NOEXCEPT - { - begin_ = rhs.begin_; - end_ = rhs.end_; - current_ = rhs.current_; - return *this; - } - -// iterator operations - reference operator*() const TEST_NOEXCEPT - { - return *current_; - } - - NonThrowingIterator & operator++() TEST_NOEXCEPT - { - ++current_; - return *this; - } - - NonThrowingIterator operator++(int) TEST_NOEXCEPT - { - NonThrowingIterator temp = *this; - ++(*this); - return temp; - } - - NonThrowingIterator & operator--() TEST_NOEXCEPT - { - --current_; - return *this; - } - - NonThrowingIterator operator--(int) TEST_NOEXCEPT - { - NonThrowingIterator temp = *this; - --(*this); - return temp; - } - - bool operator== (const NonThrowingIterator &rhs) const TEST_NOEXCEPT - { - bool atEndL = current_ == end_; - bool atEndR = rhs.current_ == rhs.end_; - if (atEndL != atEndR) return false; // one is at the end (or empty), the other is not. - if (atEndL) return true; // both are at the end (or empty) - return current_ == rhs.current_; - } +// Constructors + NonThrowingIterator () + : begin_(nullptr), end_(nullptr), current_(nullptr) {} + NonThrowingIterator (const T *first, const T* last) + : begin_(first), end_(last), current_(first) {} + NonThrowingIterator (const NonThrowingIterator &rhs) + : begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_) {} + NonThrowingIterator & operator= (const NonThrowingIterator &rhs) TEST_NOEXCEPT + { + begin_ = rhs.begin_; + end_ = rhs.end_; + current_ = rhs.current_; + return *this; + } + +// iterator operations + reference operator*() const TEST_NOEXCEPT + { + return *current_; + } + + NonThrowingIterator & operator++() TEST_NOEXCEPT + { + ++current_; + return *this; + } + + NonThrowingIterator operator++(int) TEST_NOEXCEPT + { + NonThrowingIterator temp = *this; + ++(*this); + return temp; + } + + NonThrowingIterator & operator--() TEST_NOEXCEPT + { + --current_; + return *this; + } + + NonThrowingIterator operator--(int) TEST_NOEXCEPT + { + NonThrowingIterator temp = *this; + --(*this); + return temp; + } + + bool operator== (const NonThrowingIterator &rhs) const TEST_NOEXCEPT + { + bool atEndL = current_ == end_; + bool atEndR = rhs.current_ == rhs.end_; + if (atEndL != atEndR) return false; // one is at the end (or empty), the other is not. + if (atEndL) return true; // both are at the end (or empty) + return current_ == rhs.current_; + } private: - const T* begin_; - const T* end_; - const T* current_; + const T* begin_; + const T* end_; + const T* current_; }; template <typename T> bool operator== (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT -{ return a.operator==(b); } +{ return a.operator==(b); } template <typename T> bool operator!= (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT -{ return !a.operator==(b); } +{ return !a.operator==(b); } #undef DELETE_FUNCTION diff --git a/test/support/test_macros.h b/test/support/test_macros.h index c34e8cf7ef14f..a072e31b77b70 100644 --- a/test/support/test_macros.h +++ b/test/support/test_macros.h @@ -11,6 +11,8 @@ #ifndef SUPPORT_TEST_MACROS_HPP #define SUPPORT_TEST_MACROS_HPP +#include <ciso646> // Get STL specific macros like _LIBCPP_VERSION + #define TEST_CONCAT1(X, Y) X##Y #define TEST_CONCAT(X, Y) TEST_CONCAT1(X, Y) @@ -33,6 +35,7 @@ #endif /* Make a nice name for the standard version */ +#ifndef TEST_STD_VER #if __cplusplus <= 199711L # define TEST_STD_VER 3 #elif __cplusplus <= 201103L @@ -40,15 +43,8 @@ #elif __cplusplus <= 201402L # define TEST_STD_VER 14 #else -# define TEST_STD_VER 99 // greater than current standard +# define TEST_STD_VER 16 // current year; 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 */ @@ -61,44 +57,27 @@ #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_CONSTEXPR constexpr #define TEST_NOEXCEPT noexcept +# if TEST_STD_VER >= 14 +# define TEST_CONSTEXPR_CXX14 constexpr +# else +# define TEST_CONSTEXPR_CXX14 +# endif #else #define TEST_CONSTEXPR +#define TEST_CONSTEXPR_CXX14 #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) +#if !TEST_HAS_FEATURE(cxx_rtti) && !defined(__cpp_rtti) \ + && !defined(__GXX_RTTI) #define TEST_HAS_NO_RTTI #endif -#if !TEST_HAS_FEATURE(cxx_exceptions) && !defined(__cxx_exceptions) +#if !TEST_HAS_FEATURE(cxx_exceptions) && !defined(__cpp_exceptions) \ + && !defined(__EXCEPTIONS) #define TEST_HAS_NO_EXCEPTIONS #endif @@ -107,4 +86,36 @@ template <unsigned> struct static_assert_check {}; #define TEST_HAS_SANITIZERS #endif +#if defined(_LIBCPP_NORETURN) +#define TEST_NORETURN _LIBCPP_NORETURN +#else +#define TEST_NORETURN [[noreturn]] +#endif + +/* Macros for testing libc++ specific behavior and extensions */ +#if defined(_LIBCPP_VERSION) +#define LIBCPP_ASSERT(...) assert(__VA_ARGS__) +#define LIBCPP_STATIC_ASSERT(...) static_assert(__VA_ARGS__) +#else +#define LIBCPP_ASSERT(...) ((void)0) +#define LIBCPP_STATIC_ASSERT(...) ((void)0) +#endif + +#define ASSERT_NOEXCEPT(...) \ + static_assert(noexcept(__VA_ARGS__), "Operation must be noexcept") + +#define ASSERT_NOT_NOEXCEPT(...) \ + static_assert(!noexcept(__VA_ARGS__), "Operation must NOT be noexcept") + +namespace test_macros_detail { +template <class T, class U> +struct is_same { enum { value = 0};} ; +template <class T> +struct is_same<T, T> { enum {value = 1}; }; +} // namespace test_macros_detail + +#define ASSERT_SAME_TYPE(...) \ + static_assert(test_macros_detail::is_same<__VA_ARGS__>::value, \ + "Types differ uexpectedly") + #endif // SUPPORT_TEST_MACROS_HPP diff --git a/test/support/test_memory_resource.hpp b/test/support/test_memory_resource.hpp new file mode 100644 index 0000000000000..e7b067cf631d5 --- /dev/null +++ b/test/support/test_memory_resource.hpp @@ -0,0 +1,507 @@ +//===----------------------------------------------------------------------===// +// +// 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_MEMORY_RESOURCE_HPP +#define SUPPORT_TEST_MEMORY_RESOURCE_HPP + +#include <experimental/memory_resource> +#include <memory> +#include <type_traits> +#include <cstddef> +#include <cstdlib> +#include <cstring> +#include <cstdint> +#include <cassert> +#include "test_macros.h" + +struct AllocController; + // 'AllocController' is a concrete type that instruments and controls the + // behavior of of test allocators. + +template <class T> +class CountingAllocator; + // 'CountingAllocator' is an basic implementation of the 'Allocator' + // requirements that use the 'AllocController' interface. + +template <class T> +class MinAlignAllocator; + // 'MinAlignAllocator' is an instrumented test type which implements the + // 'Allocator' requirements. 'MinAlignAllocator' ensures that it *never* + // returns a pointer to over-aligned storage. For example + // 'MinAlignPointer<char>{}.allocate(...)' will never a 2-byte aligned + // pointer. + +template <class T> +class NullAllocator; + // 'NullAllocator' is an instrumented test type which implements the + // 'Allocator' requirements except that 'allocator' and 'deallocate' are + // nops. + + +#define DISALLOW_COPY(Type) \ + Type(Type const&) = delete; \ + Type& operator=(Type const&) = delete + +constexpr std::size_t MaxAlignV = alignof(std::max_align_t); + +struct TestException {}; + +struct AllocController { + int copy_constructed = 0; + int move_constructed = 0; + + int alive = 0; + int alloc_count = 0; + int dealloc_count = 0; + int is_equal_count = 0; + + std::size_t alive_size; + std::size_t allocated_size; + std::size_t deallocated_size; + + std::size_t last_size = 0; + std::size_t last_align = 0; + void * last_pointer = 0; + + std::size_t last_alloc_size = 0; + std::size_t last_alloc_align = 0; + void * last_alloc_pointer = nullptr; + + std::size_t last_dealloc_size = 0; + std::size_t last_dealloc_align = 0; + void * last_dealloc_pointer = nullptr; + + bool throw_on_alloc = false; + + AllocController() = default; + + void countAlloc(void* p, size_t s, size_t a) { + ++alive; + ++alloc_count; + alive_size += s; + allocated_size += s; + last_pointer = last_alloc_pointer = p; + last_size = last_alloc_size = s; + last_align = last_alloc_align = a; + } + + void countDealloc(void* p, size_t s, size_t a) { + --alive; + ++dealloc_count; + alive_size -= s; + deallocated_size += s; + last_pointer = last_dealloc_pointer = p; + last_size = last_dealloc_size = s; + last_align = last_dealloc_align = a; + } + + void reset() { std::memset(this, 0, sizeof(*this)); } + +public: + bool checkAlloc(void* p, size_t s, size_t a) const { + return p == last_alloc_pointer && + s == last_alloc_size && + a == last_alloc_align; + } + + bool checkAlloc(void* p, size_t s) const { + return p == last_alloc_pointer && + s == last_alloc_size; + } + + bool checkAllocAtLeast(void* p, size_t s, size_t a) const { + return p == last_alloc_pointer && + s <= last_alloc_size && + a <= last_alloc_align; + } + + bool checkAllocAtLeast(void* p, size_t s) const { + return p == last_alloc_pointer && + s <= last_alloc_size; + } + + bool checkDealloc(void* p, size_t s, size_t a) const { + return p == last_dealloc_pointer && + s == last_dealloc_size && + a == last_dealloc_align; + } + + bool checkDealloc(void* p, size_t s) const { + return p == last_dealloc_pointer && + s == last_dealloc_size; + } + + bool checkDeallocMatchesAlloc() const { + return last_dealloc_pointer == last_alloc_pointer && + last_dealloc_size == last_alloc_size && + last_dealloc_align == last_alloc_align; + } + + void countIsEqual() { + ++is_equal_count; + } + + bool checkIsEqualCalledEq(int n) const { + return is_equal_count == n; + } +private: + DISALLOW_COPY(AllocController); +}; + +template <class T> +class CountingAllocator +{ +public: + typedef T value_type; + typedef T* pointer; + CountingAllocator() = delete; + explicit CountingAllocator(AllocController& PP) : P(&PP) {} + + CountingAllocator(CountingAllocator const& other) : P(other.P) { + P->copy_constructed += 1; + } + + CountingAllocator(CountingAllocator&& other) : P(other.P) { + P->move_constructed += 1; + } + + template <class U> + CountingAllocator(CountingAllocator<U> const& other) TEST_NOEXCEPT : P(other.P) { + P->copy_constructed += 1; + } + + template <class U> + CountingAllocator(CountingAllocator<U>&& other) TEST_NOEXCEPT : P(other.P) { + P->move_constructed += 1; + } + + T* allocate(std::size_t n) + { + void* ret = ::operator new(n*sizeof(T)); + P->countAlloc(ret, n*sizeof(T), alignof(T)); + return static_cast<T*>(ret); + } + + void deallocate(T* p, std::size_t n) + { + void* vp = static_cast<void*>(p); + P->countDealloc(vp, n*sizeof(T), alignof(T)); + ::operator delete(vp); + } + + AllocController& getController() const { return *P; } + +private: + template <class Tp> friend class CountingAllocator; + AllocController *P; +}; + +template <class T, class U> +inline bool operator==(CountingAllocator<T> const& x, + CountingAllocator<U> const& y) { + return &x.getController() == &y.getController(); +} + +template <class T, class U> +inline bool operator!=(CountingAllocator<T> const& x, + CountingAllocator<U> const& y) { + return !(x == y); +} + +template <class T> +class MinAlignedAllocator +{ +public: + typedef T value_type; + typedef T* pointer; + + MinAlignedAllocator() = delete; + + explicit MinAlignedAllocator(AllocController& R) : P(&R) {} + + MinAlignedAllocator(MinAlignedAllocator const& other) : P(other.P) { + P->copy_constructed += 1; + } + + MinAlignedAllocator(MinAlignedAllocator&& other) : P(other.P) { + P->move_constructed += 1; + } + + template <class U> + MinAlignedAllocator(MinAlignedAllocator<U> const& other) TEST_NOEXCEPT : P(other.P) { + P->copy_constructed += 1; + } + + template <class U> + MinAlignedAllocator(MinAlignedAllocator<U>&& other) TEST_NOEXCEPT : P(other.P) { + P->move_constructed += 1; + } + + T* allocate(std::size_t n) { + char* aligned_ptr = (char*)::operator new(alloc_size(n*sizeof(T))); + assert(is_max_aligned(aligned_ptr)); + + char* unaligned_ptr = aligned_ptr + alignof(T); + assert(is_min_aligned(unaligned_ptr)); + + P->countAlloc(unaligned_ptr, n * sizeof(T), alignof(T)); + + return ((T*)unaligned_ptr); + } + + void deallocate(T* p, std::size_t n) { + assert(is_min_aligned(p)); + + char* aligned_ptr = ((char*)p) - alignof(T); + assert(is_max_aligned(aligned_ptr)); + + P->countDealloc(p, n*sizeof(T), alignof(T)); + + return ::operator delete(static_cast<void*>(aligned_ptr)); + } + + AllocController& getController() const { return *P; } + +private: + static const std::size_t BlockSize = alignof(std::max_align_t); + + static std::size_t alloc_size(std::size_t s) { + std::size_t bytes = (s + BlockSize - 1) & ~(BlockSize - 1); + bytes += BlockSize; + assert(bytes % BlockSize == 0); + return bytes; + } + + static bool is_max_aligned(void* p) { + return reinterpret_cast<std::uintptr_t>(p) % BlockSize == 0; + } + + static bool is_min_aligned(void* p) { + if (alignof(T) == BlockSize) { + return is_max_aligned(p); + } else { + return reinterpret_cast<std::uintptr_t>(p) % BlockSize == alignof(T); + } + } + + template <class Tp> friend class MinAlignedAllocator; + mutable AllocController *P; +}; + + +template <class T, class U> +inline bool operator==(MinAlignedAllocator<T> const& x, + MinAlignedAllocator<U> const& y) { + return &x.getController() == &y.getController(); +} + +template <class T, class U> +inline bool operator!=(MinAlignedAllocator<T> const& x, + MinAlignedAllocator<U> const& y) { + return !(x == y); +} + +template <class T> +class NullAllocator +{ +public: + typedef T value_type; + typedef T* pointer; + NullAllocator() = delete; + explicit NullAllocator(AllocController& PP) : P(&PP) {} + + NullAllocator(NullAllocator const& other) : P(other.P) { + P->copy_constructed += 1; + } + + NullAllocator(NullAllocator&& other) : P(other.P) { + P->move_constructed += 1; + } + + template <class U> + NullAllocator(NullAllocator<U> const& other) TEST_NOEXCEPT : P(other.P) { + P->copy_constructed += 1; + } + + template <class U> + NullAllocator(NullAllocator<U>&& other) TEST_NOEXCEPT : P(other.P) { + P->move_constructed += 1; + } + + T* allocate(std::size_t n) + { + P->countAlloc(nullptr, n*sizeof(T), alignof(T)); + return nullptr; + } + + void deallocate(T* p, std::size_t n) + { + void* vp = static_cast<void*>(p); + P->countDealloc(vp, n*sizeof(T), alignof(T)); + } + + AllocController& getController() const { return *P; } + +private: + template <class Tp> friend class NullAllocator; + AllocController *P; +}; + +template <class T, class U> +inline bool operator==(NullAllocator<T> const& x, + NullAllocator<U> const& y) { + return &x.getController() == &y.getController(); +} + +template <class T, class U> +inline bool operator!=(NullAllocator<T> const& x, + NullAllocator<U> const& y) { + return !(x == y); +} + + + +template <class ProviderT, int = 0> +class TestResourceImp : public std::experimental::pmr::memory_resource +{ +public: + static int resource_alive; + static int resource_constructed; + static int resource_destructed; + + static void resetStatics() { + assert(resource_alive == 0); + resource_alive = 0; + resource_constructed = 0; + resource_destructed = 0; + } + + using memory_resource = std::experimental::pmr::memory_resource; + using Provider = ProviderT; + + int value; + + explicit TestResourceImp(int val = 0) : value(val) { + ++resource_alive; + ++resource_constructed; + } + + ~TestResourceImp() noexcept { + --resource_alive; + ++resource_destructed; + } + + void reset() { C.reset(); P.reset(); } + AllocController& getController() { return C; } + + bool checkAlloc(void* p, std::size_t s, std::size_t a) const + { return C.checkAlloc(p, s, a); } + + bool checkDealloc(void* p, std::size_t s, std::size_t a) const + { return C.checkDealloc(p, s, a); } + + bool checkIsEqualCalledEq(int n) const { return C.checkIsEqualCalledEq(n); } + +protected: + virtual void * do_allocate(std::size_t s, std::size_t a) { + if (C.throw_on_alloc) { +#ifndef TEST_HAS_NO_EXCEPTIONS + throw TestException{}; +#else + assert(false); +#endif + } + void* ret = P.allocate(s, a); + C.countAlloc(ret, s, a); + return ret; + } + + virtual void do_deallocate(void * p, std::size_t s, std::size_t a) { + C.countDealloc(p, s, a); + P.deallocate(p, s, a); + } + + virtual bool do_is_equal(memory_resource const & other) const noexcept { + C.countIsEqual(); + TestResourceImp const * o = dynamic_cast<TestResourceImp const *>(&other); + return o && o->value == value; + } +private: + mutable AllocController C; + mutable Provider P; + DISALLOW_COPY(TestResourceImp); +}; + +template <class Provider, int N> +int TestResourceImp<Provider, N>::resource_alive = 0; + +template <class Provider, int N> +int TestResourceImp<Provider, N>::resource_constructed = 0; + +template <class Provider, int N> +int TestResourceImp<Provider, N>::resource_destructed = 0; + + +struct NullProvider { + NullProvider() {} + void* allocate(size_t, size_t) { return nullptr; } + void deallocate(void*, size_t, size_t) {} + void reset() {} +private: + DISALLOW_COPY(NullProvider); +}; + +struct NewDeleteProvider { + NewDeleteProvider() {} + void* allocate(size_t s, size_t) { return ::operator new(s); } + void deallocate(void* p, size_t, size_t) { ::operator delete(p); } + void reset() {} +private: + DISALLOW_COPY(NewDeleteProvider); +}; + +template <size_t Size = 4096 * 10> // 10 pages worth of memory. +struct BufferProvider { + char buffer[Size]; + void* next = &buffer; + size_t space = Size; + + BufferProvider() {} + + void* allocate(size_t s, size_t a) { + void* ret = std::align(s, a, next, space); + if (ret == nullptr) { +#ifndef TEST_HAS_NO_EXCEPTIONS + throw std::bad_alloc(); +#else + assert(false); +#endif + } + + return ret; + } + + void deallocate(void*, size_t, size_t) {} + + void reset() { + next = &buffer; + space = Size; + } +private: + DISALLOW_COPY(BufferProvider); +}; + +using NullResource = TestResourceImp<NullProvider, 0>; +using NewDeleteResource = TestResourceImp<NewDeleteProvider, 0>; +using TestResource = TestResourceImp<BufferProvider<>, 0>; +using TestResource1 = TestResourceImp<BufferProvider<>, 1>; +using TestResource2 = TestResourceImp<BufferProvider<>, 2>; + + +#endif /* SUPPORT_TEST_MEMORY_RESOURCE_HPP */ diff --git a/test/support/type_id.h b/test/support/type_id.h new file mode 100644 index 0000000000000..309f0884e4a7b --- /dev/null +++ b/test/support/type_id.h @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// 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_TYPE_ID_H +#define SUPPORT_TYPE_ID_H + +#include <functional> +#include <cassert> + +#include "test_macros.h" + +#if TEST_STD_VER < 11 +#error This header requires C++11 or greater +#endif + +// TypeID - Represent a unique identifier for a type. TypeID allows equality +// comparisons between different types. +struct TypeID { + friend bool operator==(TypeID const& LHS, TypeID const& RHS) + {return LHS.m_id == RHS.m_id; } + friend bool operator!=(TypeID const& LHS, TypeID const& RHS) + {return LHS.m_id != RHS.m_id; } +private: + explicit constexpr TypeID(const int* xid) : m_id(xid) {} + + TypeID(const TypeID&) = delete; + TypeID& operator=(TypeID const&) = delete; + + const int* const m_id; + template <class T> friend TypeID const& makeTypeID(); + +}; + +// makeTypeID - Return the TypeID for the specified type 'T'. +template <class T> +inline TypeID const& makeTypeID() { + static int dummy; + static const TypeID id(&dummy); + return id; +} + +template <class ...Args> +struct ArgumentListID {}; + +// makeArgumentID - Create and return a unique identifier for a given set +// of arguments. +template <class ...Args> +inline TypeID const& makeArgumentID() { + return makeTypeID<ArgumentListID<Args...>>(); +} + +#endif // SUPPORT_TYPE_ID_H diff --git a/test/support/uses_alloc_types.hpp b/test/support/uses_alloc_types.hpp new file mode 100644 index 0000000000000..834e57729a7ae --- /dev/null +++ b/test/support/uses_alloc_types.hpp @@ -0,0 +1,298 @@ +//===----------------------------------------------------------------------===// +// +// 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 USES_ALLOC_TYPES_HPP +#define USES_ALLOC_TYPES_HPP + +# include <experimental/memory_resource> +# include <experimental/utility> +# include <memory> +# include <cassert> + +#include "test_memory_resource.hpp" +#include "type_id.h" + +// There are two forms of uses-allocator construction: +// (1) UA_AllocArg: 'T(allocator_arg_t, Alloc const&, Args&&...)' +// (2) UA_AllocLast: 'T(Args&&..., Alloc const&)' +// 'UA_None' represents non-uses allocator construction. +enum class UsesAllocatorType { + UA_None = 0, + UA_AllocArg = 2, + UA_AllocLast = 4 +}; +constexpr UsesAllocatorType UA_None = UsesAllocatorType::UA_None; +constexpr UsesAllocatorType UA_AllocArg = UsesAllocatorType::UA_AllocArg; +constexpr UsesAllocatorType UA_AllocLast = UsesAllocatorType::UA_AllocLast; + +template <class Alloc, std::size_t N> +class UsesAllocatorV1; + // Implements form (1) of uses-allocator construction from the specified + // 'Alloc' type and exactly 'N' additional arguments. It also provides + // non-uses allocator construction from 'N' arguments. This test type + // blows up when form (2) of uses-allocator is even considered. + +template <class Alloc, std::size_t N> +class UsesAllocatorV2; + // Implements form (2) of uses-allocator construction from the specified + // 'Alloc' type and exactly 'N' additional arguments. It also provides + // non-uses allocator construction from 'N' arguments. + +template <class Alloc, std::size_t N> +class UsesAllocatorV3; + // Implements both form (1) and (2) of uses-allocator construction from + // the specified 'Alloc' type and exactly 'N' additional arguments. It also + // provides non-uses allocator construction from 'N' arguments. + +template <class Alloc, std::size_t> +class NotUsesAllocator; + // Implements both form (1) and (2) of uses-allocator construction from + // the specified 'Alloc' type and exactly 'N' additional arguments. It also + // provides non-uses allocator construction from 'N' arguments. However + // 'NotUsesAllocator' never provides a 'allocator_type' typedef so it is + // never automatically uses-allocator constructed. + + +template <class ...ArgTypes, class TestType> +bool checkConstruct(TestType& value, UsesAllocatorType form, + typename TestType::CtorAlloc const& alloc) + // Check that 'value' was constructed using the specified 'form' of + // construction and with the specified 'ArgTypes...'. Additionally + // check that 'value' was constructed using the specified 'alloc'. +{ + if (form == UA_None) { + return value.template checkConstruct<ArgTypes&&...>(form); + } else { + return value.template checkConstruct<ArgTypes&&...>(form, alloc); + } +} + + +template <class ...ArgTypes, class TestType> +bool checkConstruct(TestType& value, UsesAllocatorType form) { + return value.template checkConstruct<ArgTypes&&...>(form); +} + +template <class TestType> +bool checkConstructionEquiv(TestType& T, TestType& U) + // check that 'T' and 'U' where initialized in the exact same manner. +{ + return T.checkConstructEquiv(U); +} + +//////////////////////////////////////////////////////////////////////////////// +namespace detail { + +template <bool IsZero, size_t N, class ArgList, class ...Args> +struct TakeNImp; + +template <class ArgList, class ...Args> +struct TakeNImp<true, 0, ArgList, Args...> { + typedef ArgList type; +}; + +template <size_t N, class ...A1, class F, class ...R> +struct TakeNImp<false, N, ArgumentListID<A1...>, F, R...> + : TakeNImp<N-1 == 0, N - 1, ArgumentListID<A1..., F>, R...> {}; + +template <size_t N, class ...Args> +struct TakeNArgs : TakeNImp<N == 0, N, ArgumentListID<>, Args...> {}; + +template <class T> +struct Identity { typedef T type; }; + +template <class T> +using IdentityT = typename Identity<T>::type; + +template <bool Value> +using EnableIfB = typename std::enable_if<Value, bool>::type; + +} // end namespace detail + +using detail::EnableIfB; + +struct AllocLastTag {}; + +template <class Alloc> +struct UsesAllocatorTestBase { +public: + using CtorAlloc = typename std::conditional< + std::is_same<Alloc, std::experimental::erased_type>::value, + std::experimental::pmr::memory_resource*, + Alloc + >::type; + + template <class ...ArgTypes> + bool checkConstruct(UsesAllocatorType expectType) const { + return expectType == constructor_called && + makeArgumentID<ArgTypes...>() == *args_id; + } + + template <class ...ArgTypes> + bool checkConstruct(UsesAllocatorType expectType, + CtorAlloc const& expectAlloc) const { + return expectType == constructor_called && + makeArgumentID<ArgTypes...>() == *args_id && + expectAlloc == allocator; + } + + bool checkConstructEquiv(UsesAllocatorTestBase& O) const { + return constructor_called == O.constructor_called + && *args_id == *O.args_id + && allocator == O.allocator; + } + +protected: + explicit UsesAllocatorTestBase(const TypeID* aid) + : args_id(aid), constructor_called(UA_None), allocator() + {} + + template <class ...Args> + UsesAllocatorTestBase(std::allocator_arg_t, CtorAlloc const& a, Args&&...) + : args_id(&makeArgumentID<Args&&...>()), + constructor_called(UA_AllocArg), + allocator(a) + {} + + template <class ...Args, class ArgsIDL = detail::TakeNArgs<sizeof...(Args) - 1, Args&&...>> + UsesAllocatorTestBase(AllocLastTag, Args&&... args) + : args_id(&makeTypeID<typename ArgsIDL::type>()), + constructor_called(UA_AllocLast), + allocator(getAllocatorFromPack( + typename ArgsIDL::type{}, + std::forward<Args>(args)...)) + { + } + +private: + template <class ...LArgs, class ...Args> + static CtorAlloc getAllocatorFromPack(ArgumentListID<LArgs...>, Args&&... args) { + return getAllocatorFromPackImp<LArgs const&...>(args...); + } + + template <class ...LArgs> + static CtorAlloc getAllocatorFromPackImp( + typename detail::Identity<LArgs>::type..., CtorAlloc const& alloc) { + return alloc; + } + + const TypeID* args_id; + UsesAllocatorType constructor_called = UA_None; + CtorAlloc allocator; +}; + +template <class Alloc, size_t Arity> +class UsesAllocatorV1 : public UsesAllocatorTestBase<Alloc> +{ +public: + typedef Alloc allocator_type; + + using Base = UsesAllocatorTestBase<Alloc>; + using CtorAlloc = typename Base::CtorAlloc; + + UsesAllocatorV1() : Base(&makeArgumentID<>()) {} + + // Non-Uses Allocator Ctor + template <class ...Args, EnableIfB<sizeof...(Args) == Arity> = false> + UsesAllocatorV1(Args&&... args) : Base(&makeArgumentID<Args&&...>()) {}; + + // Uses Allocator Arg Ctor + template <class ...Args> + UsesAllocatorV1(std::allocator_arg_t tag, CtorAlloc const & a, Args&&... args) + : Base(tag, a, std::forward<Args>(args)...) + { } + + // BLOWS UP: Uses Allocator Last Ctor + template <class _First, class ...Args, EnableIfB<sizeof...(Args) == Arity> _Dummy = false> + constexpr UsesAllocatorV1(_First&& __first, Args&&... args) + { + static_assert(!std::is_same<_First, _First>::value, ""); + } +}; + + +template <class Alloc, size_t Arity> +class UsesAllocatorV2 : public UsesAllocatorTestBase<Alloc> +{ +public: + typedef Alloc allocator_type; + + using Base = UsesAllocatorTestBase<Alloc>; + using CtorAlloc = typename Base::CtorAlloc; + + UsesAllocatorV2() : Base(&makeArgumentID<>()) {} + + // Non-Uses Allocator Ctor + template <class ...Args, EnableIfB<sizeof...(Args) == Arity> = false> + UsesAllocatorV2(Args&&... args) : Base(&makeArgumentID<Args&&...>()) {}; + + // Uses Allocator Last Ctor + template <class ...Args, EnableIfB<sizeof...(Args) == Arity + 1> = false> + UsesAllocatorV2(Args&&... args) + : Base(AllocLastTag{}, std::forward<Args>(args)...) + {} +}; + +template <class Alloc, size_t Arity> +class UsesAllocatorV3 : public UsesAllocatorTestBase<Alloc> +{ +public: + typedef Alloc allocator_type; + + using Base = UsesAllocatorTestBase<Alloc>; + using CtorAlloc = typename Base::CtorAlloc; + + UsesAllocatorV3() : Base(&makeArgumentID<>()) {} + + // Non-Uses Allocator Ctor + template <class ...Args, EnableIfB<sizeof...(Args) == Arity> = false> + UsesAllocatorV3(Args&&... args) : Base(&makeArgumentID<Args&&...>()) {}; + + // Uses Allocator Arg Ctor + template <class ...Args> + UsesAllocatorV3(std::allocator_arg_t tag, CtorAlloc const& alloc, Args&&... args) + : Base(tag, alloc, std::forward<Args>(args)...) + {} + + // Uses Allocator Last Ctor + template <class ...Args, EnableIfB<sizeof...(Args) == Arity + 1> = false> + UsesAllocatorV3(Args&&... args) + : Base(AllocLastTag{}, std::forward<Args>(args)...) + {} +}; + +template <class Alloc, size_t Arity> +class NotUsesAllocator : public UsesAllocatorTestBase<Alloc> +{ +public: + // no allocator_type typedef provided + + using Base = UsesAllocatorTestBase<Alloc>; + using CtorAlloc = typename Base::CtorAlloc; + + NotUsesAllocator() : Base(&makeArgumentID<>()) {} + + // Non-Uses Allocator Ctor + template <class ...Args, EnableIfB<sizeof...(Args) == Arity> = false> + NotUsesAllocator(Args&&... args) : Base(&makeArgumentID<Args&&...>()) {}; + + // Uses Allocator Arg Ctor + template <class ...Args> + NotUsesAllocator(std::allocator_arg_t tag, CtorAlloc const& alloc, Args&&... args) + : Base(tag, alloc, std::forward<Args>(args)...) + {} + + // Uses Allocator Last Ctor + template <class ...Args, EnableIfB<sizeof...(Args) == Arity + 1> = false> + NotUsesAllocator(Args&&... args) + : Base(AllocLastTag{}, std::forward<Args>(args)...) + {} +}; + +#endif /* USES_ALLOC_TYPES_HPP */ diff --git a/test/ubsan_blacklist.txt b/test/ubsan_blacklist.txt new file mode 100644 index 0000000000000..8331d7f41f634 --- /dev/null +++ b/test/ubsan_blacklist.txt @@ -0,0 +1 @@ +fun:*__hash_table* diff --git a/www/cxx1z_status.html b/www/cxx1z_status.html index 42bc3d76032a7..dc6587a1d1fd4 100644 --- a/www/cxx1z_status.html +++ b/www/cxx1z_status.html @@ -53,7 +53,7 @@ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3346.pdf">3346</a></td><td>LWG</td><td>Terminology for Container Element Requirements - Rev 1</td><td>Kona</td><td>Complete</td><td>3.4</td></tr> --> <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/n4089">N4089</a></td><td>LWG</td></td><td>Safe conversions in <code>unique_ptr<T[]></code>.</td><td>Urbana</td><td>In progress</td><td>3.9</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://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> @@ -71,12 +71,56 @@ <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> <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0004R1.html">P0004R1</a></td><td>LWG</td><td>Remove Deprecated iostreams aliases.</td><td>Kona</td><td>Complete</td><td>3.8</td></tr> - <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0006R0.html">P0006R0</a></td><td>LWG</td><td>Adopt Type Traits Variable Templates for C++17.</td><td>Kona</td><td>Complete</td><td>3.8</td></tr> + <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0006r0.html">P0006R0</a></td><td>LWG</td><td>Adopt Type Traits Variable Templates for C++17.</td><td>Kona</td><td>Complete</td><td>3.8</td></tr> <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0092R1.html">P0092R1</a></td><td>LWG</td><td>Polishing <chrono></td><td>Kona</td><td>Complete</td><td>3.8</td></tr> <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0007R1.html">P0007R1</a></td><td>LWG</td><td>Constant View: A proposal for a <tt>std::as_const</tt> helper function template.</td><td>Kona</td><td>Complete</td><td>3.8</td></tr> - <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0156R0.htm" >P0156R0</a></td><td>LWG</td><td>Variadic lock_guard(rev 3).</td><td>Kona</td><td></td><td></td></tr> + <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0156r0.html" >P0156R0</a></td><td>LWG</td><td>Variadic lock_guard(rev 3).</td><td>Kona</td><td>Complete (ABI V2 Only)</td><td>3.9</td></tr> <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0074R0.html">P0074R0</a></td><td>LWG</td><td>Making <tt>std::owner_less</tt> more flexible</td><td>Kona</td><td>Complete</td><td>3.8</td></tr> <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0013R1.html">P0013R1</a></td><td>LWG</td><td>Logical type traits rev 2</td><td>Kona</td><td>Complete</td><td>3.8</td></tr> + <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/P0024R2">P0024R2</a></td><td>LWG</td><td>The Parallelism TS Should be Standardized</td><td>Jacksonville</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/P0226R1">P0226R1</a></td><td>LWG</td><td>Mathematical Special Functions for C++17</td><td>Jacksonville</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/P0220R1">P0220R1</a></td><td>LWG</td><td>Adopt Library Fundamentals V1 TS Components for C++17</td><td>Jacksonville</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/P0218R1">P0218R1</a></td><td>LWG</td><td>Adopt the File System TS for C++17</td><td>Jacksonville</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/P0033R1">P0033R1</a></td><td>LWG</td><td>Re-enabling shared_from_this</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> + <tr><td><a href="http://wg21.link/P0005R4">P0005R4</a></td><td>LWG</td><td>Adopt not_fn from Library Fundamentals 2 for C++17</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> + <tr><td><a href="http://wg21.link/P0152R1">P0152R1</a></td><td>LWG</td><td>constexpr atomic::is_always_lock_free</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> + <tr><td><a href="http://wg21.link/P0185R1">P0185R1</a></td><td>LWG</td><td>Adding [nothrow-]swappable traits</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> + <tr><td><a href="http://wg21.link/P0253R1">P0253R1</a></td><td>LWG</td><td>Fixing a design mistake in the searchers interface</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> + <tr><td><a href="http://wg21.link/P0025R0">P0025R0</a></td><td>LWG</td><td>An algorithm to "clamp" a value between a pair of boundary values</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> + <tr><td><a href="http://wg21.link/P0154R1">P0154R1</a></td><td>LWG</td><td>constexpr std::hardware_{constructive,destructive}_interference_size</td><td>Jacksonville</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/P0030R1">P0030R1</a></td><td>LWG</td><td>Proposal to Introduce a 3-Argument Overload to std::hypot</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> + <tr><td><a href="http://wg21.link/P0031R0">P0031R0</a></td><td>LWG</td><td>A Proposal to Add Constexpr Modifiers to reverse_iterator, move_iterator, array and Range Access</td><td>Jacksonville</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/P0272R1">P0272R1</a></td><td>LWG</td><td>Give <tt>std::string</tt> a non-const <tt>.data()</tt> member function</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> + <tr><td><a href="http://wg21.link/P0077R2">P0077R2</a></td><td>LWG</td><td><tt>is_callable</tt>, the missing INVOKE related trait</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> + <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0032r3">p0032r3</a></td><td>LWG</td><td>Homogeneous interface for variant, any and optional</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0040r3">p0040r3</a></td><td>LWG</td><td>Extending memory management tools</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0063r3">p0063r3</a></td><td>LWG</td><td>C++17 should refer to C11 instead of C99</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0067r3">p0067r3</a></td><td>LWG</td><td>Elementary string conversions</td><td>Oulu</td><td>Postponed to Issaquah</td><td></td></tr> + <tr><td><a href="http://wg21.link/p0083r3">p0083r3</a></td><td>LWG</td><td>Splicing Maps and Sets</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0084r2">p0084r2</a></td><td>LWG</td><td>Emplace Return Type</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0088r3">p0088r3</a></td><td>LWG</td><td>Variant: a type-safe union for C++17</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0163r0">p0163r0</a></td><td>LWG</td><td>shared_ptr::weak_type</td><td>Oulu</td><td>Complete</td><td>3.9</td></tr> + <tr><td><a href="http://wg21.link/p0174r2">p0174r2</a></td><td>LWG</td><td>Deprecating Vestigial Library Parts in C++17</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0175r1">p0175r1</a></td><td>LWG</td><td>Synopses for the C library</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0180r2">p0180r2</a></td><td>LWG</td><td>Reserve a New Library Namespace for Future Standardization</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0181r1">p0181r1</a></td><td>LWG</td><td>Ordered by Default</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0209r2">p0209r2</a></td><td>LWG</td><td>make_from_tuple: apply for construction</td><td>Oulu</td><td>Complete</td><td>3.9</td></tr> + <tr><td><a href="http://wg21.link/p0219r1">p0219r1</a></td><td>LWG</td><td>Relative Paths for Filesystem</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0254r2">p0254r2</a></td><td>LWG</td><td>Integrating std::string_view and std::string</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0258r2">p0258r2</a></td><td>LWG</td><td>has_unique_object_representations</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0295r0">p0295r0</a></td><td>LWG</td><td>Adopt Selected Library Fundamentals V2 Components for C++17</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0302r1">p0302r1</a></td><td>LWG</td><td>Removing Allocator Support in std::function</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0307r2">p0307r2</a></td><td>LWG</td><td>Making Optional Greater Equal Again</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0336r1">p0336r1</a></td><td>LWG</td><td>Better Names for Parallel Execution Policies in C++17</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0337r0">p0337r0</a></td><td>LWG</td><td>Delete operator= for polymorphic_allocator</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0346r1">p0346r1</a></td><td>LWG</td><td>A <random> Nomenclature Tweak</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0358r1">p0358r1</a></td><td>LWG</td><td>Fixes for not_fn</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0371r1">p0371r1</a></td><td>LWG</td><td>Temporarily discourage memory_order_consume</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0392r0">p0392r0</a></td><td>LWG</td><td>Adapting string_view by filesystem paths</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/p0393r3">p0393r3</a></td><td>LWG</td><td>Making Variant Greater Equal</td><td>Oulu</td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/P0394r4">P0394r4</a></td><td>LWG</td><td>Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling</td><td>Oulu</td><td></td><td></td></tr> <!-- <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> --> </table> @@ -84,115 +128,196 @@ <!-- <I>Note: "NAD" means that the issue was deemed "Not a defect"</I> --> <table id="issues" border="1"> <tr><th>Issue #</th><th>Issue Name</th><th>Meeting</th><th>Status</th></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/lwg-defects.html#2465">LWG#2465</a></td></tr> + <tr><td><a href="http://wg21.link/LWG2016">2016</a></td><td>Allocators must be no-throw swappable</td><td>Urbana</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2376">2118</td><td><code>unique_ptr</code> for array does not support cv qualification conversion of actual argument</td><td>Urbana</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2170">2170</a></td><td>Aggregates cannot be <code>DefaultConstructible</code></td><td>Urbana</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2308">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://wg21.link/LWG2340">2340</a></td><td>Replacement allocation functions declared as inline</td><td>Urbana</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2354">2354</a></td><td>Unnecessary copying when inserting into maps with braced-init syntax</td><td>Urbana</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2377">2377</a></td><td><code>std::align</code> requirements overly strict</td><td>Urbana</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2396">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://wg21.link/LWG2399">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://wg21.link/LWG2400">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://wg21.link/LWG2401">2401</a></td><td><code>std::function</code> needs more noexcept</td><td>Urbana</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2404">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://wg21.link/LWG2408">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://wg21.link/LWG2465">LWG#2465</a></td></tr> + <tr><td></td><td></td><td></td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2106">2106</td><td><code>move_iterator</code> wrapping iterators returning prvalues</td><td>Urbana</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2129">2129</td><td>User specializations of <code>std::initializer_list</code></td><td>Urbana</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2212">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://wg21.link/LWG2217">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://wg21.link/LWG2230">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://wg21.link/LWG2233">2233</td><td><code>bad_function_call::what()</code> unhelpful</td><td>Urbana</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2266">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://wg21.link/LWG2325">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://wg21.link/LWG2361">2361</td><td>Apply 2299 resolution throughout library</td><td>Urbana</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2365">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://wg21.link/LWG2376">2376</td><td><code>bad_weak_ptr::what()</code> overspecified</td><td>Urbana</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2387">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://wg21.link/LWG2059">2059</td><td>C++0x ambiguity problem with map::erase</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2063">2063</td><td>Contradictory requirements for string move assignment</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2076">2076</td><td>Bad CopyConstructible requirement in set constructors</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2160">2160</td><td>Unintended destruction ordering-specification of resize</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2168">2168</td><td>Inconsistent specification of uniform_real_distribution constructor</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2239">2239</td><td>min/max/minmax requirements</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2364">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://wg21.link/LWG2369">2369</td><td>constexpr max(initializer_list) vs max_element</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2378">2378</td><td>Behaviour of standard exception types</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2403">2403</td><td>stof() should call strtof() and wcstof()</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2406">2406</td><td>negative_binomial_distribution should reject p == 1</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2407">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://wg21.link/LWG2411">2411</td><td>shared_ptr is only contextually convertible to bool</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2415">2415</td><td>Inconsistency between unique_ptr and shared_ptr</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2420">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://wg21.link/LWG2425">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://wg21.link/LWG2427">2427</td><td>Container adaptors as sequence containers, redux</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2428">2428</td><td>"External declaration" used without being defined</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2433">2433</td><td>uninitialized_copy()/etc. should tolerate overloaded operator&</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2434">2434</td><td>shared_ptr::use_count() is efficient</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2437">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://wg21.link/LWG2438">2438</td><td>std::iterator inheritance shouldn't be mandated</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2439">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://wg21.link/LWG2440">2440</td><td>seed_seq::size() should be noexcept</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2442">2442</td><td>call_once() shouldn't DECAY_COPY()</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2448">2448</td><td>Non-normative Container destructor specification</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2454">2454</td><td>Add raw_storage_iterator::base() member</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2455">2455</td><td>Allocator default construction should be allowed to throw</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2458">2458</td><td>N3778 and new library deallocation signatures</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2459">2459</td><td>std::polar should require a non-negative rho</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2464">2464</td><td>try_emplace and insert_or_assign misspecified</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2467">2467</td><td>is_always_equal has slightly inconsistent default</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2470">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://wg21.link/LWG2482">2482</td><td>[c.strings] Table 73 mentions nonexistent functions</td><td>Lenexa</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2488">2488</td><td>Placeholders should be allowed and encouraged to be constexpr</td><td>Lenexa</td><td>Complete</td></tr> <tr><td></td><td></td><td></td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/lwg-defects.html#2361">2361</td><td>Apply 2299 resolution throughout library</td><td>Urbana</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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><a href="http://wg21.link/LWG1169">1169</a></td><td><tt>num_get</tt> not fully compatible with <tt>strto*</tt></td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2072">2072</a></td><td>Unclear wording about capacity of temporary buffers</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2101">2101</a></td><td>Some transformation types can produce impossible types</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2111">2111</a></td><td>Which <tt>unexpected</tt>/<tt>terminate</tt> handler is called from the exception handling runtime?</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2119">2119</a></td><td>Missing <tt>hash</tt> specializations for extended integer types</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2127">2127</a></td><td>Move-construction with <tt>raw_storage_iterator</tt></td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2133">2133</a></td><td>Attitude to overloaded comma for iterators</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2156">2156</a></td><td>Unordered containers' <tt>reserve(n)</tt> reserves for <tt>n-1</tt> elements</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2218">2218</a></td><td>Unclear how containers use <tt>allocator_traits::construct()</tt></td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2219">2219</a></td><td><tt><i>INVOKE</i></tt>-ing a pointer to member with a <tt>reference_wrapper</tt> as the object expression</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2224">2224</a></td><td>Ambiguous status of access to non-live objects</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2234">2234</a></td><td><tt>assert()</tt> should allow usage in constant expressions</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2244">2244</a></td><td>Issue on <tt>basic_istream::seekg</tt></td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2250">2250</a></td><td>Follow-up On Library Issue 2207</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2259">2259</a></td><td>Issues in 17.6.5.5 rules for member functions</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2273">2273</a></td><td><tt>regex_match</tt> ambiguity</td><td>Kona</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2336">2336</a></td><td><tt>is_trivially_constructible/is_trivially_assignable</tt> traits are always false</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2353">2353</a></td><td><tt>std::next</tt> is over-constrained</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2367">2367</a></td><td><tt>pair</tt> and <tt>tuple</tt> are not correctly implemented for <tt>is_constructible</tt> with no args</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2380">2380</a></td><td>May <tt><cstdlib></tt> provide <tt>long ::abs(long)</tt> and <tt>long long ::abs(long long)</tt>?</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2384">2384</a></td><td>Allocator's <tt>deallocate</tt> function needs better specification</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2385">2385</a></td><td><tt>function::assign</tt> allocator argument doesn't make sense</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2435">2435</a></td><td><tt>reference_wrapper::operator()</tt>'s Remark should be deleted</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2447">2447</a></td><td>Allocators and <tt>volatile</tt>-qualified value types</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2462">2462</a></td><td><tt>std::ios_base::failure</tt> is overspecified</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2466">2466</a></td><td><tt>allocator_traits::max_size()</tt> default behavior is incorrect</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2469">2469</a></td><td>Wrong specification of Requires clause of <tt>operator[]</tt> for <tt>map</tt> and <tt>unordered_map</tt></td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2473">2473</a></td><td><tt>basic_filebuf</tt>'s relation to C <tt>FILE</tt> semantics</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2476">2476</a></td><td><tt>scoped_allocator_adaptor</tt> is not assignable</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2477">2477</a></td><td>Inconsistency of wordings in <tt>std::vector::erase()</tt> and <tt>std::deque::erase()</tt></td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2483">2483</a></td><td><tt>throw_with_nested()</tt> should use <tt>is_final</tt></td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2484">2484</a></td><td><tt>rethrow_if_nested()</tt> is doubly unimplementable</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2485">2485</a></td><td><tt>get()</tt> should be overloaded for <tt>const tuple&&</tt></td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2486">2486</a></td><td><tt>mem_fn()</tt> should be required to use perfect forwarding</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2487">2487</a></td><td><tt>bind()</tt> should be <tt>const</tt>-overloaded, not <i>cv</i>-overloaded</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2489">2489</a></td><td><tt>mem_fn()</tt> should be <tt>noexcept</tt></td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2492">2492</a></td><td>Clarify requirements for <tt>comp</tt></td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2495">2495</a></td><td>There is no such thing as an Exception Safety element</td><td>Kona</td><td>Complete</td></tr> <tr><td></td><td></td><td></td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/lwg-defects.html#2063">2063</td><td>Contradictory requirements for string move assignment</td><td>Lenexa</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/lwg-defects.html#2239">2239</td><td>min/max/minmax requirements</td><td>Lenexa</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://cplusplus.github.io/LWG/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://wg21.link/LWG2192">2192</a></td><td>Validity and return type of <tt>std::abs(0u)</tt> is unclear</td><td>Jacksonville</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2276">2276</a></td><td>Missing requirement on <tt>std::promise::set_exception</tt></td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2296">2296</a></td><td><tt>std::addressof</tt> should be <tt>constexpr</td><td>Jacksonville</td><td>Complete (Clang Only)</td></tr> + <tr><td><a href="http://wg21.link/LWG2450">2450</a></td><td><tt>(greater|less|greater_equal|less_equal)<void></tt> do not yield a total order for pointers</td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2520">2520</a></td><td>N4089 broke initializing <tt>unique_ptr<T[]></tt> from a <tt>nullptr</tt></td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2522">2522</a></td><td>[fund.ts.v2] Contradiction in <tt>set_default_resource</tt> specification</td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2523">2523</a></td><td><tt>std::promise</tt> synopsis shows two <tt>set_value_at_thread_exit()</tt>'s for no apparent reason</td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2537">2537</a></td><td>Constructors for <code>priority_queue</code> taking allocators should call <code>make_heap</code></td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2539">2539</a></td><td>[fund.ts.v2] <tt>invocation_trait</tt> definition definition doesn't work for surrogate call functions</td><td>Jacksonville</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2545">2545</a></td><td>Simplify wording for <tt>bind</tt> without explicitly specified return type</td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2557">2557</a></td><td>Logical operator traits are broken in the zero-argument case</td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2558">2558</a></td><td>[fund.ts.v2] Logical operator traits are broken in the zero-argument case</td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2559">2559</a></td><td>Error in LWG 2234's resolution</td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2560">2560</a></td><td><tt>is_constructible</tt> underspecified when applied to a function type</td><td>Jacksonville</td><td>Broken in 3.6; See r261653.</td></tr> + <tr><td><a href="http://wg21.link/LWG2565">2565</a></td><td><tt>std::function</tt>'s move constructor should guarantee nothrow for <tt>reference_wrapper</tt>s and function pointers</td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2566">2566</a></td><td>Requirements on the first template parameter of container adaptors</td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2571">2571</a></td><td>§[map.modifiers]/2 imposes nonsensical requirement on <tt>insert(InputIterator, InputIterator)</tt></td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2572">2572</a></td><td>The remarks for <tt>shared_ptr::operator*</tt> should apply to <i>cv</i>-qualified <tt>void</tt> as well</td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2574">2574</a></td><td>[fund.ts.v2] <tt>std::experimental::function::operator=(F&&)</tt> should be constrained</td><td>Jacksonville</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2575">2575</a></td><td>[fund.ts.v2] <tt>experimental::function::assign</tt> should be removed</td><td>Jacksonville</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2576">2576</a></td><td><tt>istream_iterator</tt> and <tt>ostream_iterator</tt> should use <tt>std::addressof</tt></td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2577">2577</a></td><td><tt>{shared,unique}_lock</tt> should use <tt>std::addressof</tt></td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2579">2579</a></td><td>Inconsistency wrt Allocators in <tt>basic_string</tt> assignment vs. <tt>basic_string::assign</tt></td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2581">2581</a></td><td>Specialization of <tt><type_traits></tt> variable templates should be prohibited</td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2582">2582</a></td><td>§[res.on.functions]/2's prohibition against incomplete types shouldn't apply to type traits</td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2583">2583</a></td><td>There is no way to supply an allocator for <tt>basic_string(str, pos)</tt></td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2585">2585</a></td><td><tt>forward_list::resize(size_type, const value_type&)</tt> effects incorrect</td><td>Jacksonville</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2586">2586</a></td><td>Wrong value category used in <tt>scoped_allocator_adaptor::construct()</tt></td><td>Jacksonville</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2590">2590</a></td><td>Aggregate initialization for <tt>std::array</tt></td><td>Jacksonville</td><td>Complete</td></tr> <tr><td></td><td></td><td></td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#1169">1169</a></td><td><tt>num_get</tt> not fully compatible with <tt>strto*</tt></td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2072">2072</a></td><td>Unclear wording about capacity of temporary buffers</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2101">2101</a></td><td>Some transformation types can produce impossible types</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2111">2111</a></td><td>Which <tt>unexpected</tt>/<tt>terminate</tt> handler is called from the exception handling runtime?</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2119">2119</a></td><td>Missing <tt>hash</tt> specializations for extended integer types</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2127">2127</a></td><td>Move-construction with <tt>raw_storage_iterator</tt></td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2133">2133</a></td><td>Attitude to overloaded comma for iterators</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2156">2156</a></td><td>Unordered containers' <tt>reserve(n)</tt> reserves for <tt>n-1</tt> elements</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2218">2218</a></td><td>Unclear how containers use <tt>allocator_traits::construct()</tt></td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2219">2219</a></td><td><tt><i>INVOKE</i></tt>-ing a pointer to member with a <tt>reference_wrapper</tt> as the object expression</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2224">2224</a></td><td>Ambiguous status of access to non-live objects</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2234">2234</a></td><td><tt>assert()</tt> should allow usage in constant expressions</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2244">2244</a></td><td>Issue on <tt>basic_istream::seekg</tt></td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2250">2250</a></td><td>Follow-up On Library Issue 2207</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2259">2259</a></td><td>Issues in 17.6.5.5 rules for member functions</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2273">2273</a></td><td><tt>regex_match</tt> ambiguity</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2336">2336</a></td><td><tt>is_trivially_constructible/is_trivially_assignable</tt> traits are always false</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2353">2353</a></td><td><tt>std::next</tt> is over-constrained</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2367">2367</a></td><td><tt>pair</tt> and <tt>tuple</tt> are not correctly implemented for <tt>is_constructible</tt> with no args</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2380">2380</a></td><td>May <tt><cstdlib></tt> provide <tt>long ::abs(long)</tt> and <tt>long long ::abs(long long)</tt>?</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2384">2384</a></td><td>Allocator's <tt>deallocate</tt> function needs better specification</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2385">2385</a></td><td><tt>function::assign</tt> allocator argument doesn't make sense</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2435">2435</a></td><td><tt>reference_wrapper::operator()</tt>'s Remark should be deleted</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2447">2447</a></td><td>Allocators and <tt>volatile</tt>-qualified value types</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2462">2462</a></td><td><tt>std::ios_base::failure</tt> is overspecified</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2466">2466</a></td><td><tt>allocator_traits::max_size()</tt> default behavior is incorrect</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2469">2469</a></td><td>Wrong specification of Requires clause of <tt>operator[]</tt> for <tt>map</tt> and <tt>unordered_map</tt></td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2473">2473</a></td><td><tt>basic_filebuf</tt>'s relation to C <tt>FILE</tt> semantics</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2476">2476</a></td><td><tt>scoped_allocator_adaptor</tt> is not assignable</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2477">2477</a></td><td>Inconsistency of wordings in <tt>std::vector::erase()</tt> and <tt>std::deque::erase()</tt></td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2483">2483</a></td><td><tt>throw_with_nested()</tt> should use <tt>is_final</tt></td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2484">2484</a></td><td><tt>rethrow_if_nested()</tt> is doubly unimplementable</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2485">2485</a></td><td><tt>get()</tt> should be overloaded for <tt>const tuple&&</tt></td><td>Kona</td><td>Completed</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2486">2486</a></td><td><tt>mem_fn()</tt> should be required to use perfect forwarding</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2487">2487</a></td><td><tt>bind()</tt> should be <tt>const</tt>-overloaded, not <i>cv</i>-overloaded</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2489">2489</a></td><td><tt>mem_fn()</tt> should be <tt>noexcept</tt></td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2492">2492</a></td><td>Clarify requirements for <tt>comp</tt></td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2495">2495</a></td><td>There is no such thing as an Exception Safety element</td><td>Kona</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2181">2181</a></td><td>Exceptions from seed sequence operations</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2309">2309</a></td><td>mutex::lock() should not throw device_or_resource_busy</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2310">2310</a></td><td>Public exposition only member in std::array</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2312">2312</a></td><td>tuple's constructor constraints need to be phrased more precisely</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2328">2328</a></td><td>Rvalue stream extraction should use perfect forwarding</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2393">2393</a></td><td>std::function's Callable definition is broken</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2422">2422</a></td><td>std::numeric_limits<T>::is_modulo description: "most machines" errata</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2426">2426</a></td><td>Issue about compare_exchange</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2436">2436</a></td><td>Comparators for associative containers should always be CopyConstructible</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2441">2441</a></td><td>Exact-width atomic typedefs should be provided</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2451">2451</a></td><td>[fund.ts.v2] optional should 'forward' T's implicit conversions</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2509">2509</a></td><td>[fund.ts.v2] any_cast doesn't work with rvalue reference targets and cannot move with a value target</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2516">2516</a></td><td>[fund.ts.v2] Public "exposition only" members in observer_ptr</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2542">2542</a></td><td>Missing const requirements for associative containers</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2549">2549</a></td><td>Tuple EXPLICIT constructor templates that take tuple parameters end up taking references to temporaries and will create dangling references</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2550">2550</a></td><td>Wording of unordered container's clear() method complexity</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2551">2551</a></td><td>[fund.ts.v2] "Exception safety" cleanup in library fundamentals required</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2555">2555</a></td><td>[fund.ts.v2] No handling for over-aligned types in optional</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2573">2573</a></td><td>[fund.ts.v2] std::hash<std::experimental::shared_ptr> does not work for arrays</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2596">2596</a></td><td>vector::data() should use addressof</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2667">2667</a></td><td>path::root_directory() description is confusing</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2669">2669</a></td><td>recursive_directory_iterator effects refers to non-existent functions</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2670">2670</a></td><td>system_complete refers to undefined variable 'base'</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2671">2671</a></td><td>Errors in Copy</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2673">2673</a></td><td>status() effects cannot be implemented as specified</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2674">2674</a></td><td>Bidirectional iterator requirement on path::iterator is very expensive</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2683">2683</a></td><td>filesystem::copy() says "no effects"</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2684">2684</a></td><td>priority_queue lacking comparator typedef</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2685">2685</a></td><td>shared_ptr deleters must not throw on move construction</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2687">2687</a></td><td>{inclusive,exclusive}_scan misspecified</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2688">2688</a></td><td>clamp misses preconditions and has extraneous condition on result</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2689">2689</a></td><td>Parallel versions of std::copy and std::move shouldn't be in order</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2698">2698</a></td><td>Effect of assign() on iterators/pointers/references</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2704">2704</a></td><td>recursive_directory_iterator's members should require '*this is dereferenceable'</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2706">2706</a></td><td>Error reporting for recursive_directory_iterator::pop() is under-specified</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2707">2707</a></td><td>path construction and assignment should have "string_type&&" overloads</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2709">2709</a></td><td>offsetof is unnecessarily imprecise</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2710">2710</a></td><td>"Effects: Equivalent to ..." doesn't count "Synchronization:" as determined semantics</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2711">2711</a></td><td>path is convertible from approximately everything under the sun</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2716">2716</a></td><td>Specification of shuffle and sample disallows lvalue URNGs</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2718">2718</a></td><td>Parallelism bug in [algorithms.parallel.exec] p2</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2719">2719</a></td><td>permissions function should not be noexcept due to narrow contract</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2720">2720</a></td><td>permissions function incorrectly specified for symlinks</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2721">2721</a></td><td>remove_all has incorrect post conditions</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2723">2723</a></td><td>Do directory_iterator and recursive_directory_iterator become the end iterator upon error?</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2724">2724</a></td><td>The protected virtual member functions of memory_resource should be private</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2725">2725</a></td><td>filesystem::exists(const path&, error_code&) error reporting</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2726">2726</a></td><td>[recursive_]directory_iterator::increment(error_code&) is underspecified</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2727">2727</a></td><td>Parallel algorithms with constexpr specifier</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2728">2728</a></td><td>status(p).permissions() and symlink_status(p).permissions() are not specified</td><td>Oulu</td><td>Complete</td></tr> <!-- - <tr><td><a href="http://cplusplus.github.io/LWG/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><a href="http://wg21.link/LWG1214">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: 5-Oct-2015</p> + <p>Last Updated: 12-Jul-2016</p> </div> </body> </html> diff --git a/www/index.html b/www/index.html index 821f25d7e04f1..70cf5b60155ed 100644 --- a/www/index.html +++ b/www/index.html @@ -166,96 +166,18 @@ <p>First please review our <a href="http://llvm.org/docs/DeveloperPolicy.html">Developer's Policy</a>. - <p> - On Mac OS 10.7 (Lion) and later, the easiest way to get this library is to install - Xcode 4.2 or later. However if you want to install tip-of-trunk from here - (getting the bleeding edge), read on. However, be warned that Mac OS - 10.7 will not boot without a valid copy of <code>libc++.1.dylib</code> in - <code>/usr/lib</code>. - </p> - - <p>To check out the code, use:</p> - - <ul> - <li><code>svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx</code></li> - </ul> - - <p> - Note that for an in-tree build, you should check out libcxx to - llvm/projects. - </p> - - <p> - The following instructions are for building libc++ on FreeBSD, Linux, or Mac - using <a href="http://libcxxabi.llvm.org/">libc++abi</a> as the C++ ABI - library. On Linux, it is also possible to use - <a href="#libsupcxx">libsupc++</a> or <a href="#libcxxrt">libcxxrt</a>. - </p> - - <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 where-you-want-to-build</code></li> - <li><code>mkdir build && cd build</code></li> - <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 buildc:</p> - <ul> - <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 where-you-want-to-build</code></li> - <li><code>mkdir build && cd build</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> - - <p>To run the tests:</p> - <ul> - <li><code>make check-libcxx</code></li> - </ul> - - <p>If you wish to run a subset of the test suite:</p> - <ul> - <li><code>cd path/to/libcxx/libcxx</code></li> - <li><code>alias lit='python path/to/llvm/utils/lit/lit.py'</code></li> - <li><code>export - LIBCXX_SITE_CONFIG=path/to/build/dir/projects/libcxx/test/lit.site.cfg - </code></li> - <li><code>lit -sv test/re/ # or whichever subset of tests you're interested - in</code></li> - </ul> - <p>The above is currently quite inconvenient. Sorry! We're working on it!</p> - - <p>More information on using LIT can be found - <a href="http://llvm.org/docs/CommandGuide/lit.html">here</a>. For more - general information about the LLVM testing infrastructure, see the - <a href="http://llvm.org/docs/TestingGuide.html">LLVM Testing Infrastructure - Guide</a> - </p> - - <p> - Shared libraries for libc++ should now be present in llvm/build/lib. Note - that it is safest to use this from its current location rather than - replacing your system's libc++ (if it has one, if not, go right ahead). - </p> - - <p> - Mac users, remember to be careful when replacing the system's libc++. - <strong>Your system will not be able to boot without a functioning - libc++.</strong> - </p> + The documentation for building and using libc++ can be found below. + <ul> + <li><a href="http://libcxx.llvm.org/docs/UsingLibcxx.html"> + <b>Using libc++</b></a> + Documentation on using the library in your programs</li> + <li><a href="http://libcxx.llvm.org/docs/BuildingLibcxx.html"> + <b>Building libc++</b></a> + Documentation on building the library using CMake</li> + <li><a href="http://libcxx.llvm.org/docs/TestingLibcxx.html"> + <b>Testing libc++</b></a> + Documentation for developers wishing to test the library</li> + </ul> <!--=====================================================================--> <h3>Notes and Known Issues</h3> @@ -279,65 +201,6 @@ <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">clang mailing list</a>.</p> <!--=====================================================================--> - <h2>Using libc++ in your programs</h2> - <!--=====================================================================--> - - <!--=====================================================================--> - <h3>FreeBSD and Mac OS X</h3> - <!--=====================================================================--> - - <p> - To use your system-installed libc++ with clang you can: - </p> - - <ul> - <li><code>clang++ -stdlib=libc++ test.cpp</code></li> - <li><code>clang++ -std=c++11 -stdlib=libc++ test.cpp</code></li> - </ul> - - <p> - To use your tip-of-trunk libc++ on Mac OS with clang you can: - </p> - - <ul> - <li><code>export DYLD_LIBRARY_PATH=path/to/build/lib</code> - <li><code>clang++ -std=c++11 -stdlib=libc++ -nostdinc++ - -I<path-to-libcxx>/include -L<path-to-libcxx>/lib - test.cpp</code></li> - </ul> - - <!--=====================================================================--> - <h3>Linux</h3> - <!--=====================================================================--> - - <p> - You will need to keep the source tree of - <a href="http://libcxxabi.llvm.org">libc++abi</a> available on your build - machine and your copy of the libc++abi shared library must be placed where - your linker will find it. - </p> - - <p> - Unfortunately you can't simply run clang with "-stdlib=libc++" at this - point, as clang is set up to link for libc++ linked to libsupc++. To get - around this you'll have to set up your linker yourself (or patch clang). - For example: - </p> - - <ul> - <li><code>clang++ -stdlib=libc++ helloworld.cpp -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc</code></li> - </ul> - - <p> - Alternately, you could just add libc++abi to your libraries list, which in - most situations will give the same result: - </p> - - <ul> - <li><code>clang++ -stdlib=libc++ helloworld.cpp -lc++abi</code></li> - </ul> - - <!--=====================================================================--> <h2>Bug reports and patches</h2> <!--=====================================================================--> @@ -355,136 +218,6 @@ </p> <!--=====================================================================--> - <h2 id="libsupcxx">Build on Linux using CMake and libsupc++.</h2> - <!--=====================================================================--> - - <p> - You will need libstdc++ in order to provide libsupc++. - </p> - - <p> - Figure out where the libsupc++ headers are on your system. On Ubuntu this - is <code>/usr/include/c++/<version></code> and - <code>/usr/include/c++/<version>/<target-triple></code> - </p> - - <p> - You can also figure this out by running - <pre> -$ echo | g++ -Wp,-v -x c++ - -fsyntax-only -ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" -ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../x86_64-linux-gnu/include" -#include "..." search starts here: -#include <...> search starts here: - /usr/include/c++/4.7 - /usr/include/c++/4.7/x86_64-linux-gnu - /usr/include/c++/4.7/backward - /usr/lib/gcc/x86_64-linux-gnu/4.7/include - /usr/local/include - /usr/lib/gcc/x86_64-linux-gnu/4.7/include-fixed - /usr/include/x86_64-linux-gnu - /usr/include -End of search list. - </pre> - - Note the first two entries happen to be what we are looking for. This - may not be correct on other platforms. - </p> - - <p> - We can now run CMake: - <ul> - <li><code>CC=clang CXX=clang++ cmake -G "Unix Makefiles" - -DLIBCXX_CXX_ABI=libstdc++ - -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> - <li>You can also substitute <code>-DLIBCXX_CXX_ABI=libsupc++</code> - above, which will cause the library to be linked to libsupc++ instead - of libstdc++, but this is only recommended if you know that you will - never need to link against libstdc++ in the same executable as libc++. - GCC ships libsupc++ separately but only as a static library. If a - program also needs to link against libstdc++, it will provide its - own copy of libsupc++ and this can lead to subtle problems. - <li><code>make</code></li> - <li><code>sudo make install</code></li> - </ul> - <p> - You can now run clang with -stdlib=libc++. - </p> - </p> - - <!--=====================================================================--> - <h2 id="libcxxrt">Build on Linux using CMake and libcxxrt.</h2> - <!--=====================================================================--> - - <p> - You will need to keep the source tree of - <a href="https://github.com/pathscale/libcxxrt/">libcxxrt</a> available - on your build machine and your copy of the libcxxrt shared library must - be placed where your linker will find it. - </p> - - <p> - We can now run CMake: - <ul> - <li><code>CC=clang CXX=clang++ cmake -G "Unix Makefiles" - -DLIBCXX_CXX_ABI=libcxxrt - -DLIBCXX_CXX_ABI_INCLUDE_PATHS="<libcxxrt-source-dir>/src" - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX=/usr - <libc++-source-dir></code></li> - <li><code>make</code></li> - <li><code>sudo make install</code></li> - </ul> - <p> - Unfortunately you can't simply run clang with "-stdlib=libc++" at this point, as - clang is set up to link for libc++ linked to libsupc++. To get around this - you'll have to set up your linker yourself (or patch clang). For example, - <ul> - <li><code>clang++ -stdlib=libc++ helloworld.cpp -nodefaultlibs -lc++ -lcxxrt -lm -lc -lgcc_s -lgcc</code></li> - </ul> - Alternately, you could just add libcxxrt to your libraries list, which in most - situations will give the same result: - <ul> - <li><code>clang++ -stdlib=libc++ helloworld.cpp -lcxxrt</code></li> - </ul> - </p> - </p> - - <!--=====================================================================--> - <h2 id="local-abi">Using a local ABI library</h2> - <!--=====================================================================--> - <p> - <strong>Note: This is not recommended in almost all cases.</strong><br> - Generally these instructions should only be used when you can't install - your ABI library. - </p> - <p> - Normally you must link libc++ against a ABI shared library that the - linker can find. If you want to build and test libc++ against an ABI - library not in the linker's path you need to set - <code>-DLIBCXX_CXX_ABI_LIBRARY_PATH=/path/to/abi/lib</code> when - configuring CMake. - </p> - <p> - An example build using libc++abi would look like: - <ul> - <li><code>CC=clang CXX=clang++ cmake - -DLIBCXX_CXX_ABI=libc++abi - -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> - </ul> - </p> - <p> - When testing libc++ LIT will automatically link against the proper ABI - library. - </p> - - <!--=====================================================================--> <h2>Design Documents</h2> <!--=====================================================================--> @@ -493,7 +226,6 @@ End of search list. <li><a href="type_traits_design.html"><tt><type_traits></tt></a></li> <li><a href="http://cplusplusmusings.wordpress.com/2012/07/05/clang-and-standard-libraries-on-mac-os-x/">Excellent notes by Marshall Clow</a></li> <li><a href="debug_mode.html">Status of debug mode</a></li> -<li><a href="lit_usage.html">LIT usage guide</a></li> </ul> </div> diff --git a/www/kona.html b/www/kona.html deleted file mode 100644 index 8fdfba163e4a9..0000000000000 --- a/www/kona.html +++ /dev/null @@ -1,154 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> -<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ --> -<html> -<head> - <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> - <title>libc++ Kona Status</title> - <link type="text/css" rel="stylesheet" href="menu.css"> - <link type="text/css" rel="stylesheet" href="content.css"> -</head> - -<body> -<div id="menu"> - <div> - <a href="http://llvm.org/">LLVM Home</a> - </div> - - <div class="submenu"> - <label>libc++ Info</label> - <a href="/index.html">About</a> - </div> - - <div class="submenu"> - <label>Quick Links</label> - <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> - </div> -</div> - -<div id="content"> - <!--*********************************************************************--> - <h1>libc++ Kona Status</h1> - <!--*********************************************************************--> - - <p>This is a temporary page; please check the c++1z status <a href="http://libcxx.llvm.org/cxx1z_status.html">here</a></p> - <p>This page shows the status of the papers and issues that are expected to be adopted in Kona.</p> - - <p>The groups that have contributed papers: - <ul> - <li>LWG - Library working group</li> - <li>CWG - Core Language Working group</li> - <li>SG1 - Study group #1 (Concurrency working group)</li> - </ul> - </p> - - <h3>Paper Status</h3> - <table id="papers" border="1"> - <tr><th>Paper #</th><th>Group</th><th>Paper Name</th><th>Meeting</th><th>Status</th><th>First released version</th></tr> -<!-- - <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3346.pdf">3346</a></td><td>LWG</td><td>Terminology for Container Element Requirements - Rev 1</td><td>Kona</td><td>Complete</td><td>3.4</td></tr> ---> -<!-- <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> --> - </table> - - <h3>Library Working group Issues Status</h3> - <table id="issues" border="1"> - <tr><th>Issue #</th><th>Issue Name</th><th>Meeting</th><th>Status</th></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#1169">1169</a></td><td><tt>num_get</tt> not fully compatible with <tt>strto*</tt></td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2072">2072</a></td><td>Unclear wording about capacity of temporary buffers</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2101">2101</a></td><td>Some transformation types can produce impossible types</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2111">2111</a></td><td>Which <tt>unexpected</tt>/<tt>terminate</tt> handler is called from the exception handling runtime?</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2119">2119</a></td><td>Missing <tt>hash</tt> specializations for extended integer types</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2127">2127</a></td><td>Move-construction with <tt>raw_storage_iterator</tt></td><td>Kona</td><td>Patch Ready</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2133">2133</a></td><td>Attitude to overloaded comma for iterators</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2156">2156</a></td><td>Unordered containers' <tt>reserve(n)</tt> reserves for <tt>n-1</tt> elements</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2218">2218</a></td><td>Unclear how containers use <tt>allocator_traits::construct()</tt></td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2219">2219</a></td><td><tt><i>INVOKE</i></tt>-ing a pointer to member with a <tt>reference_wrapper</tt> as the object expression</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2224">2224</a></td><td>Ambiguous status of access to non-live objects</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2234">2234</a></td><td><tt>assert()</tt> should allow usage in constant expressions</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2244">2244</a></td><td>Issue on <tt>basic_istream::seekg</tt></td><td>Kona</td><td>Patch Ready</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2250">2250</a></td><td>Follow-up On Library Issue 2207</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2259">2259</a></td><td>Issues in 17.6.5.5 rules for member functions</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2273">2273</a></td><td><tt>regex_match</tt> ambiguity</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2336">2336</a></td><td><tt>is_trivially_constructible/is_trivially_assignable</tt> traits are always false</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2353">2353</a></td><td><tt>std::next</tt> is over-constrained</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2367">2367</a></td><td><tt>pair</tt> and <tt>tuple</tt> are not correctly implemented for <tt>is_constructible</tt> with no args</td><td>Kona</td><td>Patch Ready</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2380">2380</a></td><td>May <tt><cstdlib></tt> provide <tt>long ::abs(long)</tt> and <tt>long long ::abs(long long)</tt>?</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2384">2384</a></td><td>Allocator's <tt>deallocate</tt> function needs better specification</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2385">2385</a></td><td><tt>function::assign</tt> allocator argument doesn't make sense</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2435">2435</a></td><td><tt>reference_wrapper::operator()</tt>'s Remark should be deleted</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2447">2447</a></td><td>Allocators and <tt>volatile</tt>-qualified value types</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2462">2462</a></td><td><tt>std::ios_base::failure</tt> is overspecified</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2466">2466</a></td><td><tt>allocator_traits::max_size()</tt> default behavior is incorrect</td><td>Kona</td><td>Patch Ready</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2469">2469</a></td><td>Wrong specification of Requires clause of <tt>operator[]</tt> for <tt>map</tt> and <tt>unordered_map</tt></td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2473">2473</a></td><td><tt>basic_filebuf</tt>'s relation to C <tt>FILE</tt> semantics</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2476">2476</a></td><td><tt>scoped_allocator_adaptor</tt> is not assignable</td><td>Kona</td><td>Patch Ready</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2477">2477</a></td><td>Inconsistency of wordings in <tt>std::vector::erase()</tt> and <tt>std::deque::erase()</tt></td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2483">2483</a></td><td><tt>throw_with_nested()</tt> should use <tt>is_final</tt></td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2484">2484</a></td><td><tt>rethrow_if_nested()</tt> is doubly unimplementable</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2485">2485</a></td><td><tt>get()</tt> should be overloaded for <tt>const tuple&&</tt></td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2486">2486</a></td><td><tt>mem_fn()</tt> should be required to use perfect forwarding</td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2487">2487</a></td><td><tt>bind()</tt> should be <tt>const</tt>-overloaded, not <i>cv</i>-overloaded</td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2489">2489</a></td><td><tt>mem_fn()</tt> should be <tt>noexcept</tt></td><td>Kona</td><td>Patch Ready</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2492">2492</a></td><td>Clarify requirements for <tt>comp</tt></td><td>Kona</td><td>Complete</td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2494">2494</a></td><td>[fund.ts.v2] <tt>ostream_joiner</tt> needs <tt>noexcept</tt></td><td>Kona</td><td></td></tr> - <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2495">2495</a></td><td>There is no such thing as an Exception Safety element</td><td>Kona</td><td></td></tr> - -<!-- - <tr><td><a href="http://cplusplus.github.io/LWG/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> - -<h3>Comments about the issues</h3> -<ul> -<li>1169 - We currently have a single function __num_get_float that calls strtold_l, and then casts down to the appropriate floating point type. That will have to change.</li> -<li><i>2072 - We already do this; this is just making the wording better.</i></li> -<li>2101 - Need to write some careful test cases. In particular, need to check function types with/without const/ref qualifiers. Currently we get this wrong. Installing metashell to play with these.</li> -<li><i>2111 - Resolved an ambiguity by calling it out. No code change required.</i></li> -<li>2119 - Hashes for all integral and enumeration types. Research needed</li> -<li><i>2127 - Add a new member to raw_storage_iterator. Looks simple.</i> <b>Patch Available</b></li> -<li><i>2133 - We do this already; thanks Eric.</i></li> -<li>2156 - check and make sure that we already do this. Write a test.</li> -<li>2181 - I suspect that this will not require any code changes, but will need to be read carefully.</li> -<li>2218 - Shouldn't require any code changes.</li> -<li>2219 - Sizable changes required. INVOKE needs 2 additional overloads and plenty of tests. I'm not going to back port this to C++03. (Eric)</li> -<li>2224 - </li> -<li>2234 - </li> -<li><i>2244 - We don't do this; easy fix. <b>Patch Available</b></i></li> -<li>2250 - Looks like wording cleanup. Need to check more closely, but I think there's no code changes here.</li> -<li><i>2259 - No code changes needed here.</i></li> -<li>2273 - </li> -<li>2336 - <b>Check later</b></li> -<li>2353 - Simple change, needs a test. (test probably used to exist)</li> -<li><i>2367 - <b>Patch Available as D13750</b> (Eric)</i></li> -<li><i>2380 - No code changes here; we already do this.</i></li> -<li><i>2384 - Wording cleanup; no code change required</i></li> -<li>2385 - Removing broken signatures. Only question is "how far back"?</li> -<li><i>2435 - Wording cleanup; no code change required</i></li> -<li><i>2447 - This is a relaxation of a requirement that we satisfy. No changes needed.</i>.</li> -<li><i>2462 - Added a simple test. No code change needed</i> <b>Patch Available</b></li> -<li><i>2466 - Simple change; need a test.</i> <b>Patch Available</b></li> -<li>2469 - This is a follow on to 2464, which we're done. This restates a bunch of operations in terms of newer ops. Probably refactoring to do here, but tests shouldn't change.</li> -<li><i>2473 - There are two changes here; one to <tt>filebuf::seekpos</tt> and the other to <tt>filebuf::sync</tt>. We do both of these already.</i></li> -<li><i>2476 - Just needed tests.</i> <b>Patch Available</b></li> -<li><i>2477 - Wording cleanup.</i></li> -<li><i>2483 - We already do this.</i></li> -<li><i>2484 - We already do this.</i></li> -<li>2485 - Ask Eric to do it. </li> -<li>2486 - Lots of code changes, all mechanical. Tests will be sizable.</li> -<li><i>2487 - This is removing a requirement on bind(), which we don't currently satisfy. So, nothing to do.</i></li> -<li><i>2489 - Looks easy. Just add some NOEXCEPT, and tests.</i> <b>Patch Available</b></li> -<li><i>2492 - Wording cleanup; no code changes needed.</i></li> -<li>2494 - My implementation of this (not checked in) already has these.</li> -<li>2494 - </li> -</ul> - -<p>Last Updated: 5-Oct-2015</p> -</div> -</body> -</html> diff --git a/www/lit_usage.html b/www/lit_usage.html deleted file mode 100644 index 2fcb2d0a5f979..0000000000000 --- a/www/lit_usage.html +++ /dev/null @@ -1,207 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> -<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ --> -<html> -<head> - <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> - <title>Testing libc++ using LIT</title> - <link type="text/css" rel="stylesheet" href="menu.css"> - <link type="text/css" rel="stylesheet" href="content.css"> - <style> - .lit-option { - padding-top: 0.5em; - margin-bottom: 0.0em; - font-size: medium; - color: #2d58b7 - } - .lit-option-desc { - display: block; - margin-top: 0em; - margin-bottom: 0em; - margin-left: 20px; - margin-right: 20px; - } - </style> -</head> - -<body> -<div id="menu"> - <div> - <a href="http://llvm.org/">LLVM Home</a> - </div> - - <div class="submenu"> - <label>libc++ Info</label> - <a href="/index.html">About</a> - </div> - - <div class="submenu"> - <label>Quick Links</label> - <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> - </div> -</div> - -<div id="content"> -<!--*********************************************************************--> - <h1>Testing libc++ using LIT</h1> -<!--*********************************************************************--> -<p> -libc++ uses LIT to configure and run its tests. The primary way to run the -libc++ tests is by using <code>make check-libcxx</code>. However since libc++ -can be used in any number of possible configurations it is important to -customize the way LIT builds and runs the tests. This guide provides -information on how to use LIT directly to test libc++. -</p> -<p> -Documentation for LIT can be found -<a href="http://llvm.org/docs/CommandGuide/lit.html">here</a>. -</p> - -<!--*********************************************************************--> - <h2>Getting Started</h2> -<!--*********************************************************************--> -<p> -After building libc++ use the following commands before you start using LIT to -test. -</p> -<ul> - <li><code>alias lit='python path/to/llvm/utils/lit/lit.py'</code></li> - <li><code>export LIBCXX_SITE_CONFIG=path/to/build-libcxx/test/lit.site.cfg</code></li> -</ul> -<p> -You can now run the libc++ tests by running: -</p> -<ul> - <li><code>cd path/to/libcxx</code></li> - <li><code>lit -sv ./test</code></li> -</ul> -<p> -To only run a subsection of the tests use: -<ul> - <li><code>lit -sv test/std/numerics # Run only the numeric tests</code></li> -</ul> - -<!--*********************************************************************--> - <h2>Customization Options</h2> -<!--*********************************************************************--> -<p> -libc++'s testsuite provides multiple options to configure the way the tests -are build and run. To use these options you pass them on the LIT command line -as <code>--param NAME</code> or <code>--param NAME=VALUE</code>. Some options -have default values specified during CMake's configuration. Passing the option -on the command line will override the default. -</p> - - -<p> -<h3 class="lit-option">libcxx_site_config=<path/to/lit.site.cfg></h3> -<blockquote class="lit-option-desc"> -Specify the site configuration to use when running the tests. This option -overrides the enviroment variable <code>LIBCXX_SITE_CONFIG</code> -</blockquote> -</p> - -<p> -<h3 class="lit-option">libcxx_headers=<path/to/headers></h3> -<blockquote class="lit-option-desc"> -Specify the libc++ headers that are tested. By default the headers in the source -tree are used. -</blockquote> -</p> - -<p> -<h3 class="lit-option">libcxx_library=<path/to/libc++.so></h3> -<blockquote class="lit-option-desc"> -Specify the libc++ library that is tested. By default the library in the build -directory is used. This option cannot be used when <code>use_system_lib</code> -is provided. -</blockquote> -</p> - -<p> -<h3 class="lit-option">use_system_lib=<bool></h3> -<blockquote class="lit-option-desc"> -<b>Default: </b><code>False</code></br> -Enable or disable testing against the installed version of libc++ library. -Note: This does not use the installed headers. -</blockquote> -</p> - -<p> -<h3 class="lit-option">use_lit_shell=<bool></h3> -<blockquote class="lit-option-desc"> -Enable or disable the use of LIT's internal shell in ShTests. If the enviroment -variable <code>LIT_USE_INTERNAL_SHELL</code> is present then that is used as the -default value. Otherwise the default value is <code>True</code> on Windows and -<code>False</code> on every other platform. -</blockquote> -</p> - -<p> -<h3 class="lit-option">no_default_flags=<bool></h3> -<blockquote class="lit-option-desc"> -<b>Default: </b><code>False</code></br> -Disable all default compile and link flags from being added. When this option is -used only flags specified using the <code>compile_flags</code> and -<code>link_flags</code> will be used. -</blockquote> -</p> - -<p> -<h3 class="lit-option">compile_flags="<list-of-args>"</h3> -<blockquote class="lit-option-desc"> -Specify additional compile flags as a space delimited string. -Note: This options should not be used to change the standard version used. -</blockquote> -</p> - -<p> -<h3 class="lit-option">link_flags="<list-of-args>"</h3> -<blockquote class="lit-option-desc"> -Specify additional link flags as a space delimited string. -</blockquote> -</p> - -<p> -<h3 class="lit-option">std=<standard version></h3> -<blockquote class="lit-option-desc"> -<b>Values: </b><code>c++98, c++03, c++11, c++14, c++1z</code></br> -Change the standard version used when building the tests. -</blockquote> -</p> - -<p> -<h3 class="lit-option">debug_level=<level></h3> -<blockquote class="lit-option-desc"> -<b>Values: </b><code>0, 1</code></br> -Enable the use of debug mode. Level 0 enables assertions and level 1 enables -assertions and debugging of iterator misuse. -</blockquote> -</p> - -<p> -<h3 class="lit-option">use_sanitizer=<sanitizer name></h3> -<blockquote class="lit-option-desc"> -<b>Values: </b><code>Memory, MemoryWithOrigins, Address, Undefined</code></br> -Run the tests using the given sanitizer. If <code>LLVM_USE_SANITIZER</code> -was given when building libc++ then that sanitizer will be used by default. -</blockquote> -</p> - -<p> -<h3 class="lit-option">color_diagnostics</h3> -<blockquote class="lit-option-desc"> -Enable the use of colorized compile diagnostics. If the -<code>color_diagnostics</code> option is specified or the enviroment variable -<code>LIBCXX_COLOR_DIAGNOSTICS</code> is present then color diagnostics will be -enabled. -</blockquote> -</p> - -</div> -</body> -</html> diff --git a/www/ts1z_status.html b/www/ts1z_status.html index 9d4a000b0b991..4c460c5d14978 100644 --- a/www/ts1z_status.html +++ b/www/ts1z_status.html @@ -72,6 +72,14 @@ <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>Class memory_resource</td><td>Complete</td></tr> + <tr><td>Class template polymorphic_allocator</td><td>Complete</td></tr> + <tr><td>Template alias resource_adaptor</td><td>Complete</td></tr> + <tr><td>Global memory resources</td><td>Complete</td></tr> + <tr><td>Pool resource classes</td><td>Implementation in progress</td></tr> + <tr><td>Class monotonic_buffer_resource</td><td>Implementation in progress</td></tr> + <tr><td>Alias templates using polymorphic memory resource</td><td>Complete</td></tr> + <tr><td></td><td></td></tr> <tr><td>Searchers</td><td>Complete</td></tr> <tr><td>Optional Objects</td><td>Initial implementation complete</td></tr> <tr><td>class any</td><td>Complete</td></tr> @@ -90,12 +98,12 @@ <h3>Features in Filesystem</h3> <table id="Features" border="1"> - <tr><th>Feature Name</th><th>Status</th></tr> - <tr><td>All features</td><td>Not started</td></tr> + <tr><th>Feature Name</th><th>Status</th><th>First released version</th></tr> + <tr><td>All features</td><td>Complete</td><td>3.9</td></tr> </table> - <p>Last Updated: 7-Dec-2015</p> + <p>Last Updated: 17-June-2016</p> </div> </body> </html> diff --git a/www/upcoming_meeting.html b/www/upcoming_meeting.html new file mode 100644 index 0000000000000..1316618e9b417 --- /dev/null +++ b/www/upcoming_meeting.html @@ -0,0 +1,137 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ --> +<html> +<head> + <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"> + <title>libc++ Upcoming Meeting Status</title> + <link type="text/css" rel="stylesheet" href="menu.css"> + <link type="text/css" rel="stylesheet" href="content.css"> +</head> + +<body> +<div id="menu"> + <div> + <a href="http://llvm.org/">LLVM Home</a> + </div> + + <div class="submenu"> + <label>libc++ Info</label> + <a href="/index.html">About</a> + </div> + + <div class="submenu"> + <label>Quick Links</label> + <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> + </div> +</div> + +<div id="content"> + <!--*********************************************************************--> + <h1>libc++ Oulu Status</h1> + <!--*********************************************************************--> + + <p>This is a temporary page; please check the c++1z status <a href="http://libcxx.llvm.org/cxx1z_status.html">here</a></p> + <p>This page shows the status of the papers and issues that are expected to be adopted in Oulu.</p> + + <p>The groups that have contributed papers: + <ul> + <li>LWG - Library working group</li> + <li>CWG - Core Language Working group</li> + <li>SG1 - Study group #1 (Concurrency working group)</li> + </ul> + </p> + + <h3>Paper Status</h3> + <table id="papers" border="1"> + <tr><th>Paper #</th><th>Group</th><th>Paper Name</th><th>Meeting</th><th>Status</th><th>First released version</th></tr> +<!-- + <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3346.pdf">3346</a></td><td>LWG</td><td>Terminology for Container Element Requirements - Rev 1</td><td>Kona</td><td>Complete</td><td>3.4</td></tr> +--> +<!-- <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> --> + </table> + + <h3>Library Working group Issues Status</h3> + <table id="issues" border="1"> + <tr><th>Issue #</th><th>Issue Name</th><th>Meeting</th><th>Status</th></tr> + + <tr><td><a href="http://wg21.link/LWG2181">2181</a></td><td>Exceptions from seed sequence operations</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2309">2309</a></td><td>mutex::lock() should not throw device_or_resource_busy</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2310">2310</a></td><td>Public exposition only member in std::array</td><td>Oulu</td><td>Patch Ready</td></tr> + <tr><td><a href="http://wg21.link/LWG2328">2328</a></td><td>Rvalue stream extraction should use perfect forwarding</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2393">2393</a></td><td>std::function's Callable definition is broken</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2426">2426</a></td><td>Issue about compare_exchange</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2436">2436</a></td><td>Comparators for associative containers should always be CopyConstructible</td><td>Oulu</td><td>Patch Ready</td></tr> + <tr><td><a href="http://wg21.link/LWG2441">2441</a></td><td>Exact-width atomic typedefs should be provided</td><td>Oulu</td><td>Patch Ready</td></tr> + <tr><td><a href="http://wg21.link/LWG2451">2451</a></td><td>[fund.ts.v2] optional<T> should 'forward' T's implicit conversions</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2509">2509</a></td><td>[fund.ts.v2] any_cast doesn't work with rvalue reference targets and cannot move with a value target</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2516">2516</a></td><td>[fund.ts.v2] Public "exposition only" members in observer_ptr</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2542">2542</a></td><td>Missing const requirements for associative containers</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2549">2549</a></td><td>Tuple EXPLICIT constructor templates that take tuple parameters end up taking references to temporaries and will create dangling references</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2550">2550</a></td><td>Wording of unordered container's clear() method complexity</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2551">2551</a></td><td>[fund.ts.v2] "Exception safety" cleanup in library fundamentals required</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2555">2555</a></td><td>[fund.ts.v2] No handling for over-aligned types in optional</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2573">2573</a></td><td>[fund.ts.v2] std::hash<std::experimental::shared_ptr<T>> does not work for arrays</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2596">2596</a></td><td>vector::data() should use addressof</td><td>Oulu</td><td>Patch Ready</td></tr> + <tr><td><a href="http://wg21.link/LWG2667">2667</a></td><td>path::root_directory() description is confusing</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2669">2669</a></td><td>recursive_directory_iterator effects refers to non-existent functions</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2670">2670</a></td><td>system_complete refers to undefined variable 'base'</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2671">2671</a></td><td>Errors in Copy</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2673">2673</a></td><td>status() effects cannot be implemented as specified</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2674">2674</a></td><td>Bidirectional iterator requirement on path::iterator is very expensive</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2683">2683</a></td><td>filesystem::copy() says "no effects"</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2684">2684</a></td><td>priority_queue lacking comparator typedef</td><td>Oulu</td><td>Patch Ready</td></tr> + <tr><td><a href="http://wg21.link/LWG2685">2685</a></td><td>shared_ptr deleters must not not throw on move construction</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2688">2688</a></td><td>clamp misses preconditions and has extraneous condition on result</td><td>Oulu</td><td>Patch Ready</td></tr> + <tr><td><a href="http://wg21.link/LWG2689">2689</a></td><td>Parallel versions of std::copy and std::move shouldn't be in order</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2698">2698</a></td><td>Effect of assign() on iterators/pointers/references</td><td>Oulu</td><td>Complete</td></tr> + <tr><td><a href="http://wg21.link/LWG2706">2706</a></td><td>Error reporting for recursive_directory_iterator::pop() is under-specified</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2707">2707</a></td><td>path construction and assignment should have "string_type&&" overloads</td><td>Oulu</td><td></td></tr> + <tr><td><a href="http://wg21.link/LWG2710">2710</a></td><td>"Effects: Equivalent to ..." doesn't count "Synchronization:" as determined semantics</td><td>Oulu</td><td>Complete</td></tr> + </table> + +<h3>Comments about the issues</h3> +<ul> +<li>2181 - </li> +<li>2309 - I don't think there's anything to do here.</li> +<li>2310 - I think we need a test that checks array::data() == addressof(front()). Other than that, we're good.</li> +<li>2328 - <istream>:1467 - fix is straightforward. Need to think about tests.</li> +<li>2393 - </li> +<li>2426 - I believe this is just a wording clarification, but need to study it some more.</li> +<li>2436 - Adds Requirements on compare/hasher. We can static_assert this, and test it.</li> +<li>2441 - Looks straightforward.</li> +<li>2451 - <i>Significant work.</i></li> +<li>2509 - <i>Significant work.</i></li> +<li>2516 - We don't have an observer_ptr implementation yet.</li> +<li>2542 - This is probably mostly writing additional tests.</li> +<li>2549 - Tuple EXPLICIT - Eric?</li> +<li>2550 - Wording clarification; no code change needed.</li> +<li>2551 - Wording cleanup; no code change needed.</li> +<li>2555 - Wording clarification; no code change needed.</li> +<li>2573 - </li> +<li>2596 - Turns out we do this already. Needs tests, though.</li> +<li>2667 - Wording clarification; no code change needed.</li> +<li>2669 - Wording clarification; no code change needed.</li> +<li>2670 - Wording clarification; no code change needed.</li> +<li>2671 - Wording clarification; no code change needed.</li> +<li>2673 - Wording clarification; no code change needed.</li> +<li>2674 - We already depend on the requirements being relaxed.</li> +<li>2683 - We already do this.</li> +<li>2684 - We already have one; just need to add a test for it.</li> +<li>2685 - Wording clarification; no code change needed. We don't handle throwing move ctors here anyway.</li> +<li>2688 - I believe that we already do this. Add more tests</li> +<li>2689 - We don't have a parallel implementation yet (though I'm working on it).</li> +<li>2698 - Wording clarification; no code change needed.</li> +<li>2706 - We already implement the new pop(error_code&) overloads</li> +<li>2707 - We already implement the new overloads.</li> +<li>2710 - Wording cleanup; no code change needed.</li> +</ul> + +<p>Last Updated: 7-Jun-2016</p> +</div> +</body> +</html> |