Revert "Revert "Update aosp/master libcxx rebase to r263688""

This reverts commit 1d4a1edbc7e4461b59239e1b8297e9dd395a6322.

Change-Id: I2909937fe582f2c5552bc86e7f4d2d5cff0de0aa
diff --git a/CMakeLists.txt b/CMakeLists.txt
index be6fbbe..8460561 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,13 +12,6 @@
   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,6 +19,25 @@
   ${CMAKE_MODULE_PATH}
   )
 
+# 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"
+                  "Reconfigure with -DLLVM_CONFIG=path/to/llvm-config "
+                  "or -DLLVM_PATH=path/to/llvm-source-root.")
+endif()
+
 # Require out of source build.
 include(MacroEnsureOutOfSourceBuild)
 MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
@@ -33,16 +45,6 @@
  build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there."
  )
 
-# Find the LLVM sources and simulate LLVM CMake options.
-include(HandleOutOfTreeLLVM)
-if (LIBCXX_BUILT_STANDALONE AND NOT LLVM_FOUND)
-  message(WARNING "UNSUPPORTED LIBCXX CONFIGURATION DETECTED: "
-                  "llvm-config not found and LLVM_PATH not defined.\n"
-                  "Reconfigure with -DLLVM_CONFIG=path/to/llvm-config "
-                  "or -DLLVM_PATH=path/to/llvm-source-root.")
-endif()
-
-
 #===============================================================================
 # Setup CMake Options
 #===============================================================================
@@ -50,12 +52,17 @@
 # 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_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
     "Define suffix of library directory name (32/64)")
 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)
 
 # ABI Library options ---------------------------------------------------------
 set(LIBCXX_CXX_ABI "${LIBCXX_CXX_ABI}" CACHE STRING
@@ -63,8 +70,41 @@
 set(CXXABIS none libcxxabi libcxxrt libstdc++ libsupc++)
 set_property(CACHE LIBCXX_CXX_ABI PROPERTY STRINGS ;${CXXABIS})
 
+# Setup the default options if LIBCXX_CXX_ABI is not specified.
+if (NOT LIBCXX_CXX_ABI)
+  if (NOT DEFINED LIBCXX_BUILT_STANDALONE AND
+      IS_DIRECTORY "${CMAKE_SOURCE_DIR}/projects/libcxxabi")
+    set(LIBCXX_CXX_ABI_LIBNAME "libcxxabi")
+    set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${CMAKE_SOURCE_DIR}/projects/libcxxabi/include")
+    set(LIBCXX_CXX_ABI_INTREE 1)
+  else ()
+    set(LIBCXX_CXX_ABI_LIBNAME "none")
+  endif ()
+else ()
+  set(LIBCXX_CXX_ABI_LIBNAME "${LIBCXX_CXX_ABI}")
+endif ()
+
+# Use a static copy of the ABI library when linking libc++. This option
+# cannot be used with LIBCXX_ENABLE_ABI_LINKER_SCRIPT.
 option(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "Statically link the ABI library" OFF)
 
+# Generate and install a linker script inplace of libc++.so. The linker script
+# will link libc++ to the correct ABI library. This option is on by default
+# On UNIX platforms other than Apple unless 'LIBCXX_ENABLE_STATIC_ABI_LIBRARY'
+# is on. This option is also disabled when the ABI library is not specified
+# or is specified to be "none".
+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 LIBCXX_ENABLE_SHARED)
+    set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE ON)
+endif()
+
+option(LIBCXX_ENABLE_ABI_LINKER_SCRIPT
+      "Use and install a linker script for the given ABI library"
+      ${ENABLE_LINKER_SCRIPT_DEFAULT_VALUE})
+
 # Build libc++abi with libunwind. We need this option to determine whether to
 # link with libunwind or libgcc_s while running the test cases.
 option(LIBCXXABI_USE_LLVM_UNWINDER "Build and use the LLVM unwinder." OFF)
@@ -84,16 +124,43 @@
 option(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS "Build libc++ with support for thread-unsafe C functions" ON)
 option(LIBCXX_ENABLE_MONOTONIC_CLOCK
   "Build libc++ with support for a monotonic clock.
-   This option may only be used when LIBCXX_ENABLE_THREADS=OFF." ON)
+   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)
 
 # Misc options ----------------------------------------------------------------
-option(LIBCXX_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
+# 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_GENERATE_COVERAGE "Enable generating code coverage." OFF)
 set(LIBCXX_COVERAGE_LIBRARY "" CACHE STRING
     "The Profile-rt library used to build with code coverage")
 
+# Don't allow a user to accidentally overwrite the system libc++ installation on Darwin.
+# If the user specifies -DCMAKE_INSTALL_PREFIX=/usr the install rules for libc++
+# will not be generated and a warning will be issued.
+option(LIBCXX_OVERRIDE_DARWIN_INSTALL "Enable overwriting darwins libc++ installation." OFF)
+mark_as_advanced(LIBCXX_OVERRIDE_DARWIN_INSTALL) # Don't show this option by default.
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT LIBCXX_OVERRIDE_DARWIN_INSTALL)
+  if ("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr")
+    message(WARNING "Disabling libc++ install rules because installation would "
+                    "overwrite the systems installation. Configure with "
+                    "-DLIBCXX_OVERRIDE_DARWIN_INSTALL=ON to suppress this behaviour.")
+    mark_as_advanced(CLEAR LIBCXX_OVERRIDE_DARWIN_INSTALL) # Show the override option.
+    set(LIBCXX_INSTALL_HEADERS OFF)
+    set(LIBCXX_INSTALL_LIBRARY OFF)
+  endif()
+endif()
+
+set(LIBCXX_CONFIGURE_IDE_DEFAULT OFF)
+if (XCODE OR MSVC_IDE)
+  set(LIBCXX_CONFIGURE_IDE_DEFAULT ON)
+endif()
+option(LIBCXX_CONFIGURE_IDE "Configure libcxx for use within an IDE"
+      ${LIBCXX_CONFIGURE_IDE_DEFAULT})
+
 #===============================================================================
 # Check option configurations
 #===============================================================================
@@ -130,6 +197,29 @@
   endif()
 endif()
 
+if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
+    if (APPLE)
+      message(FATAL_ERROR "LIBCXX_ENABLE_ABI_LINKER_SCRIPT cannot be used on APPLE targets")
+    endif()
+    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)
+    message(FATAL_ERROR "Conflicting options given.
+        LIBCXX_ENABLE_STATIC_ABI_LIBRARY cannot be specified with
+        LIBCXX_ENABLE_ABI_LINKER_SCRIPT")
+endif()
+
+if (LIBCXX_HAS_MUSL_LIBC AND NOT LIBCXX_INSTALL_SUPPORT_HEADERS)
+  message(FATAL_ERROR "LIBCXX_INSTALL_SUPPORT_HEADERS can not be turned off"
+                      "when building for Musl with LIBCXX_HAS_MUSL_LIBC.")
+endif()
+
 #===============================================================================
 # Configure System
 #===============================================================================
@@ -166,7 +256,7 @@
 # Setup Compiler Flags
 #===============================================================================
 
-include(HandleLibCXXABI) # Steup the ABI library flags
+include(HandleLibCXXABI) # Setup the ABI library flags
 
 # Include macros for adding and removing libc++ flags.
 include(HandleLibcxxFlags)
@@ -175,6 +265,11 @@
 remove_flags(-DNDEBUG -UNDEBUG -D_DEBUG
              -stdlib=libc++ -stdlib=libstdc++ -lc++abi -m32)
 
+# FIXME(EricWF): See the FIXME on LIBCXX_ENABLE_PEDANTIC.
+# Remove the -pedantic flag and -Wno-pedantic and -pedantic-errors
+# so they don't get transformed into -Wno and -errors respectivly.
+remove_flags(-Wno-pedantic -pedantic-errors -pedantic)
+
 # Required flags ==============================================================
 add_compile_flags_if_supported(-std=c++11)
 if (NOT MSVC AND NOT LIBCXX_SUPPORTS_STD_EQ_CXX11_FLAG)
@@ -239,15 +334,8 @@
 
 # Feature flags ===============================================================
 define_if(MSVC -D_CRT_SECURE_NO_WARNINGS)
-define_if_not(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE -D_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE)
-define_if_not(LIBCXX_ENABLE_STDIN -D_LIBCPP_HAS_NO_STDIN)
-define_if_not(LIBCXX_ENABLE_STDOUT -D_LIBCPP_HAS_NO_STDOUT)
-define_if_not(LIBCXX_ENABLE_THREADS -D_LIBCPP_HAS_NO_THREADS)
-define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK -D_LIBCPP_HAS_NO_MONOTONIC_CLOCK)
-define_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS -D_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS)
 
-
-# Sanitizer flags
+# Sanitizer flags =============================================================
 
 # Configure for sanitizers. If LIBCXX_BUILT_STANDALONE then we have to do
 # the flag translation ourselves. Othewise LLVM's CMakeList.txt will handle it.
@@ -282,12 +370,42 @@
     message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.")
   endif()
 endif()
+
+# Configuration file flags =====================================================
+if (NOT LIBCXX_ABI_VERSION EQUAL "1")
+  config_define(${LIBCXX_ABI_VERSION} _LIBCPP_ABI_VERSION)
+endif()
+config_define_if(LIBCXX_ABI_UNSTABLE _LIBCPP_ABI_UNSTABLE)
+
+config_define_if_not(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE)
+config_define_if_not(LIBCXX_ENABLE_STDIN _LIBCPP_HAS_NO_STDIN)
+config_define_if_not(LIBCXX_ENABLE_STDOUT _LIBCPP_HAS_NO_STDOUT)
+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_MUSL_LIBC _LIBCPP_HAS_MUSL_LIBC)
+
+if (LIBCXX_NEEDS_SITE_CONFIG)
+  configure_file(
+    include/__config_site.in
+    ${LIBCXX_BINARY_DIR}/__config_site
+    @ONLY)
+  # Provide the config definitions by included the generated __config_site
+  # file at compile time.
+  add_compile_flags("-include ${LIBCXX_BINARY_DIR}/__config_site")
+endif()
+
 #===============================================================================
 # Setup Source Code And Tests
 #===============================================================================
 include_directories(include)
 add_subdirectory(include)
 add_subdirectory(lib)
+
 if (LIBCXX_INCLUDE_TESTS)
   add_subdirectory(test)
 endif()
+if (LIBCXX_INCLUDE_DOCS)
+  add_subdirectory(docs)
+endif()
diff --git a/LICENSE.TXT b/LICENSE.TXT
index 53352e4..339e232 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -14,7 +14,7 @@
 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 ab7b5b6..0000000
--- 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/TODO.TXT b/TODO.TXT
index 513b863..bdb94de 100644
--- a/TODO.TXT
+++ b/TODO.TXT
@@ -1,5 +1,15 @@
 This is meant to be a general place to list things that should be done "someday"
 
+3.8 Release Goals
+=================
+* LFTS v1 (EricWF, MClow)
+* Filesystem TS (EricWF)
+* ASIO TS (MClow)
+* <regex> Improvements (MClow)
+* Setup ABI Versioning policy (EricWF)
+* Fix PR19302 - Fix UB in list and __tree.
+
+
 ABI Related Tasks
 =================
 * Explicitly manage and verify symbols exported from the dylib.
@@ -21,18 +31,18 @@
 
 Atomic Related Tasks
 ====================
-* Support <atomic> in C++03 (needed for internal use).
+* Enable mixing of clang and GCC atomics internally. Currently some
+  parts of libc++ use atomics only when clang provides them.
+  (see memory@5380 for an example)
 * Audit use of libatomic builtins in <atomic> with GCC.
 * future should use <atomic> for synchronization.
-* call_once should use <atomic> for synchronization.
-* Audit shared_ptr use of <atomic>
 
 Test Suite Tasks
 ================
-* Get test suite passing in C++03.
 * Move all libc++ specific tests from test/std into test/libcxx.
 * Improve how LIT handles compiler warnings.
 * Improve the quality and portability of the locale test data.
+* Convert failure tests to use Clang Verify.
 
 Misc Tasks
 ==========
@@ -42,8 +52,5 @@
 * Look at basic_string's move assignment operator, re LWG 2063 and POCMA
 * libc++ is missing try_emplace
 * Put a static_assert in std::allocator to deny const/volatile types (LWG 2447)
-* Investigate the effect of using __decltype instead of __typeof__ to provide
-  decltype in C++03. What code could be broken by this change?
-* Convert failure tests to use Clang Verify.
 * Document support (or lack of) for C++11 libraries in C++03.
 * Document supported compilers.
diff --git a/cmake/Modules/CheckLibcxxAtomic.cmake b/cmake/Modules/CheckLibcxxAtomic.cmake
new file mode 100644
index 0000000..ca490b3
--- /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)
+# If not, check if the library exists, and atomics work with it.
+if(NOT LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB)
+  check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_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 4224882..d9c652d 100644
--- a/cmake/Modules/HandleLibCXXABI.cmake
+++ b/cmake/Modules/HandleLibCXXABI.cmake
@@ -41,10 +41,13 @@
         file(COPY "${incpath}/${fpath}"
           DESTINATION "${CMAKE_BINARY_DIR}/include/${dstdir}"
           )
-        install(FILES "${CMAKE_BINARY_DIR}/include/${fpath}"
-          DESTINATION include/c++/v1/${dstdir}
-          PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
-          )
+        if (LIBCXX_INSTALL_HEADERS)
+          install(FILES "${CMAKE_BINARY_DIR}/include/${fpath}"
+            DESTINATION include/c++/v1/${dstdir}
+            COMPONENT libcxx
+            PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+            )
+        endif()
         list(APPEND abilib_headers "${CMAKE_BINARY_DIR}/include/${fpath}")
       endif()
     endforeach()
@@ -58,19 +61,6 @@
 
 endmacro()
 
-# Setup the default options if LIBCXX_CXX_ABI is not specified.
-if (NOT LIBCXX_CXX_ABI)
-  if (NOT DEFINED LIBCXX_BUILT_STANDALONE AND
-      IS_DIRECTORY "${CMAKE_SOURCE_DIR}/projects/libcxxabi")
-    set(LIBCXX_CXX_ABI_LIBNAME "libcxxabi")
-    set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${CMAKE_SOURCE_DIR}/projects/libcxxabi/include")
-    set(LIBCXX_CXX_ABI_INTREE 1)
-  else ()
-    set(LIBCXX_CXX_ABI_LIBNAME "none")
-  endif ()
-else ()
-  set(LIBCXX_CXX_ABI_LIBNAME "${LIBCXX_CXX_ABI}")
-endif ()
 
 # Configure based on the selected ABI library.
 if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++" OR
diff --git a/cmake/Modules/HandleLibcxxFlags.cmake b/cmake/Modules/HandleLibcxxFlags.cmake
index 223b7b7..b8ea134 100644
--- a/cmake/Modules/HandleLibcxxFlags.cmake
+++ b/cmake/Modules/HandleLibcxxFlags.cmake
@@ -35,6 +35,11 @@
   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})
@@ -49,6 +54,28 @@
   endif()
 endmacro()
 
+# Add a macro definition to the __config_site file if the specified condition
+# is 'true'. Note that '-D${def}' is not added. Instead it is expected that
+# the build include the '__config_site' header.
+macro(config_define_if condition def)
+  if (${condition})
+    set(${def} ON)
+    set(LIBCXX_NEEDS_SITE_CONFIG ON)
+  endif()
+endmacro()
+
+macro(config_define_if_not condition def)
+  if (NOT ${condition})
+    set(${def} ON)
+    set(LIBCXX_NEEDS_SITE_CONFIG ON)
+  endif()
+endmacro()
+
+macro(config_define value def)
+  set(${def} ${value})
+  set(LIBCXX_NEEDS_SITE_CONFIG ON)
+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 bf629a9..4f7bbaf 100644
--- a/cmake/Modules/HandleOutOfTreeLLVM.cmake
+++ b/cmake/Modules/HandleOutOfTreeLLVM.cmake
@@ -35,18 +35,22 @@
     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()
   endif()
 
   if (NOT EXISTS ${LLVM_MAIN_SRC_DIR})
-    message(FATAL_ERROR "Not found: ${LLVM_MAIN_SRC_DIR}")
+    set(LLVM_FOUND OFF)
+    message(WARNING "Not found: ${LLVM_MAIN_SRC_DIR}")
+    return()
   endif()
 
   if(NOT EXISTS ${LLVM_CMAKE_PATH})
-    message(FATAL_ERROR "Not found: ${LLVM_CMAKE_PATH}")
+    set(LLVM_FOUND OFF)
+    message(WARNING "Not found: ${LLVM_CMAKE_PATH}")
+    return()
   endif()
 
   list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
@@ -73,6 +77,12 @@
   if (NOT DEFINED LLVM_INCLUDE_TESTS)
     set(LLVM_INCLUDE_TESTS ${LLVM_FOUND})
   endif()
+  if (NOT DEFINED LLVM_INCLUDE_DOCS)
+    set(LLVM_INCLUDE_DOCS ${LLVM_FOUND})
+  endif()
+  if (NOT DEFINED LLVM_ENABLE_SPHINX)
+    set(LLVM_ENABLE_SPHINX OFF)
+  endif()
 
   # Required LIT Configuration ------------------------------------------------
   # Define the default arguments to use with 'lit', and an option for the user
@@ -91,6 +101,38 @@
     set(cmake_3_2_USES_TERMINAL USES_TERMINAL)
   endif()
 
+  # Required doc configuration
+  if (LLVM_ENABLE_SPHINX)
+    message(STATUS "Sphinx enabled.")
+    find_package(Sphinx REQUIRED)
+  else()
+    message(STATUS "Sphinx disabled.")
+  endif()
+
+  # FIXME - This is cribbed from HandleLLVMOptions.cmake.
+  if(WIN32)
+    set(LLVM_HAVE_LINK_VERSION_SCRIPT 0)
+    if(CYGWIN)
+      set(LLVM_ON_WIN32 0)
+      set(LLVM_ON_UNIX 1)
+    else(CYGWIN)
+      set(LLVM_ON_WIN32 1)
+      set(LLVM_ON_UNIX 0)
+    endif(CYGWIN)
+  else(WIN32)
+    if(UNIX)
+      set(LLVM_ON_WIN32 0)
+      set(LLVM_ON_UNIX 1)
+      if(APPLE)
+        set(LLVM_HAVE_LINK_VERSION_SCRIPT 0)
+      else(APPLE)
+        set(LLVM_HAVE_LINK_VERSION_SCRIPT 1)
+      endif(APPLE)
+    else(UNIX)
+      MESSAGE(SEND_ERROR "Unable to determine platform")
+    endif(UNIX)
+  endif(WIN32)
+
   # Add LLVM Functions --------------------------------------------------------
   include(AddLLVM OPTIONAL)
 endif()
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index ace7aca..3e6c359 100644
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -1,5 +1,6 @@
 include(CheckLibraryExists)
 include(CheckCXXCompilerFlag)
+include(CheckLibcxxAtomic)
 
 # Check compiler flags
 
@@ -13,8 +14,7 @@
 
 # Check libraries
 check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB)
-check_library_exists(c printf "" LIBCXX_HAS_C_LIB)
+check_library_exists(c fopen "" LIBCXX_HAS_C_LIB)
 check_library_exists(m ccos "" LIBCXX_HAS_M_LIB)
 check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB)
 check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB)
-
diff --git a/docs/BuildingLibcxx.rst b/docs/BuildingLibcxx.rst
new file mode 100644
index 0000000..0730703
--- /dev/null
+++ b/docs/BuildingLibcxx.rst
@@ -0,0 +1,338 @@
+
+===============
+Building libc++
+===============
+
+.. contents::
+  :local:
+
+.. _build instructions:
+
+Getting Started
+===============
+
+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.
+
+The basic steps needed to build libc++ are:
+
+#. Checkout LLVM:
+
+   * ``cd where-you-want-llvm-to-live``
+   * ``svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm``
+
+#. Checkout libc++:
+
+   * ``cd where-you-want-llvm-to-live``
+   * ``cd llvm/projects``
+   * ``svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx``
+
+#. Checkout libc++abi:
+
+   * ``cd where-you-want-llvm-to-live``
+   * ``cd llvm/projects``
+   * ``svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabi``
+
+#. Configure and build libc++ with libc++abi:
+
+   CMake is the only supported configuration system.
+
+   Clang is the preferred compiler when building and using libc++.
+
+   * ``cd where you want to build llvm``
+   * ``mkdir build``
+   * ``cd build``
+   * ``cmake -G <generator> [options] <path to llvm sources>``
+
+   For more information about configuring libc++ see :ref:`CMake Options`.
+
+   * ``make cxx`` --- will build libc++ and libc++abi.
+   * ``make check-libcxx check-libcxxabi`` --- will run the test suites.
+
+   Shared libraries for libc++ and libc++ abi should now be present in llvm/build/lib.
+   See :ref:`using an alternate libc++ installation <alternate libcxx>`
+
+#. **Optional**: Install libc++ and libc++abi
+
+   If your system already provides a libc++ installation it is important to be
+   careful not to replace it. Remember Use the CMake option ``CMAKE_INSTALL_PREFIX`` to
+   select a safe place to install libc++.
+
+   * ``make install-libcxx install-libcxxabi`` --- Will install the libraries and the headers
+
+   .. warning::
+     * Replacing your systems libc++ installation could render the system non-functional.
+     * Mac OS X will not boot without a valid copy of ``libc++.1.dylib`` in ``/usr/lib``.
+
+
+The instructions are for building libc++ on
+FreeBSD, Linux, or Mac using `libc++abi`_ as the C++ ABI library.
+On Linux, it is also possible to use :ref:`libsupc++ <libsupcxx>` or libcxxrt.
+
+It is sometimes beneficial to build outside of the LLVM tree. An out-of-tree
+build would look like this:
+
+.. code-block:: bash
+
+  $ cd where-you-want-libcxx-to-live
+  $ # Check out llvm, libc++ and libc++abi.
+  $ ``svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm``
+  $ ``svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx``
+  $ ``svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabi``
+  $ cd where-you-want-to-build
+  $ mkdir build && cd build
+  $ export CC=clang CXX=clang++
+  $ cmake -DLLVM_PATH=path/to/llvm \
+          -DLIBCXX_CXX_ABI=libcxxabi \
+          -DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/libcxxabi/include \
+          path/to/libcxx
+  $ make
+  $ make check-libcxx # optional
+
+
+.. _`libc++abi`: http://libcxxabi.llvm.org/
+
+
+.. _CMake Options:
+
+CMake Options
+=============
+
+Here are some of the CMake variables that are used often, along with a
+brief explanation and LLVM-specific notes. For full documentation, check the
+CMake docs or execute ``cmake --help-variable VARIABLE_NAME``.
+
+**CMAKE_BUILD_TYPE**:STRING
+  Sets the build type for ``make`` based generators. Possible values are
+  Release, Debug, RelWithDebInfo and MinSizeRel. On systems like Visual Studio
+  the user sets the build type with the IDE settings.
+
+**CMAKE_INSTALL_PREFIX**:PATH
+  Path where LLVM will be installed if "make install" is invoked or the
+  "INSTALL" target is built.
+
+**CMAKE_CXX_COMPILER**:STRING
+  The C++ compiler to use when building and testing libc++.
+
+
+.. _libcxx-specific options:
+
+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``
+
+  Build libc++ with assertions enabled.
+
+.. option:: LIBCXX_BUILD_32_BITS:BOOL
+
+  **Default**: ``OFF``
+
+  Build libc++ as a 32 bit library. Also see :option:`LLVM_BUILD_32_BITS`.
+
+.. option:: LIBCXX_ENABLE_SHARED:BOOL
+
+  **Default**: ``ON``
+
+  Build libc++ as a shared library. If ``OFF`` is specified then libc++ is
+  built as a static library.
+
+.. option:: LIBCXX_LIBDIR_SUFFIX:STRING
+
+  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++.
+
+
+.. _ABI Library Specific Options:
+
+ABI Library Specific Options
+----------------------------
+
+.. option:: LIBCXX_CXX_ABI:STRING
+
+  **Values**: ``none``, ``libcxxabi``, ``libcxxrt``, ``libstdc++``, ``libsupc++``.
+
+  Select the ABI library to build libc++ against.
+
+.. option:: LIBCXX_CXX_ABI_INCLUDE_PATHS:PATHS
+
+  Provide additional search paths for the ABI library headers.
+
+.. option:: LIBCXX_CXX_ABI_LIBRARY_PATH:PATH
+
+  Provide the path to the ABI library that libc++ should link against.
+
+.. option:: LIBCXX_ENABLE_STATIC_ABI_LIBRARY:BOOL
+
+  **Default**: ``OFF``
+
+  If this option is enabled, libc++ will try and link the selected ABI library
+  statically.
+
+.. option:: LIBCXX_ENABLE_ABI_LINKER_SCRIPT:BOOL
+
+  **Default**: ``ON`` by default on UNIX platforms other than Apple unless
+  'LIBCXX_ENABLE_STATIC_ABI_LIBRARY' is ON. Otherwise the default value is ``OFF``.
+
+  This option generate and installs a linker script as ``libc++.so`` which
+  links the correct ABI library.
+
+.. option:: LIBCXXABI_USE_LLVM_UNWINDER:BOOL
+
+  **Default**: ``OFF``
+
+  Build and use the LLVM unwinder. Note: This option can only be used when
+  libc++abi is the C++ ABI library used.
+
+
+libc++ Feature options
+----------------------
+
+.. option:: LIBCXX_ENABLE_EXCEPTIONS:BOOL
+
+  **Default**: ``ON``
+
+  Build libc++ with exception support.
+
+.. option:: LIBCXX_ENABLE_RTTI:BOOL
+
+  **Default**: ``ON``
+
+  Build libc++ with run time type information.
+
+
+libc++ Feature options
+----------------------
+
+The following options allow building libc++ for a different ABI version.
+
+.. option:: LIBCXX_ABI_VERSION:STRING
+
+  **Default**: ``1``
+
+  Defines the target ABI version of libc++.
+
+.. option:: LIBCXX_ABI_UNSTABLE:BOOL
+
+  **Default**: ``OFF``
+
+  Build the "unstable" ABI version of libc++. Includes all ABI changing features
+  on top of the current stable version.
+
+.. _LLVM-specific variables:
+
+LLVM-specific options
+---------------------
+
+.. option:: LLVM_LIBDIR_SUFFIX:STRING
+
+  Extra suffix to append to the directory where libraries are to be
+  installed. On a 64-bit architecture, one could use ``-DLLVM_LIBDIR_SUFFIX=64``
+  to install libraries to ``/usr/lib64``.
+
+.. option:: LLVM_BUILD_32_BITS:BOOL
+
+  Build 32-bits executables and libraries on 64-bits systems. This option is
+  available only on some 64-bits unix systems. Defaults to OFF.
+
+.. option:: LLVM_LIT_ARGS:STRING
+
+  Arguments given to lit.  ``make check`` and ``make clang-test`` are affected.
+  By default, ``'-sv --no-progress-bar'`` on Visual C++ and Xcode, ``'-sv'`` on
+  others.
+
+
+Using Alternate ABI libraries
+=============================
+
+
+.. _libsupcxx:
+
+Using libsupc++ on Linux
+------------------------
+
+You will need libstdc++ in order to provide libsupc++.
+
+Figure out where the libsupc++ headers are on your system. On Ubuntu this
+is ``/usr/include/c++/<version>`` and ``/usr/include/c++/<version>/<target-triple>``
+
+You can also figure this out by running
+
+.. code-block:: bash
+
+  $ 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 &lt;...&gt; 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.
+
+Note that the first two entries happen to be what we are looking for. This
+may not be correct on other platforms.
+
+We can now run CMake:
+
+.. code-block:: bash
+
+  $ 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>
+
+
+You can also substitute ``-DLIBCXX_CXX_ABI=libsupc++``
+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.
+
+.. code-block:: bash
+
+  $ make cxx
+  $ make install
+
+You can now run clang with -stdlib=libc++.
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
new file mode 100644
index 0000000..f63ee00
--- /dev/null
+++ b/docs/CMakeLists.txt
@@ -0,0 +1,9 @@
+
+if (LLVM_ENABLE_SPHINX)
+  if (SPHINX_FOUND)
+    include(AddSphinxTarget)
+    if (${SPHINX_OUTPUT_HTML})
+      add_sphinx_target(html libcxx)
+    endif()
+  endif()
+endif()
\ No newline at end of file
diff --git a/docs/DesignDocs/ABIVersioning.rst b/docs/DesignDocs/ABIVersioning.rst
new file mode 100644
index 0000000..5960dd1
--- /dev/null
+++ b/docs/DesignDocs/ABIVersioning.rst
@@ -0,0 +1,17 @@
+
+====================
+Libc++ ABI stability
+====================
+
+Libc++ aims to preserve stable ABI to avoid subtle bugs when code built to the old ABI
+is linked with the code build to the new ABI. At the same time, libc++ allows ABI-breaking
+improvements and bugfixes for the scenarios when ABI change is not a issue.
+
+To support both cases, libc++ allows specifying the ABI version at the
+build time.  The version is defined with a cmake option
+LIBCXX_ABI_VERSION. Another option LIBCXX_ABI_UNSTABLE can be used to
+include all present ABI breaking features. These options translate
+into C++ macro definitions _LIBCPP_ABI_VERSION, _LIBCPP_ABI_UNSTABLE.
+
+Any ABI-changing feature is placed under it's own macro, _LIBCPP_ABI_XXX, which is enabled
+based on the value of _LIBCPP_ABI_VERSION. _LIBCPP_ABI_UNSTABLE, if set, enables all features at once.
diff --git a/docs/DesignDocs/CapturingConfigInfo.rst b/docs/DesignDocs/CapturingConfigInfo.rst
new file mode 100644
index 0000000..73378a2
--- /dev/null
+++ b/docs/DesignDocs/CapturingConfigInfo.rst
@@ -0,0 +1,88 @@
+=======================================================
+Capturing configuration information during installation
+=======================================================
+
+.. contents::
+   :local:
+
+The Problem
+===========
+
+Currently the libc++ supports building the library with a number of different
+configuration options.  Unfortunately all of that configuration information is
+lost when libc++ is installed. In order to support "persistent"
+configurations libc++ needs a mechanism to capture the configuration options
+in the INSTALLED headers.
+
+
+Design Goals
+============
+
+* The solution should not INSTALL any additional headers. We don't want an extra
+  #include slowing everybody down.
+
+* The solution should not unduly affect libc++ developers. The problem is limited
+  to installed versions of libc++ and the solution should be as well.
+
+* The solution should not modify any existing headers EXCEPT during installation.
+  It makes developers lives harder if they have to regenerate the libc++ headers
+  every time they are modified.
+
+* The solution should not make any of the libc++ headers dependant on
+  files generated by the build system. The headers should be able to compile
+  out of the box without any modification.
+
+* The solution should not have ANY effect on users who don't need special
+  configuration options. The vast majority of users will never need this so it
+  shouldn't cost them.
+
+
+The Solution
+============
+
+When you first configure libc++ using CMake we check to see if we need to
+capture any options. If we haven't been given any "persistent" options then
+we do NOTHING.
+
+Otherwise we create a custom installation rule that modifies the installed __config
+header. The rule first generates a dummy "__config_site" header containing the required
+#defines. The contents of the dummy header are then prependend to the installed
+__config header. By manually prepending the files we avoid the cost of an
+extra #include and we allow the __config header to be ignorant of the extra
+configuration all together. An example "__config" header generated when
+-DLIBCXX_ENABLE_THREADS=OFF is given to CMake would look something like:
+
+.. code-block:: 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.
+  //
+  //===----------------------------------------------------------------------===//
+
+  #ifndef _LIBCPP_CONFIG_SITE
+  #define _LIBCPP_CONFIG_SITE
+
+  /* #undef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE */
+  /* #undef _LIBCPP_HAS_NO_STDIN */
+  /* #undef _LIBCPP_HAS_NO_STDOUT */
+  #define _LIBCPP_HAS_NO_THREADS
+  /* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */
+  /* #undef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS */
+
+  #endif
+  // -*- C++ -*-
+  //===--------------------------- __config ---------------------------------===//
+  //
+  //                     The LLVM Compiler Infrastructure
+  //
+  // This file is dual licensed under the MIT and the University of Illinois Open
+  // Source Licenses. See LICENSE.TXT for details.
+  //
+  //===----------------------------------------------------------------------===//
+
+  #ifndef _LIBCPP_CONFIG
+  #define _LIBCPP_CONFIG
diff --git a/docs/Makefile.sphinx b/docs/Makefile.sphinx
new file mode 100644
index 0000000..2ca1e4d
--- /dev/null
+++ b/docs/Makefile.sphinx
@@ -0,0 +1,37 @@
+# Makefile for Sphinx documentation
+#
+# FIXME: This hack is only in place to allow the libcxx.llvm.org/docs builder
+# to work with libcxx. This should be removed when that builder supports
+# out-of-tree builds.
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext default
+
+default: html
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@# FIXME: Remove this `cp` once HTML->Sphinx transition is completed.
+	@# Kind of a hack, but HTML-formatted docs are on the way out anyway.
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
diff --git a/docs/README.txt b/docs/README.txt
new file mode 100644
index 0000000..06d94f5
--- /dev/null
+++ b/docs/README.txt
@@ -0,0 +1,13 @@
+libc++ Documentation
+====================
+
+The libc++ documentation is written using the Sphinx documentation generator. It is
+currently tested with Sphinx 1.1.3.
+
+To build the documents into html configure libc++ with the following cmake options:
+
+  * -DLLVM_ENABLE_SPHINX=ON
+  * -DLIBCXX_INCLUDE_DOCS=ON
+
+After configuring libc++ with these options the make rule `docs-libcxx-html`
+should be available.
diff --git a/docs/TestingLibcxx.rst b/docs/TestingLibcxx.rst
new file mode 100644
index 0000000..9226ae1
--- /dev/null
+++ b/docs/TestingLibcxx.rst
@@ -0,0 +1,200 @@
+==============
+Testing libc++
+==============
+
+.. contents::
+  :local:
+
+Getting Started
+===============
+
+libc++ uses LIT to configure and run its tests. The primary way to run the
+libc++ tests is by using make check-libcxx. 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++.
+
+Please see the `Lit Command Guide`_ for more information about LIT.
+
+.. _LIT Command Guide: http://llvm.org/docs/CommandGuide/lit.html
+
+Setting up the Environment
+--------------------------
+
+After building libc++ you must setup your environment to test libc++ using
+LIT.
+
+#. Create a shortcut to the actual lit executable so that you can invoke it
+   easily from the command line.
+
+   .. code-block:: bash
+
+     $ alias lit='python path/to/llvm/utils/lit/lit.py'
+
+#. Tell LIT where to find your build configuration.
+
+   .. code-block:: bash
+
+     $ export LIBCXX_SITE_CONFIG=path/to/build-libcxx/test/lit.site.cfg
+
+Example Usage
+-------------
+
+Once you have your environment set up and you have built libc++ you can run
+parts of the libc++ test suite by simply running `lit` on a specified test or
+directory. For example:
+
+.. code-block:: bash
+
+  $ cd path/to/src/libcxx
+  $ lit -sv test/std/re # Run all of the std::regex tests
+  $ lit -sv test/std/depr/depr.c.headers/stdlib_h.pass.cpp # Run a single test
+  $ lit -sv test/std/atomics test/std/threads # Test std::thread and std::atomic
+
+Sometimes you'll want to change the way LIT is running the tests. Custom options
+can be specified using the `--param=<name>=<val>` flag. The most common option
+you'll want to change is the standard dialect (ie -std=c++XX). By default the
+test suite will select the newest C++ dialect supported by the compiler and use
+that. However if you want to manually specify the option like so:
+
+.. code-block:: bash
+
+  $ lit -sv test/std/containers # Run the tests with the newest -std
+  $ lit -sv --param=std=c++03 test/std/containers # Run the tests in C++03
+
+Occasionally you'll want to add extra compile or link flags when testing.
+You can do this as follows:
+
+.. code-block:: bash
+
+  $ lit -sv --param=compile_flags='-Wcustom-warning'
+  $ lit -sv --param=link_flags='-L/custom/library/path'
+
+Some other common examples include:
+
+.. code-block:: bash
+
+  # Specify a custom compiler.
+  $ lit -sv --param=cxx_under_test=/opt/bin/g++ test/std
+
+  # Enable warnings in the test suite
+  $ lit -sv --param=enable_warnings=true test/std
+
+  # Use UBSAN when running the tests.
+  $ lit -sv --param=use_sanitizer=Undefined
+
+
+LIT Options
+===========
+
+:program:`lit` [*options*...] [*filenames*...]
+
+Command Line Options
+--------------------
+
+To use these options you pass them on the LIT command line as --param NAME or
+--param NAME=VALUE. Some options have default values specified during CMake's
+configuration. Passing the option on the command line will override the default.
+
+.. program:: lit
+
+.. option:: --cxx_under_test=<path/to/compiler>
+
+  Specify the compiler used to build the tests.
+
+.. option:: std=<standard version>
+
+  **Values**: c++98, c++03, c++11, c++14, c++1z
+
+  Change the standard version used when building the tests.
+
+.. 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>
+
+  Specify the libc++ headers that are tested. By default the headers in the
+  source tree are used.
+
+.. option:: --cxx_library_root=<path/to/lib/>
+
+  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:: --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>
+
+  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>
+
+  **Default**: False
+
+  Disable all default compile and link flags from being added. When this
+  option is used only flags specified using the compile_flags and link_flags
+  will be used.
+
+.. 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>"
+
+  Specify additional link flags as a space delimited string.
+
+.. option:: --debug_level=<level>
+
+  **Values**: 0, 1
+
+  Enable the use of debug mode. Level 0 enables assertions and level 1 enables
+  assertions and debugging of iterator misuse.
+
+.. option:: use_sanitizer=<sanitizer name>
+
+  **Values**: Memory, MemoryWithOrigins, Address, Undefined
+
+  Run the tests using the given sanitizer. If LLVM_USE_SANITIZER was given when
+  building libc++ then that sanitizer will be used by default.
+
+.. option:: color_diagnostics
+
+  Enable the use of colorized compile diagnostics. If the color_diagnostics
+  option is specified or the environment variable LIBCXX_COLOR_DIAGNOSTICS is
+  present then color diagnostics will be enabled.
+
+
+Environment Variables
+---------------------
+
+.. envvar:: LIBCXX_SITE_CONFIG=<path/to/lit.site.cfg>
+
+  Specify the site configuration to use when running the tests.
+  Also see :option:`libcxx_site_config`.
+
+.. envvar:: LIBCXX_COLOR_DIAGNOSTICS
+
+  If ``LIBCXX_COLOR_DIAGNOSTICS`` is defined then the test suite will attempt
+  to use color diagnostic outputs from the compiler.
+  Also see :option:`color_diagnostics`.
diff --git a/docs/UsingLibcxx.rst b/docs/UsingLibcxx.rst
new file mode 100644
index 0000000..514ed14
--- /dev/null
+++ b/docs/UsingLibcxx.rst
@@ -0,0 +1,125 @@
+============
+Using libc++
+============
+
+.. contents::
+  :local:
+
+Getting Started
+===============
+
+If you already have libc++ installed you can use it with clang.
+
+.. code-block:: bash
+
+    $ clang++ -stdlib=libc++ test.cpp
+    $ clang++ -std=c++11 -stdlib=libc++ test.cpp
+
+On OS X and FreeBSD libc++ is the default standard library
+and the ``-stdlib=libc++`` is not required.
+
+.. _alternate libcxx:
+
+If you want to select an alternate installation of libc++ you
+can use the following options.
+
+.. code-block:: bash
+
+  $ clang++ -std=c++11 -stdlib=libc++ -nostdinc++ \
+            -I<libcxx-install-prefix>/include/c++/v1 \
+            -L<libcxx-install-prefix>/lib \
+            -Wl,-rpath,<libcxx-install-prefix>/lib \
+            test.cpp
+
+The option ``-Wl,-rpath,<libcxx-install-prefix>/lib`` adds a runtime library
+search path. Meaning that the systems dynamic linker will look for libc++ in
+``<libcxx-install-prefix>/lib`` whenever the program is run. Alternatively the
+environment variable ``LD_LIBRARY_PATH`` (``DYLD_LIBRARY_PATH`` on OS X) can
+be used to change the dynamic linkers search paths after a program is compiled.
+
+An example of using ``LD_LIBRARY_PATH``:
+
+.. code-block:: bash
+
+  $ clang++ -stdlib=libc++ -nostdinc++ \
+            -I<libcxx-install-prefix>/include/c++/v1
+            -L<libcxx-install-prefix>/lib \
+            test.cpp -o
+  $ ./a.out # Searches for libc++ in the systems library paths.
+  $ 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
+=====================
+
+On Linux libc++ can typically be used with only '-stdlib=libc++'. However
+some libc++ installations require the user manually link libc++abi themselves.
+If you are running into linker errors when using libc++ try adding '-lc++abi'
+to the link line.  For example:
+
+.. code-block:: bash
+
+  $ clang++ -stdlib=libc++ test.cpp -lc++ -lc++abi -lm -lc -lgcc_s -lgcc
+
+Alternately, you could just add libc++abi to your libraries list, which in
+most situations will give the same result:
+
+.. code-block:: bash
+
+  $ clang++ -stdlib=libc++ test.cpp -lc++abi
+
+
+Using libc++ with GCC
+---------------------
+
+GCC does not provide a way to switch from libstdc++ to libc++. You must manually
+configure the compile and link commands.
+
+In particular you must tell GCC to remove the libstdc++ include directories
+using ``-nostdinc++`` and to not link libstdc++.so using ``-nodefaultlibs``.
+
+Note that ``-nodefaultlibs`` removes all of the standard system libraries and
+not just libstdc++ so they must be manually linked. For example:
+
+.. code-block:: bash
+
+  $ 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
new file mode 100644
index 0000000..e385406
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,251 @@
+# -*- coding: utf-8 -*-
+#
+# libc++ documentation build configuration file.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'libc++'
+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.9'
+# The full version, including alpha/beta/rc tags.
+release = '3.9'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%Y-%m-%d'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+show_authors = True
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'friendly'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'haiku'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'libcxxdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('contents', 'libcxx.tex', u'libcxx Documentation',
+   u'LLVM project', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('contents', 'libc++', u'libc++ Documentation',
+     [u'LLVM project'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+  ('contents', 'libc++', u'libc++ Documentation',
+   u'LLVM project', 'libc++', 'One line description of project.',
+   'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+
+# FIXME: Define intersphinx configration.
+intersphinx_mapping = {}
+
+
+# -- Options for extensions ----------------------------------------------------
+
+# Enable this if you want TODOs to show up in the generated documentation.
+todo_include_todos = True
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..b0c8b81
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,185 @@
+.. _index:
+
+=============================
+"libc++" C++ Standard Library
+=============================
+
+Overview
+========
+
+libc++ is a new implementation of the C++ standard library, targeting C++11.
+
+* Features and Goals
+
+  * Correctness as defined by the C++11 standard.
+  * Fast execution.
+  * Minimal memory use.
+  * Fast compile times.
+  * ABI compatibility with gcc's libstdc++ for some low-level features
+    such as exception objects, rtti and memory allocation.
+  * Extensive unit tests.
+
+* Design and Implementation:
+
+  * Extensive unit tests
+  * Internal linker model can be dumped/read to textual format
+  * Additional linking features can be plugged in as "passes"
+  * OS specific and CPU specific code factored out
+
+
+Getting Started with libc++
+---------------------------
+
+.. toctree::
+   :maxdepth: 2
+
+   UsingLibcxx
+   BuildingLibcxx
+   TestingLibcxx
+
+
+Current Status
+--------------
+
+After its initial introduction, many people have asked "why start a new
+library instead of contributing to an existing library?" (like Apache's
+libstdcxx, GNU's libstdc++, STLport, etc).  There are many contributing
+reasons, but some of the major ones are:
+
+* From years of experience (including having implemented the standard
+  library before), we've learned many things about implementing
+  the standard containers which require ABI breakage and fundamental changes
+  to how they are implemented.  For example, it is generally accepted that
+  building std::string using the "short string optimization" instead of
+  using Copy On Write (COW) is a superior approach for multicore
+  machines (particularly in C++11, which has rvalue references).  Breaking
+  ABI compatibility with old versions of the library was
+  determined to be critical to achieving the performance goals of
+  libc++.
+
+* Mainline libstdc++ has switched to GPL3, a license which the developers
+  of libc++ cannot use.  libstdc++ 4.2 (the last GPL2 version) could be
+  independently extended to support C++11, but this would be a fork of the
+  codebase (which is often seen as worse for a project than starting a new
+  independent one).  Another problem with libstdc++ is that it is tightly
+  integrated with G++ development, tending to be tied fairly closely to the
+  matching version of G++.
+
+* STLport and the Apache libstdcxx library are two other popular
+  candidates, but both lack C++11 support.  Our experience (and the
+  experience of libstdc++ developers) is that adding support for C++11 (in
+  particular rvalue references and move-only types) requires changes to
+  almost every class and function, essentially amounting to a rewrite.
+  Faced with a rewrite, we decided to start from scratch and evaluate every
+  design decision from first principles based on experience.
+  Further, both projects are apparently abandoned: STLport 5.2.1 was
+  released in Oct'08, and STDCXX 4.2.1 in May'08.
+
+Platform and Compiler Support
+-----------------------------
+
+libc++ is known to work on the following platforms, using gcc-4.2 and
+clang  (lack of C++11 language support disables some functionality).
+Note that functionality provided by ``<atomic>`` is only functional with clang
+and GCC.
+
+============ ==================== ============ ========================
+OS           Arch                 Compilers    ABI Library
+============ ==================== ============ ========================
+Mac OS X     i386, x86_64         Clang, GCC   libc++abi
+FreeBSD 10+  i386, x86_64, ARM    Clang, GCC   libcxxrt, libc++abi
+Linux        i386, x86_64         Clang, GCC   libc++abi
+============ ==================== ============ ========================
+
+The following minimum compiler versions are strongly recommended.
+
+* Clang 3.5 and above
+* GCC 4.7 and above.
+
+Anything older *may* work.
+
+C++ Dialect Support
+---------------------
+
+* C++11 - Complete
+* `C++14 - Complete <http://libcxx.llvm.org/cxx1y_status.html>`__
+* `C++1z - In Progress <http://libcxx.llvm.org/cxx1z_status.html>`__
+* `Post C++14 Technical Specifications - In Progress <http://libcxx.llvm.org/ts1z_status.html>`__
+
+Notes and Known Issues
+----------------------
+
+This list contains known issues with libc++
+
+* Building libc++ with ``-fno-rtti`` is not supported. However
+  linking against it with ``-fno-rtti`` is supported.
+* On OS X v10.8 and older the CMake option ``-DLIBCXX_LIBCPPABI_VERSION=""``
+  must be used during configuration.
+
+
+A full list of currently open libc++ bugs can be `found here`__.
+
+.. __:  https://llvm.org/bugs/buglist.cgi?component=All%20Bugs&product=libc%2B%2B&query_format=advanced&resolution=---&order=changeddate%20DESC%2Cassigned_to%20DESC%2Cbug_status%2Cpriority%2Cbug_id&list_id=74184
+
+Design Documents
+----------------
+
+.. toctree::
+   :maxdepth: 1
+
+   DesignDocs/CapturingConfigInfo
+   DesignDocs/ABIVersioning
+
+
+* `<atomic> design <http://libcxx.llvm.org/atomic_design.html>`_
+* `<type_traits> design <http://libcxx.llvm.org/type_traits_design.html>`_
+* `Status of debug mode <http://libcxx.llvm.org/debug_mode.html>`_
+* `Notes by Marshall Clow`__
+
+.. __: https://cplusplusmusings.wordpress.com/2012/07/05/clang-and-standard-libraries-on-mac-os-x/
+
+Build Bots and Test Coverage
+----------------------------
+
+* `LLVM Buildbot Builders <http://lab.llvm.org:8011/console>`_
+* `Apple Jenkins Builders <http://lab.llvm.org:8080/green/view/Libcxx/>`_
+* `EricWF's Nightly Builders <http://ds2.efcs.ca:8080/console>`_
+* `Code Coverage Results <http://efcs.ca/libcxx-coverage>`_
+
+Getting Involved
+================
+
+First please review our `Developer's Policy <http://llvm.org/docs/DeveloperPolicy.html>`__
+and `Getting started with LLVM <http://llvm.org/docs/GettingStarted.html>`__.
+
+**Bug Reports**
+
+If you think you've found a bug in libc++, please report it using
+the `LLVM Bugzilla`_. If you're not sure, you
+can post a message to the `cfe-dev mailing list`_ or on IRC.
+Please include "libc++" in your subject.
+
+**Patches**
+
+If you want to contribute a patch to libc++, the best place for that is
+`Phabricator <http://llvm.org/docs/Phabricator.html>`_. Please include [libcxx] in the subject and
+add `cfe-commits` as a subscriber. Also make sure you are subscribed to the
+`cfe-commits mailing list <http://lists.llvm.org/mailman/listinfo/cfe-commits>`_.
+
+**Discussion and Questions**
+
+Send discussions and questions to the
+`cfe-dev mailing list <http://lists.llvm.org/mailman/listinfo/cfe-dev>`_.
+Please include [libcxx] in the subject.
+
+
+
+Quick Links
+===========
+* `LLVM Homepage <http://llvm.org/>`_
+* `libc++abi Homepage <http://libcxxabi.llvm.org/>`_
+* `LLVM Bugzilla <http://llvm.org/bugs/>`_
+* `cfe-commits Mailing List`_
+* `cfe-dev Mailing List`_
+* `Browse libc++ -- SVN <http://llvm.org/svn/llvm-project/libcxx/trunk/>`_
+* `Browse libc++ -- ViewVC <http://llvm.org/viewvc/llvm-project/libcxx/trunk/>`_
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 95206bf..d3dcc52 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -1,10 +1,12 @@
 if (NOT LIBCXX_INSTALL_SUPPORT_HEADERS)
   set(LIBCXX_SUPPORT_HEADER_PATTERN PATTERN "support" EXCLUDE)
 endif()
+
 set(LIBCXX_HEADER_PATTERN
   PATTERN "*"
   PATTERN "CMakeLists.txt" EXCLUDE
   PATTERN ".svn" EXCLUDE
+  PATTERN "__config_site.in" EXCLUDE
   ${LIBCXX_SUPPORT_HEADER_PATTERN}
   )
 
@@ -17,8 +19,44 @@
 if (LIBCXX_INSTALL_HEADERS)
   install(DIRECTORY .
     DESTINATION include/c++/v1
+    COMPONENT libcxx-headers
     FILES_MATCHING
     ${LIBCXX_HEADER_PATTERN}
     PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
   )
+
+  if (LIBCXX_NEEDS_SITE_CONFIG)
+    set(UNIX_CAT cat)
+    if (WIN32)
+      set(UNIX_CAT type)
+    endif()
+    # Generate and install a custom __config header. The new header is created
+    # by  prepending __config_site to the current __config header.
+    add_custom_command(OUTPUT ${LIBCXX_BINARY_DIR}/__generated_config
+      COMMAND ${CMAKE_COMMAND} -E copy ${LIBCXX_BINARY_DIR}/__config_site ${LIBCXX_BINARY_DIR}/__generated_config
+      COMMAND ${UNIX_CAT} ${LIBCXX_SOURCE_DIR}/include/__config >> ${LIBCXX_BINARY_DIR}/__generated_config
+      DEPENDS ${LIBCXX_SOURCE_DIR}/include/__config
+              ${LIBCXX_BINARY_DIR}/__config_site
+    )
+    # Add a target that executes the generation commands.
+    add_custom_target(generate_config_header ALL
+      DEPENDS ${LIBCXX_BINARY_DIR}/__generated_config)
+    # 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-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
+                      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 0000000..f315ca2
--- /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 0000000..cbc8ad2
--- /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 e001215..f64cce3 100644
--- a/include/__config
+++ b/include/__config
@@ -11,19 +11,39 @@
 #ifndef _LIBCPP_CONFIG
 #define _LIBCPP_CONFIG
 
-#if !defined(_MSC_VER) || defined(__clang__)
+#if defined(_MSC_VER) && !defined(__clang__)
+#define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
+#endif
+
+#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
 #pragma GCC system_header
 #endif
 
+#ifdef __cplusplus
+
 #ifdef __GNUC__
 #define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__)
 #else
 #define _GNUC_VER 0
 #endif
 
-#define _LIBCPP_VERSION 3800
+#define _LIBCPP_VERSION 3900
 
+#ifndef _LIBCPP_ABI_VERSION
 #define _LIBCPP_ABI_VERSION 1
+#endif
+
+#if defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2
+// Change short string represention so that string data starts at offset 0,
+// improving its alignment in some cases.
+#define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
+// Fix deque iterator type in order to support incomplete types.
+#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
+#define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB
+#define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
+#endif
 
 #define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y
 #define _LIBCPP_CONCAT(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y)
@@ -37,6 +57,9 @@
 #ifndef __has_builtin
 #define __has_builtin(__x) 0
 #endif
+#ifndef __has_extension
+#define __has_extension(__x) 0
+#endif
 #ifndef __has_feature
 #define __has_feature(__x) 0
 #endif
@@ -61,6 +84,16 @@
 #endif  // __BIG_ENDIAN__
 #endif  // __BIG_ENDIAN__
 
+#ifdef __BYTE_ORDER__
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define _LIBCPP_LITTLE_ENDIAN 1
+#define _LIBCPP_BIG_ENDIAN 0
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define _LIBCPP_LITTLE_ENDIAN 0
+#define _LIBCPP_BIG_ENDIAN 1
+#endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#endif // __BYTE_ORDER__
+
 #ifdef __FreeBSD__
 # include <sys/endian.h>
 #  if _BYTE_ORDER == _LITTLE_ENDIAN
@@ -147,6 +180,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
@@ -205,6 +244,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
@@ -227,9 +272,12 @@
 
 #if defined(__clang__)
 
-#if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) &&        \
-    !defined(__arm__)
-#define _LIBCPP_ALTERNATE_STRING_LAYOUT
+// _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for
+// _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT left here for backward compatibility.
+#if (defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) &&       \
+     !defined(__arm__)) ||                                                     \
+    defined(_LIBCPP_ALTERNATE_STRING_LAYOUT)
+#define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
 #endif
 
 #if __has_feature(cxx_alignas)
@@ -249,7 +297,7 @@
 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
 
@@ -271,7 +319,9 @@
 #  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
 
 #if !(__has_feature(cxx_defaulted_functions))
 #define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
@@ -354,24 +404,23 @@
 #elif defined(__ANDROID__)
 #define _LIBCPP_HAS_QUICK_EXIT
 #elif defined(__linux__)
-#include <features.h>
+#if !defined(_LIBCPP_HAS_MUSL_LIBC)
+# include <features.h>
 #if __GLIBC_PREREQ(2, 15)
 #define _LIBCPP_HAS_QUICK_EXIT
 #endif
 #if __GLIBC_PREREQ(2, 17)
 #define _LIBCPP_HAS_C11_FEATURES
 #endif
+#else // defined(_LIBCPP_HAS_MUSL_LIBC)
+#define _LIBCPP_HAS_QUICK_EXIT
+#define _LIBCPP_HAS_C11_FEATURES
 #endif
+#endif // __linux__
 #endif
 
-#if (__has_feature(cxx_noexcept))
-#  define _NOEXCEPT noexcept
-#  define _NOEXCEPT_(x) noexcept(x)
-#  define _NOEXCEPT_OR_FALSE(x) noexcept(x)
-#else
-#  define _NOEXCEPT throw()
-#  define _NOEXCEPT_(x)
-#  define _NOEXCEPT_OR_FALSE(x) false
+#if !(__has_feature(cxx_noexcept))
+#define _LIBCPP_HAS_NO_NOEXCEPT
 #endif
 
 #if __has_feature(underlying_type)
@@ -396,6 +445,11 @@
 #define _LIBCPP_HAS_NO_ASAN
 #endif
 
+// Allow for build-time disabling of unsigned integer sanitization
+#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__)
 
 #define _ALIGNAS(x) __attribute__((__aligned__(x)))
@@ -403,8 +457,6 @@
 
 #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)
@@ -419,8 +471,6 @@
 #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
@@ -429,19 +479,21 @@
 #define _LIBCPP_HAS_NO_CONSTEXPR
 #endif
 
-// No version of GCC supports relaxed constexpr rules
+// Determine if GCC supports relaxed constexpr
+#if !defined(__cpp_constexpr) || __cpp_constexpr < 201304L
 #define _LIBCPP_HAS_NO_CXX14_CONSTEXPR
-// GCC 5 will support variable templates
-#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
+#endif
 
-#define _NOEXCEPT throw()
-#define _NOEXCEPT_(x)
-#define _NOEXCEPT_OR_FALSE(x) false
+// GCC 5 will support variable templates
+#if !defined(__cpp_variable_templates) || __cpp_variable_templates < 201304L
+#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
+#endif
 
 #ifndef __GXX_EXPERIMENTAL_CXX0X__
 
 #define _LIBCPP_HAS_NO_ADVANCED_SFINAE
 #define _LIBCPP_HAS_NO_DECLTYPE
+#define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS
 #define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
 #define _LIBCPP_HAS_NO_DELETED_FUNCTIONS
 #define _LIBCPP_HAS_NO_NULLPTR
@@ -449,32 +501,32 @@
 #define _LIBCPP_HAS_NO_UNICODE_CHARS
 #define _LIBCPP_HAS_NO_VARIADICS
 #define _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS
 #define _LIBCPP_HAS_NO_STRONG_ENUMS
+#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+#define _LIBCPP_HAS_NO_NOEXCEPT
 
 #else  // __GXX_EXPERIMENTAL_CXX0X__
 
-#define _LIBCPP_HAS_NO_TRAILING_RETURN
-#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS
-
 #if _GNUC_VER < 403
+#define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS
 #define _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#endif
-
-#if _GNUC_VER < 403
 #define _LIBCPP_HAS_NO_STATIC_ASSERT
 #endif
 
+
 #if _GNUC_VER < 404
 #define _LIBCPP_HAS_NO_DECLTYPE
 #define _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+#define _LIBCPP_HAS_NO_TRAILING_RETURN
 #define _LIBCPP_HAS_NO_UNICODE_CHARS
 #define _LIBCPP_HAS_NO_VARIADICS
 #define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 #endif  // _GNUC_VER < 404
 
 #if _GNUC_VER < 406
+#define _LIBCPP_HAS_NO_NOEXCEPT
 #define _LIBCPP_HAS_NO_NULLPTR
+#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
 #endif
 
 #if _GNUC_VER < 407
@@ -501,22 +553,19 @@
 #elif defined(_LIBCPP_MSVC)
 
 #define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-#define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
 #define _LIBCPP_HAS_NO_CONSTEXPR
 #define _LIBCPP_HAS_NO_CXX14_CONSTEXPR
 #define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
 #define _LIBCPP_HAS_NO_UNICODE_CHARS
 #define _LIBCPP_HAS_NO_DELETED_FUNCTIONS
 #define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#define _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
 
-#define _NOEXCEPT throw ()
-#define _NOEXCEPT_(x)
-#define _NOEXCEPT_OR_FALSE(x) false
+
 
 #define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {
 #define _LIBCPP_END_NAMESPACE_STD  }
@@ -534,16 +583,12 @@
 #define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
 #define _ATTRIBUTE(x) __attribute__((x))
 #define _LIBCPP_NORETURN __attribute__((noreturn))
-#define _LIBCPP_UNUSED
 
-#define _NOEXCEPT throw()
-#define _NOEXCEPT_(x)
-#define _NOEXCEPT_OR_FALSE(x) false
-
+#define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS
 #define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
 #define _LIBCPP_HAS_NO_ADVANCED_SFINAE
-#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS
 #define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#define _LIBCPP_HAS_NO_NOEXCEPT
 #define _LIBCPP_HAS_NO_NULLPTR
 #define _LIBCPP_HAS_NO_UNICODE_CHARS
 #define _LIBCPP_HAS_IS_BASE_OF
@@ -567,6 +612,14 @@
 
 #endif // __clang__ || __GNUC__ || _MSC_VER || __IBMCPP__
 
+#ifndef _LIBCPP_HAS_NO_NOEXCEPT
+#  define _NOEXCEPT noexcept
+#  define _NOEXCEPT_(x) noexcept(x)
+#else
+#  define _NOEXCEPT throw()
+#  define _NOEXCEPT_(x)
+#endif
+
 #ifdef _LIBCPP_HAS_NO_UNICODE_CHARS
 typedef unsigned short char16_t;
 typedef unsigned int   char32_t;
@@ -578,9 +631,11 @@
 
 #ifdef _LIBCPP_HAS_NO_STATIC_ASSERT
 
+extern "C++" {
 template <bool> struct __static_assert_test;
 template <> struct __static_assert_test<true> {};
 template <unsigned> struct __static_assert_check {};
+}
 #define static_assert(__b, __m) \
     typedef __static_assert_check<sizeof(__static_assert_test<(__b)>)> \
     _LIBCPP_CONCAT(__t, __LINE__)
@@ -608,6 +663,12 @@
 #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
@@ -665,10 +726,12 @@
 #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
@@ -716,6 +779,18 @@
 #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
+#  define _LIBCPP_EXPLICIT_MOVE(x) (x)
+#endif
+
 #ifndef _LIBCPP_HAS_NO_ASAN
 extern "C" void __sanitizer_annotate_contiguous_container(
   const void *, const void *, const void *, const void *);
@@ -725,7 +800,7 @@
 // g++ and cl.exe have RTTI on by default and define a macro when it is.
 // g++ only defines the macro in 4.3.2 and onwards.
 #if !defined(_LIBCPP_NO_RTTI)
-#  if defined(__GNUG__) && ((__GNUC__ >= 5) || (__GNUC__ == 4 && \
+#  if defined(__GNUC__) && ((__GNUC__ >= 5) || (__GNUC__ == 4 && \
    (__GNUC_MINOR__ >= 3 || __GNUC_PATCHLEVEL__ >= 2))) && !defined(__GXX_RTTI)
 #    define _LIBCPP_NO_RTTI
 #  elif (defined(_MSC_VER) && !defined(__clang__)) && !defined(_CPPRTTI)
@@ -737,6 +812,21 @@
 #  define _LIBCPP_WEAK __attribute__((__weak__))
 #endif
 
+// Thread API
+#ifndef _LIBCPP_HAS_NO_THREADS
+# if defined(__FreeBSD__) || \
+    defined(__NetBSD__) || \
+    defined(__linux__) || \
+    defined(__APPLE__) || \
+    defined(__CloudABI__) || \
+    defined(__sun__)
+#  define _LIBCPP_THREAD_API_PTHREAD
+# else
+#  error "No thread API"
+# endif // _LIBCPP_THREAD_API
+#endif // _LIBCPP_HAS_NO_THREADS
+
+
 #if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS)
 #  error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \
          _LIBCPP_HAS_NO_THREADS is defined.
@@ -757,7 +847,7 @@
 #define _LIBCPP_HAS_NO_STDOUT
 #endif
 
-#if defined(__ANDROID__) || defined(__CloudABI__)
+#if defined(__ANDROID__) || defined(__CloudABI__) || defined(_LIBCPP_HAS_MUSL_LIBC)
 #define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
 #endif
 
@@ -767,4 +857,34 @@
 #define _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
 #endif
 
-#endif  // _LIBCPP_CONFIG
+#if __has_feature(cxx_atomic) || __has_extension(c_atomic)
+#define _LIBCPP_HAS_C_ATOMIC_IMP
+#elif _GNUC_VER > 407
+#define _LIBCPP_HAS_GCC_ATOMIC_IMP
+#endif
+
+#if (!defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)) \
+     || defined(_LIBCPP_HAS_NO_THREADS)
+#define _LIBCPP_HAS_NO_ATOMIC_HEADER
+#endif
+
+#ifndef _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+#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
+
+#endif // _LIBCPP_CONFIG
diff --git a/include/__config_site.in b/include/__config_site.in
new file mode 100644
index 0000000..ec64485
--- /dev/null
+++ b/include/__config_site.in
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CONFIG_SITE
+#define _LIBCPP_CONFIG_SITE
+
+#cmakedefine _LIBCPP_ABI_VERSION @_LIBCPP_ABI_VERSION@
+#cmakedefine _LIBCPP_ABI_UNSTABLE
+#cmakedefine _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
+#cmakedefine _LIBCPP_HAS_NO_STDIN
+#cmakedefine _LIBCPP_HAS_NO_STDOUT
+#cmakedefine _LIBCPP_HAS_NO_THREADS
+#cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK
+#cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
+#cmakedefine _LIBCPP_HAS_MUSL_LIBC
+
+#endif // _LIBCPP_CONFIG_SITE
diff --git a/include/__functional_03 b/include/__functional_03
index 56a8475..4edbb09 100644
--- a/include/__functional_03
+++ b/include/__functional_03
@@ -451,15 +451,6 @@
     aligned_storage<3*sizeof(void*)>::type __buf_;
     __base* __f_;
 
-    template <class _Fp>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(const _Fp&) {return true;}
-    template <class _R2>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (*__p)()) {return __p;}
-    template <class _R2>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(const function<_R2()>& __p) {return __p;}
 public:
     typedef _Rp result_type;
 
@@ -558,7 +549,7 @@
                                      typename enable_if<!is_integral<_Fp>::value>::type*)
     : __f_(0)
 {
-    if (__not_null(__f))
+    if (__function::__not_null(__f))
     {
         typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;
         if (sizeof(_FF) <= sizeof(__buf_))
@@ -585,7 +576,7 @@
     : __f_(0)
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    if (__not_null(__f))
+    if (__function::__not_null(__f))
     {
         typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;
         if (sizeof(_FF) <= sizeof(__buf_))
@@ -736,27 +727,6 @@
     aligned_storage<3*sizeof(void*)>::type __buf_;
     __base* __f_;
 
-    template <class _Fp>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(const _Fp&) {return true;}
-    template <class _R2, class _B0>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (*__p)(_B0)) {return __p;}
-    template <class _R2, class _Cp>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)()) {return __p;}
-    template <class _R2, class _Cp>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)() const) {return __p;}
-    template <class _R2, class _Cp>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)() volatile) {return __p;}
-    template <class _R2, class _Cp>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)() const volatile) {return __p;}
-    template <class _R2, class _B0>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(const function<_R2(_B0)>& __p) {return __p;}
 public:
     typedef _Rp result_type;
 
@@ -855,7 +825,7 @@
                                      typename enable_if<!is_integral<_Fp>::value>::type*)
     : __f_(0)
 {
-    if (__not_null(__f))
+    if (__function::__not_null(__f))
     {
         typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;
         if (sizeof(_FF) <= sizeof(__buf_))
@@ -882,7 +852,7 @@
     : __f_(0)
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    if (__not_null(__f))
+    if (__function::__not_null(__f))
     {
         typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;
         if (sizeof(_FF) <= sizeof(__buf_))
@@ -1033,27 +1003,6 @@
     aligned_storage<3*sizeof(void*)>::type __buf_;
     __base* __f_;
 
-    template <class _Fp>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(const _Fp&) {return true;}
-    template <class _R2, class _B0, class _B1>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (*__p)(_B0, _B1)) {return __p;}
-    template <class _R2, class _Cp, class _B1>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)(_B1)) {return __p;}
-    template <class _R2, class _Cp, class _B1>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)(_B1) const) {return __p;}
-    template <class _R2, class _Cp, class _B1>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)(_B1) volatile) {return __p;}
-    template <class _R2, class _Cp, class _B1>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)(_B1) const volatile) {return __p;}
-    template <class _R2, class _B0, class _B1>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(const function<_R2(_B0, _B1)>& __p) {return __p;}
 public:
     typedef _Rp result_type;
 
@@ -1152,7 +1101,7 @@
                                  typename enable_if<!is_integral<_Fp>::value>::type*)
     : __f_(0)
 {
-    if (__not_null(__f))
+    if (__function::__not_null(__f))
     {
         typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;
         if (sizeof(_FF) <= sizeof(__buf_))
@@ -1179,7 +1128,7 @@
     : __f_(0)
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    if (__not_null(__f))
+    if (__function::__not_null(__f))
     {
         typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;
         if (sizeof(_FF) <= sizeof(__buf_))
@@ -1329,27 +1278,6 @@
     aligned_storage<3*sizeof(void*)>::type __buf_;
     __base* __f_;
 
-    template <class _Fp>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(const _Fp&) {return true;}
-    template <class _R2, class _B0, class _B1, class _B2>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (*__p)(_B0, _B1, _B2)) {return __p;}
-    template <class _R2, class _Cp, class _B1, class _B2>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2)) {return __p;}
-    template <class _R2, class _Cp, class _B1, class _B2>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const) {return __p;}
-    template <class _R2, class _Cp, class _B1, class _B2>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) volatile) {return __p;}
-    template <class _R2, class _Cp, class _B1, class _B2>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const volatile) {return __p;}
-    template <class _R2, class _B0, class _B1, class _B2>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(const function<_R2(_B0, _B1, _B2)>& __p) {return __p;}
 public:
     typedef _Rp result_type;
 
@@ -1449,7 +1377,7 @@
                                      typename enable_if<!is_integral<_Fp>::value>::type*)
     : __f_(0)
 {
-    if (__not_null(__f))
+    if (__function::__not_null(__f))
     {
         typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;
         if (sizeof(_FF) <= sizeof(__buf_))
@@ -1476,7 +1404,7 @@
     : __f_(0)
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    if (__not_null(__f))
+    if (__function::__not_null(__f))
     {
         typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;
         if (sizeof(_FF) <= sizeof(__buf_))
diff --git a/include/__functional_base b/include/__functional_base
index 3ff2e35..1a08ea2 100644
--- a/include/__functional_base
+++ b/include/__functional_base
@@ -38,8 +38,6 @@
     typedef _Result result_type;
 };
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash;
-
 template <class _Tp>
 struct __has_result_type
 {
@@ -77,57 +75,6 @@
 };
 #endif
 
-// addressof
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-_Tp*
-addressof(_Tp& __x) _NOEXCEPT
-{
-    return (_Tp*)&reinterpret_cast<const volatile char&>(__x);
-}
-
-#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
-// _LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF is defined, the compiler
-// itself is providing these definitions. Otherwise, we provide them.
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__strong _Tp*
-addressof(__strong _Tp& __x) _NOEXCEPT
-{
-  return &__x;
-}
-
-#ifdef _LIBCPP_HAS_OBJC_ARC_WEAK
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__weak _Tp*
-addressof(__weak _Tp& __x) _NOEXCEPT
-{
-  return &__x;
-}
-#endif
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__autoreleasing _Tp*
-addressof(__autoreleasing _Tp& __x) _NOEXCEPT
-{
-  return &__x;
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__unsafe_unretained _Tp*
-addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT
-{
-  return &__x;
-}
-#endif
-
-
 // __weak_result_type
 
 template <class _Tp>
@@ -357,75 +304,19 @@
 
 #endif // _LIBCPP_HAS_NO_VARIADICS
 
-// __invoke
+#ifndef _LIBCPP_CXX03_LANG
 
-#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
-
-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>
@@ -515,51 +406,119 @@
 #ifndef _LIBCPP_HAS_NO_VARIADICS
     // invoke
     template <class... _ArgTypes>
-       _LIBCPP_INLINE_VISIBILITY
-       typename __invoke_of<type&, _ArgTypes...>::type
-          operator() (_ArgTypes&&... __args) const
-          {
-              return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
-          }
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_of<type&, _ArgTypes...>::type
+    operator() (_ArgTypes&&... __args) const {
+        return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
+    }
 #else
 
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return<type>::type
-       operator() () const
-       {
-           return __invoke(get());
-       }
+    operator() () const {
+        return __invoke(get());
+    }
 
     template <class _A0>
-       _LIBCPP_INLINE_VISIBILITY
-       typename __invoke_return0<type&, _A0>::type
-          operator() (_A0& __a0) const
-          {
-              return __invoke<type&, _A0>(get(), __a0);
-          }
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return0<type, _A0>::type
+    operator() (_A0& __a0) const {
+        return __invoke(get(), __a0);
+    }
+
+    template <class _A0>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return0<type, _A0 const>::type
+    operator() (_A0 const& __a0) const {
+        return __invoke(get(), __a0);
+    }
 
     template <class _A0, class _A1>
-       _LIBCPP_INLINE_VISIBILITY
-       typename __invoke_return1<type&, _A0, _A1>::type
-          operator() (_A0& __a0, _A1& __a1) const
-          {
-              return __invoke<type&, _A0, _A1>(get(), __a0, __a1);
-          }
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return1<type, _A0, _A1>::type
+    operator() (_A0& __a0, _A1& __a1) const {
+        return __invoke(get(), __a0, __a1);
+    }
+
+    template <class _A0, class _A1>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return1<type, _A0 const, _A1>::type
+    operator() (_A0 const& __a0, _A1& __a1) const {
+        return __invoke(get(), __a0, __a1);
+    }
+
+    template <class _A0, class _A1>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return1<type, _A0, _A1 const>::type
+    operator() (_A0& __a0, _A1 const& __a1) const {
+        return __invoke(get(), __a0, __a1);
+    }
+
+    template <class _A0, class _A1>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return1<type, _A0 const, _A1 const>::type
+    operator() (_A0 const& __a0, _A1 const& __a1) const {
+        return __invoke(get(), __a0, __a1);
+    }
 
     template <class _A0, class _A1, class _A2>
-       _LIBCPP_INLINE_VISIBILITY
-       typename __invoke_return2<type&, _A0, _A1, _A2>::type
-          operator() (_A0& __a0, _A1& __a1, _A2& __a2) const
-          {
-              return __invoke<type&, _A0, _A1, _A2>(get(), __a0, __a1, __a2);
-          }
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0, _A1, _A2>::type
+    operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
+        return __invoke(get(), __a0, __a1, __a2);
+    }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0 const, _A1, _A2>::type
+    operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const {
+        return __invoke(get(), __a0, __a1, __a2);
+    }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0, _A1 const, _A2>::type
+    operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const {
+        return __invoke(get(), __a0, __a1, __a2);
+    }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0, _A1, _A2 const>::type
+    operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const {
+        return __invoke(get(), __a0, __a1, __a2);
+    }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type
+    operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const {
+        return __invoke(get(), __a0, __a1, __a2);
+    }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type
+    operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const {
+        return __invoke(get(), __a0, __a1, __a2);
+    }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type
+    operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const {
+        return __invoke(get(), __a0, __a1, __a2);
+    }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type
+    operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const {
+        return __invoke(get(), __a0, __a1, __a2);
+    }
 #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/__functional_base_03 b/include/__functional_base_03
index 0a7ff62..8407dcf 100644
--- a/include/__functional_base_03
+++ b/include/__functional_base_03
@@ -14,431 +14,128 @@
 // manual variadic expansion for <functional>
 
 // __invoke
+
+template <class _Ret, class _T1, bool _IsFunc, bool _IsBase>
+struct __enable_invoke_imp;
+
+template <class _Ret, class _T1>
+struct __enable_invoke_imp<_Ret, _T1, true, true> {
+    typedef _Ret _Bullet1;
+    typedef _Bullet1 type;
+};
+
+template <class _Ret, class _T1>
+struct __enable_invoke_imp<_Ret, _T1, true, false>  {
+    typedef _Ret _Bullet2;
+    typedef _Bullet2 type;
+};
+
+template <class _Ret, class _T1>
+struct __enable_invoke_imp<_Ret, _T1, false, true>  {
+    typedef typename add_lvalue_reference<
+                typename __apply_cv<_T1, _Ret>::type
+            >::type _Bullet3;
+    typedef _Bullet3 type;
+};
+
+template <class _Ret, class _T1>
+struct __enable_invoke_imp<_Ret, _T1, false, false>  {
+    typedef typename add_lvalue_reference<
+                typename __apply_cv<decltype(*_VSTD::declval<_T1>()), _Ret>::type
+            >::type _Bullet4;
+    typedef _Bullet4 type;
+};
+
+template <class _Ret, class _T1>
+struct __enable_invoke_imp<_Ret, _T1*, false, false>  {
+    typedef typename add_lvalue_reference<
+                typename __apply_cv<_T1, _Ret>::type
+            >::type _Bullet4;
+    typedef _Bullet4  type;
+};
+
+template <class _Fn, class _T1,
+          class _Traits = __member_pointer_traits<_Fn>,
+          class _Ret = typename _Traits::_ReturnType,
+          class _Class = typename _Traits::_ClassType>
+struct __enable_invoke : __enable_invoke_imp<
+    _Ret, _T1,
+    is_member_function_pointer<_Fn>::value,
+    is_base_of<_Class, typename remove_reference<_T1>::type>::value>
+{
+};
+
+__nat __invoke(__any, ...);
+
 // first bullet
 
-template <class _Rp, class _Tp, class _T1>
+template <class _Fn, class _T1>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(), _T1& __t1)
-{
+typename __enable_invoke<_Fn, _T1>::_Bullet1
+__invoke(_Fn __f, _T1& __t1) {
     return (__t1.*__f)();
 }
 
-template <class _Rp, class _Tp, class _T1, class _A0>
+template <class _Fn, class _T1, class _A0>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0), _T1& __t1, _A0& __a0)
-{
+typename __enable_invoke<_Fn, _T1>::_Bullet1
+__invoke(_Fn __f, _T1& __t1, _A0& __a0) {
     return (__t1.*__f)(__a0);
 }
 
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+template <class _Fn, class _T1, class _A0, class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1), _T1& __t1, _A0& __a0, _A1& __a1)
-{
+typename __enable_invoke<_Fn, _T1>::_Bullet1
+__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
     return (__t1.*__f)(__a0, __a1);
 }
 
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+template <class _Fn, class _T1, class _A0, class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2), _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2)
-{
+typename __enable_invoke<_Fn, _T1>::_Bullet1
+__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) {
     return (__t1.*__f)(__a0, __a1, __a2);
 }
 
-template <class _Rp, class _Tp, class _T1>
+template <class _Fn, class _T1>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)() const, _T1& __t1)
-{
-    return (__t1.*__f)();
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0) const, _T1& __t1, _A0& __a0)
-{
-    return (__t1.*__f)(__a0);
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1) const, _T1& __t1, _A0& __a0, _A1& __a1)
-{
-    return (__t1.*__f)(__a0, __a1);
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2)
-{
-    return (__t1.*__f)(__a0, __a1, __a2);
-}
-
-template <class _Rp, class _Tp, class _T1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)() volatile, _T1& __t1)
-{
-    return (__t1.*__f)();
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0) volatile, _T1& __t1, _A0& __a0)
-{
-    return (__t1.*__f)(__a0);
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1) volatile, _T1& __t1, _A0& __a0, _A1& __a1)
-{
-    return (__t1.*__f)(__a0, __a1);
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) volatile, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2)
-{
-    return (__t1.*__f)(__a0, __a1, __a2);
-}
-
-template <class _Rp, class _Tp, class _T1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)() const volatile, _T1& __t1)
-{
-    return (__t1.*__f)();
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0) const volatile, _T1& __t1, _A0& __a0)
-{
-    return (__t1.*__f)(__a0);
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1) const volatile, _T1& __t1, _A0& __a0, _A1& __a1)
-{
-    return (__t1.*__f)(__a0, __a1);
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const volatile, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2)
-{
-    return (__t1.*__f)(__a0, __a1, __a2);
-}
-
-// second bullet
-
-template <class _Rp, class _Tp, class _T1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(), _T1 __t1)
-{
+typename __enable_invoke<_Fn, _T1>::_Bullet2
+__invoke(_Fn __f, _T1& __t1) {
     return ((*__t1).*__f)();
 }
 
-template <class _Rp, class _Tp, class _T1, class _A0>
+template <class _Fn, class _T1, class _A0>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0), _T1 __t1, _A0& __a0)
-{
+typename __enable_invoke<_Fn, _T1>::_Bullet2
+__invoke(_Fn __f, _T1& __t1, _A0& __a0) {
     return ((*__t1).*__f)(__a0);
 }
 
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+template <class _Fn, class _T1, class _A0, class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1), _T1 __t1, _A0& __a0, _A1& __a1)
-{
+typename __enable_invoke<_Fn, _T1>::_Bullet2
+__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
     return ((*__t1).*__f)(__a0, __a1);
 }
 
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+template <class _Fn, class _T1, class _A0, class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2), _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2)
-{
+typename __enable_invoke<_Fn, _T1>::_Bullet2
+__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) {
     return ((*__t1).*__f)(__a0, __a1, __a2);
 }
 
-template <class _Rp, class _Tp, class _T1>
+template <class _Fn, class _T1>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)() const, _T1 __t1)
-{
-    return ((*__t1).*__f)();
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0) const, _T1 __t1, _A0& __a0)
-{
-    return ((*__t1).*__f)(__a0);
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1) const, _T1 __t1, _A0& __a0, _A1& __a1)
-{
-    return ((*__t1).*__f)(__a0, __a1);
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const, _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2)
-{
-    return ((*__t1).*__f)(__a0, __a1, __a2);
-}
-
-template <class _Rp, class _Tp, class _T1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)() volatile, _T1 __t1)
-{
-    return ((*__t1).*__f)();
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0) volatile, _T1 __t1, _A0& __a0)
-{
-    return ((*__t1).*__f)(__a0);
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1) volatile, _T1 __t1, _A0& __a0, _A1& __a1)
-{
-    return ((*__t1).*__f)(__a0, __a1);
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) volatile, _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2)
-{
-    return ((*__t1).*__f)(__a0, __a1, __a2);
-}
-
-template <class _Rp, class _Tp, class _T1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)() const volatile, _T1 __t1)
-{
-    return ((*__t1).*__f)();
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0) const volatile, _T1 __t1, _A0& __a0)
-{
-    return ((*__t1).*__f)(__a0);
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1) const volatile, _T1 __t1, _A0& __a0, _A1& __a1)
-{
-    return ((*__t1).*__f)(__a0, __a1);
-}
-
-template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    _Rp
->::type
-__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const volatile, _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2)
-{
-    return ((*__t1).*__f)(__a0, __a1, __a2);
-}
-
-// third bullet
-
-template <class _Rp, class _Tp, class _T1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_member_object_pointer<_Rp _Tp::*>::value &&
-    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-   __apply_cv<_T1, _Rp>
->::type::type&
-__invoke(_Rp _Tp::* __f, _T1& __t1)
-{
+typename __enable_invoke<_Fn, _T1>::_Bullet3
+__invoke(_Fn __f, _T1& __t1) {
     return __t1.*__f;
 }
 
-
-// forth bullet
-
-template <class _T1, class _Rp, bool>
-struct __4th_helper
-{
-};
-
-template <class _T1, class _Rp>
-struct __4th_helper<_T1, _Rp, true>
-{
-    typedef typename __apply_cv<decltype(*_VSTD::declval<_T1&>()), _Rp>::type type;
-};
-
-template <class _Rp, class _Tp, class _T1>
+template <class _Fn, class _T1>
 inline _LIBCPP_INLINE_VISIBILITY
-typename __4th_helper<_T1, _Rp,
-    is_member_object_pointer<_Rp _Tp::*>::value &&
-    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value
->::type&
-__invoke(_Rp _Tp::* __f, _T1& __t1)
-{
+typename __enable_invoke<_Fn, _T1>::_Bullet4
+__invoke(_Fn __f, _T1& __t1) {
     return (*__t1).*__f;
 }
 
@@ -488,29 +185,28 @@
     typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type;
 };
 
-template <class _Tp, class _A0, bool = is_member_object_pointer<_Tp>::value>
+template <class _Tp, class _A0>
 struct __invoke_return0
 {
     typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type;
 };
 
 template <class _Rp, class _Tp, class _A0>
-struct __invoke_return0<_Rp _Tp::*, _A0, true>
+struct __invoke_return0<_Rp _Tp::*, _A0>
 {
-    typedef typename __apply_cv<_A0, _Rp>::type& type;
-};
-
-template <class _Rp, class _Tp, class _A0>
-struct __invoke_return0<_Rp _Tp::*, _A0*, true>
-{
-    typedef typename __apply_cv<_A0, _Rp>::type& type;
+    typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type;
 };
 
 template <class _Tp, class _A0, class _A1>
 struct __invoke_return1
 {
     typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),
-                                                     _VSTD::declval<_A1&>())) type;
+                                                      _VSTD::declval<_A1&>())) type;
+};
+
+template <class _Rp, class _Class, class _A0, class _A1>
+struct __invoke_return1<_Rp _Class::*, _A0, _A1> {
+    typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type;
 };
 
 template <class _Tp, class _A0, class _A1, class _A2>
@@ -521,4 +217,8 @@
                                                       _VSTD::declval<_A2&>())) type;
 };
 
+template <class _Ret, class _Class, class _A0, class _A1, class _A2>
+struct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> {
+    typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type;
+};
 #endif  // _LIBCPP_FUNCTIONAL_BASE_03
diff --git a/include/__hash_table b/include/__hash_table
index dac4cfd..8f6fc4d 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);
 
@@ -46,18 +70,13 @@
 struct __hash_node
     : public __hash_node_base
              <
-                 typename pointer_traits<_VoidPtr>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-                     rebind<__hash_node<_Tp, _VoidPtr> >
-#else
-                     rebind<__hash_node<_Tp, _VoidPtr> >::other
-#endif
+                 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
@@ -81,32 +100,175 @@
     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 _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
     class _LIBCPP_TYPE_VIS_ONLY unordered_map;
 
+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 pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-                     rebind<value_type>
-#else
-                     rebind<value_type>::other
-#endif
-                                                         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
@@ -215,37 +377,24 @@
     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;
+    static_assert(!is_const<typename pointer_traits<_NodePtr>::element_type>::value, "");
+    typedef __hash_node_types<_NodePtr> _NodeTypes;
+    typedef _NodePtr __node_pointer;
 
-    __node_pointer         __node_;
-
-    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 pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<const value_type>
-#else
-            rebind<const value_type>::other
-#endif
-                                                       pointer;
-    typedef typename pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<__node>
-#else
-            rebind<__node>::other
-#endif
-                                                      __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
@@ -361,30 +510,22 @@
     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 __pointer_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<value_type>
-#else
-            rebind<value_type>::other
-#endif
-                                                                pointer;
+    typedef typename _NodeTypes::__node_value_type_pointer      pointer;
 
     _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT
     {
@@ -507,7 +648,8 @@
 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_;
@@ -516,29 +658,18 @@
     typedef pointer_traits<__node_pointer>          __pointer_traits;
     typedef typename __pointer_traits::element_type __node;
     typedef typename remove_const<__node>::type     __non_const_node;
-    typedef typename pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<__non_const_node>
-#else
-            rebind<__non_const_node>::other
-#endif
-                                                    __non_const_node_pointer;
+    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 __pointer_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<const value_type>
-#else
-            rebind<const value_type>::other
-#endif
-                                                       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
     {
@@ -725,10 +856,11 @@
 {
     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_;
 
@@ -748,7 +880,7 @@
     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);
     }
@@ -767,28 +899,47 @@
 
 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 pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<__first_node>
-#else
-            rebind<__first_node>::other
-#endif
-                                                     __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:
 
@@ -799,10 +950,10 @@
     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
@@ -838,6 +989,7 @@
     typedef __hash_local_iterator<__node_pointer>             local_iterator;
     typedef __hash_const_local_iterator<__node_pointer>       const_local_iterator;
 
+    _LIBCPP_INLINE_VISIBILITY
     __hash_table()
         _NOEXCEPT_(
             is_nothrow_default_constructible<__bucket_list>::value &&
@@ -845,13 +997,14 @@
             is_nothrow_default_constructible<__node_allocator>::value &&
             is_nothrow_default_constructible<hasher>::value &&
             is_nothrow_default_constructible<key_equal>::value);
+    _LIBCPP_INLINE_VISIBILITY
     __hash_table(const hasher& __hf, const key_equal& __eql);
     __hash_table(const hasher& __hf, const key_equal& __eql,
                  const allocator_type& __a);
     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 &&
@@ -860,11 +1013,12 @@
             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_(
             __node_traits::propagate_on_container_move_assignment::value &&
@@ -889,41 +1043,103 @@
     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);
-    template <class... _Args>
-        iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
-#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+#ifndef _LIBCPP_CXX03_LANG
+    template <class _Key, class ..._Args>
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args);
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    template <class _ValueTp>
+    template <class... _Args>
     _LIBCPP_INLINE_VISIBILITY
-    pair<iterator, bool> __insert_unique_value(_ValueTp&& __x);
-#else
+    pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
+
+    template <class _Pp>
     _LIBCPP_INLINE_VISIBILITY
-    pair<iterator, bool> __insert_unique_value(const value_type& __x);
+    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... _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));
+    }
+
+    template <class _Pp>
+    _LIBCPP_INLINE_VISIBILITY
+    iterator __insert_multi(_Pp&& __x) {
+      return __emplace_multi(_VSTD::forward<_Pp>(__x));
+    }
+
+    template <class _Pp>
+    _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
 
-    pair<iterator, bool> __insert_unique(const value_type& __x);
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    pair<iterator, bool> __insert_unique(value_type&& __x);
-    template <class _Pp>
-    pair<iterator, bool> __insert_unique(_Pp&& __x);
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    template <class _Pp>
-        iterator __insert_multi(_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
+    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);
@@ -936,9 +1152,13 @@
         return __bucket_list_.get_deleter().size();
     }
 
+    _LIBCPP_INLINE_VISIBILITY
     iterator       begin() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     iterator       end() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     const_iterator begin() const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     const_iterator end() const _NOEXCEPT;
 
     template <class _Key>
@@ -967,6 +1187,7 @@
     __node_holder remove(const_iterator __p) _NOEXCEPT;
 
     template <class _Key>
+        _LIBCPP_INLINE_VISIBILITY
         size_type __count_unique(const _Key& __k) const;
     template <class _Key>
         size_type __count_multi(const _Key& __k) const;
@@ -1078,16 +1299,17 @@
 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)
@@ -1097,6 +1319,7 @@
     _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_(
@@ -1123,6 +1346,7 @@
     }
     _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;
@@ -1132,11 +1356,12 @@
 };
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table()
     _NOEXCEPT_(
         is_nothrow_default_constructible<__bucket_list>::value &&
         is_nothrow_default_constructible<__first_node>::value &&
+        is_nothrow_default_constructible<__node_allocator>::value &&
         is_nothrow_default_constructible<hasher>::value &&
         is_nothrow_default_constructible<key_equal>::value)
     : __p2_(0),
@@ -1145,7 +1370,7 @@
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,
                                                        const key_equal& __eql)
     : __bucket_list_(nullptr, __bucket_list_deleter()),
@@ -1198,13 +1423,14 @@
 {
 }
 
-#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)
         _NOEXCEPT_(
             is_nothrow_move_constructible<__bucket_list>::value &&
             is_nothrow_move_constructible<__first_node>::value &&
+            is_nothrow_move_constructible<__node_allocator>::value &&
             is_nothrow_move_constructible<hasher>::value &&
             is_nothrow_move_constructible<key_equal>::value)
     : __bucket_list_(_VSTD::move(__u.__bucket_list_)),
@@ -1246,7 +1472,7 @@
     }
 }
 
-#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()
@@ -1311,7 +1537,7 @@
         }
         __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;
     }
@@ -1330,7 +1556,7 @@
     return __cache;
 }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_CXX03_LANG
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 void
@@ -1403,8 +1629,7 @@
         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();
         }
@@ -1412,7 +1637,7 @@
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __hash_table<_Tp, _Hash, _Equal, _Alloc>&
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u)
     _NOEXCEPT_(
@@ -1426,7 +1651,7 @@
     return *this;
 }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif  // _LIBCPP_CXX03_LANG
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 template <class _InputIterator>
@@ -1434,6 +1659,11 @@
 __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();
@@ -1468,6 +1698,12 @@
 __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();
@@ -1493,11 +1729,11 @@
         __deallocate(__cache);
     }
     for (; __first != __last; ++__first)
-        __insert_multi(*__first);
+        __insert_multi(_NodeTypes::__get_value(*__first));
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT
 {
@@ -1509,7 +1745,7 @@
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT
 {
@@ -1521,7 +1757,7 @@
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT
 {
@@ -1533,7 +1769,7 @@
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT
 {
@@ -1719,31 +1955,24 @@
     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;
@@ -1758,13 +1987,17 @@
                                        __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),
@@ -1776,7 +2009,7 @@
         __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_
@@ -1802,13 +2035,12 @@
 #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());
@@ -1845,64 +2077,11 @@
     return __r;
 }
 
-#endif  // _LIBCPP_HAS_NO_VARIADICS
-
-template <class _Tp, class _Hash, class _Equal, class _Alloc>
-pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(value_type&& __x)
-{
-    return __insert_unique_value(_VSTD::move(__x));
-}
-
-template <class _Tp, class _Hash, class _Equal, class _Alloc>
-template <class _Pp>
-pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(_Pp&& __x)
-{
-    __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
+#else // _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>::__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());
@@ -1913,7 +2092,7 @@
 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,
@@ -1926,7 +2105,7 @@
     return __r;
 }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif  // _LIBCPP_CXX03_LANG
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 void
@@ -2065,70 +2244,74 @@
     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 _VSTD::move(__h);  // explicitly moved for C++03
+    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 _VSTD::move(__h);  // explicitly moved for C++03
+    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)
@@ -2258,7 +2441,7 @@
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 template <class _Key>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const
 {
diff --git a/include/__locale b/include/__locale
index 1989558..7bc701d 100644
--- a/include/__locale
+++ b/include/__locale
@@ -37,6 +37,8 @@
 #elif (defined(__GLIBC__) || defined(__APPLE__)      || defined(__FreeBSD__) \
     || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
 # include <xlocale.h>
+#elif defined(_LIBCPP_HAS_MUSL_LIBC)
+# include <support/musl/xlocale.h>
 #endif // __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || __EMSCRIPTEN__ || __IBMCPP__
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -329,7 +331,7 @@
 class _LIBCPP_TYPE_VIS ctype_base
 {
 public:
-#ifdef __GLIBC__
+#if defined(__GLIBC__)
     typedef unsigned short mask;
     static const mask space  = _ISspace;
     static const mask print  = _ISprint;
@@ -359,7 +361,7 @@
     typedef __uint32_t mask;
 # elif defined(__FreeBSD__)
     typedef unsigned long mask;
-# elif defined(__EMSCRIPTEN__) ||  defined(__NetBSD__)
+# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)
     typedef unsigned short mask;
 # endif
     static const mask space  = _CTYPE_S;
diff --git a/include/__mutex_base b/include/__mutex_base
index d5ece7c..32536a6 100644
--- a/include/__mutex_base
+++ b/include/__mutex_base
@@ -14,7 +14,7 @@
 #include <__config>
 #include <chrono>
 #include <system_error>
-#include <pthread.h>
+#include <__threading_support>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -24,16 +24,24 @@
 
 #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_;
+    __libcpp_mutex_t __m_;
 
 public:
     _LIBCPP_INLINE_VISIBILITY
 #ifndef _LIBCPP_HAS_NO_CONSTEXPR
-     constexpr mutex() _NOEXCEPT : __m_(PTHREAD_MUTEX_INITIALIZER) {}
+    constexpr mutex() _NOEXCEPT : __m_(_LIBCPP_MUTEX_INITIALIZER) {}
 #else
-     mutex() _NOEXCEPT {__m_ = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;}
+    mutex() _NOEXCEPT {__m_ = (__libcpp_mutex_t)_LIBCPP_MUTEX_INITIALIZER;}
 #endif
      ~mutex();
 
@@ -42,11 +50,11 @@
     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_;}
 };
 
@@ -69,7 +77,7 @@
 #endif
 
 template <class _Mutex>
-class _LIBCPP_TYPE_VIS_ONLY lock_guard
+class _LIBCPP_TYPE_VIS_ONLY _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) lock_guard
 {
 public:
     typedef _Mutex mutex_type;
@@ -79,13 +87,13 @@
 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;
@@ -107,24 +115,24 @@
     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()
     {
@@ -266,13 +274,13 @@
 
 class _LIBCPP_TYPE_VIS condition_variable
 {
-    pthread_cond_t __cv_;
+    __libcpp_condvar_t  __cv_;
 public:
     _LIBCPP_INLINE_VISIBILITY
 #ifndef _LIBCPP_HAS_NO_CONSTEXPR
-    constexpr condition_variable() : __cv_(PTHREAD_COND_INITIALIZER) {}
+    constexpr condition_variable() : __cv_(_LIBCPP_CONDVAR_INITIALIZER) {}
 #else
-    condition_variable() {__cv_ = (pthread_cond_t)PTHREAD_COND_INITIALIZER;}
+    condition_variable() {__cv_ = (__libcpp_condvar_t)_LIBCPP_CONDVAR_INITIALIZER;}
 #endif
     ~condition_variable();
 
@@ -306,11 +314,12 @@
 
     template <class _Rep, class _Period, class _Predicate>
         bool
+        _LIBCPP_INLINE_VISIBILITY
         wait_for(unique_lock<mutex>& __lk,
                  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:
@@ -390,7 +399,7 @@
 }
 
 template <class _Rep, class _Period, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 condition_variable::wait_for(unique_lock<mutex>& __lk,
                              const chrono::duration<_Rep, _Period>& __d,
diff --git a/include/__nullptr b/include/__nullptr
new file mode 100644
index 0000000..95415a6
--- /dev/null
+++ b/include/__nullptr
@@ -0,0 +1,66 @@
+// -*- C++ -*-
+//===--------------------------- __nullptr --------------------------------===//
+//
+//                     The 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_NULLPTR
+#define _LIBCPP_NULLPTR
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#ifdef _LIBCPP_HAS_NO_NULLPTR
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct _LIBCPP_TYPE_VIS_ONLY nullptr_t
+{
+    void* __lx;
+
+    struct __nat {int __for_bool_;};
+
+    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {}
+    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}
+
+    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}
+
+    template <class _Tp>
+        _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR
+        operator _Tp* () const {return 0;}
+
+    template <class _Tp, class _Up>
+        _LIBCPP_ALWAYS_INLINE
+        operator _Tp _Up::* () const {return 0;}
+
+    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;}
+    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;}
+    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator<(nullptr_t, nullptr_t) {return false;}
+    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator<=(nullptr_t, nullptr_t) {return true;}
+    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator>(nullptr_t, nullptr_t) {return false;}
+    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator>=(nullptr_t, nullptr_t) {return true;}
+};
+
+inline _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);}
+
+#define nullptr _VSTD::__get_nullptr_t()
+
+_LIBCPP_END_NAMESPACE_STD
+
+#else  // _LIBCPP_HAS_NO_NULLPTR
+
+namespace std
+{
+    typedef decltype(nullptr) nullptr_t;
+}
+
+#endif  // _LIBCPP_HAS_NO_NULLPTR
+
+#endif  // _LIBCPP_NULLPTR
diff --git a/include/__split_buffer b/include/__split_buffer
index 727b1b6..79d1aa1 100644
--- a/include/__split_buffer
+++ b/include/__split_buffer
@@ -56,9 +56,12 @@
     _LIBCPP_INLINE_VISIBILITY pointer&              __end_cap() _NOEXCEPT       {return __end_cap_.first();}
     _LIBCPP_INLINE_VISIBILITY const pointer&        __end_cap() const _NOEXCEPT {return __end_cap_.first();}
 
+    _LIBCPP_INLINE_VISIBILITY
     __split_buffer()
         _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
+    _LIBCPP_INLINE_VISIBILITY
     explicit __split_buffer(__alloc_rr& __a);
+    _LIBCPP_INLINE_VISIBILITY
     explicit __split_buffer(const __alloc_rr& __a);
     __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a);
     ~__split_buffer();
@@ -128,7 +131,9 @@
 
     _LIBCPP_INLINE_VISIBILITY void __destruct_at_begin(pointer __new_begin)
         {__destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());}
+        _LIBCPP_INLINE_VISIBILITY
         void __destruct_at_begin(pointer __new_begin, false_type);
+        _LIBCPP_INLINE_VISIBILITY
         void __destruct_at_begin(pointer __new_begin, true_type);
 
     _LIBCPP_INLINE_VISIBILITY
@@ -266,7 +271,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 __split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type)
 {
@@ -275,7 +280,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 __split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type)
 {
@@ -309,7 +314,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __split_buffer<_Tp, _Allocator>::__split_buffer()
     _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
     : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr)
@@ -317,14 +322,14 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a)
     : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
 {
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a)
     : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
 {
diff --git a/include/__threading_support b/include/__threading_support
new file mode 100644
index 0000000..49fdca2
--- /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_THREAD_API_PTHREAD)
+#include <pthread.h>
+#include <sched.h>
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if defined(_LIBCPP_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_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 8030eef..62178e3 100644
--- a/include/__tree
+++ b/include/__tree
@@ -37,6 +37,22 @@
 template <class _Key, class _Compare, class _Allocator>
     class _LIBCPP_TYPE_VIS_ONLY multiset;
 
+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
@@ -502,41 +518,165 @@
     }
 }
 
-template <class _Allocator> class __map_node_destructor;
+// node traits
 
-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;
+
+#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;
 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 {};
 
-    __tree_node_destructor& operator=(const __tree_node_destructor&);
+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;
+};
 
+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)
-        {}
+  typedef typename pointer_traits<_NodePtr>::element_type       __node_type;
+  typedef _NodePtr                                              __node_pointer;
 
-    _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 _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 __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
@@ -554,42 +694,21 @@
 
 template <class _VoidPtr>
 class __tree_node_base
-    : public __tree_end_node
-             <
-                typename pointer_traits<_VoidPtr>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-                     rebind<__tree_node_base<_VoidPtr> >
-#else
-                     rebind<__tree_node_base<_VoidPtr> >::other
-#endif
-             >
+    : public __tree_node_base_types<_VoidPtr>::__end_node_type
 {
-    __tree_node_base(const __tree_node_base&);
-    __tree_node_base& operator=(const __tree_node_base&);
+    typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes;
+
 public:
-    typedef typename pointer_traits<_VoidPtr>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<__tree_node_base>
-#else
-            rebind<__tree_node_base>::other
-#endif
-                                                pointer;
-    typedef typename pointer_traits<_VoidPtr>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<const __tree_node_base>
-#else
-            rebind<const __tree_node_base>::other
-#endif
-                                                const_pointer;
-    typedef __tree_end_node<pointer> base;
+    typedef typename _NodeBaseTypes::__node_base_pointer pointer;
 
     pointer __right_;
     pointer __parent_;
     bool __is_black_;
 
-    _LIBCPP_INLINE_VISIBILITY
-    __tree_node_base() _NOEXCEPT
-        : __right_(), __parent_(), __is_black_(false) {}
+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>
@@ -597,47 +716,69 @@
     : 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_;
 
-#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)
+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 _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_iterator;
-template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
+
+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)
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    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 _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 pointer_traits<__node_pointer> __pointer_traits;
 
     __node_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 pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<value_type>
-#else
-            rebind<value_type>::other
-#endif
-                                       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
@@ -652,7 +793,7 @@
     _LIBCPP_INLINE_VISIBILITY
     __tree_iterator& operator++() {
       __ptr_ = static_cast<__node_pointer>(
-          __tree_next(static_cast<typename __node::base::pointer>(__ptr_)));
+          __tree_next(static_cast<__node_base_pointer>(__ptr_)));
       return *this;
     }
     _LIBCPP_INLINE_VISIBILITY
@@ -662,7 +803,7 @@
     _LIBCPP_INLINE_VISIBILITY
     __tree_iterator& operator--() {
       __ptr_ = static_cast<__node_pointer>(
-          __tree_prev(static_cast<typename __node::base::pointer>(__ptr_)));
+          __tree_prev(static_cast<__node_base_pointer>(__ptr_)));
       return *this;
     }
     _LIBCPP_INLINE_VISIBILITY
@@ -688,27 +829,22 @@
     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 pointer_traits<__node_pointer> __pointer_traits;
 
     __node_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 pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<const value_type>
-#else
-            rebind<const value_type>::other
-#endif
-                                       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
@@ -717,16 +853,8 @@
     {}
 
 private:
-    typedef typename remove_const<__node>::type  __non_const_node;
-    typedef typename pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<__non_const_node>
-#else
-            rebind<__non_const_node>::other
-#endif
-                                                 __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
@@ -738,14 +866,6 @@
 
     _LIBCPP_INLINE_VISIBILITY
     __tree_const_iterator& operator++() {
-      typedef typename pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-          rebind<typename __node::base>
-#else
-          rebind<typename __node::base>::other
-#endif
-              __node_base_pointer;
-
       __ptr_ = static_cast<__node_pointer>(
           __tree_next(static_cast<__node_base_pointer>(__ptr_)));
       return *this;
@@ -757,14 +877,6 @@
 
     _LIBCPP_INLINE_VISIBILITY
     __tree_const_iterator& operator--() {
-      typedef typename pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-          rebind<typename __node::base>
-#else
-          rebind<typename __node::base>::other
-#endif
-              __node_base_pointer;
-
       __ptr_ = static_cast<__node_pointer>(
           __tree_prev(static_cast<__node_base_pointer>(__ptr_)));
       return *this;
@@ -800,40 +912,51 @@
     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 __tree_node<value_type, __void_pointer> __node;
-    typedef __tree_node_base<__void_pointer>        __node_base;
+    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 __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;
-private:
-    typedef typename __node_base::base __end_node_t;
-    typedef typename pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<__end_node_t>
-#else
-            rebind<__end_node_t>::other
-#endif
-                                                     __end_node_ptr;
-    typedef typename pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<__end_node_t>
-#else
-            rebind<__end_node_t>::other
-#endif
-                                                     __end_node_const_ptr;
+    typedef allocator_traits<__node_allocator>         __node_traits;
 
-    __node_pointer                                          __begin_node_;
+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, __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.");
+
+private:
+    __node_pointer                                     __begin_node_;
     __compressed_pair<__end_node_t, __node_allocator>  __pair1_;
     __compressed_pair<size_type, value_compare>        __pair3_;
 
@@ -841,18 +964,18 @@
     _LIBCPP_INLINE_VISIBILITY
     __node_pointer __end_node() _NOEXCEPT
     {
-        return static_cast<__node_pointer>
-               (
-                   pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
-               );
+        return static_cast<__node_pointer>(
+                pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
+        );
     }
     _LIBCPP_INLINE_VISIBILITY
-    __node_const_pointer __end_node() const _NOEXCEPT
+    __node_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<__node_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();}
@@ -880,12 +1003,10 @@
     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_);}
 
     typedef __tree_iterator<value_type, __node_pointer, difference_type>             iterator;
     typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
@@ -941,37 +1062,194 @@
 #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_impl(_Args&&... __args);
+
+    template <class... _Args>
+    iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
+
+    template <class... _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>
-        __emplace_unique(_Args&&... __args);
-    template <class... _Args>
-        iterator
-        __emplace_multi(_Args&&... __args);
+    >::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_unique(const_iterator __p, _Args&&... __args);
+    >::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... _Args>
-        iterator
-        __emplace_hint_multi(const_iterator __p, _Args&&... __args);
-#endif  // _LIBCPP_HAS_NO_VARIADICS
+    _LIBCPP_INLINE_VISIBILITY
+    iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
+        return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...);
+    }
+
+    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));
+    }
+
+    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>
-        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
+    _LIBCPP_INLINE_VISIBILITY
+    iterator __insert_multi(_Vp&& __v) {
+        return __emplace_multi(_VSTD::forward<_Vp>(__v));
+    }
 
-    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 _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,
@@ -1015,8 +1293,8 @@
             {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,
+                                     __node_pointer __result) const;
     template <class _Key>
         _LIBCPP_INLINE_VISIBILITY
         iterator upper_bound(const _Key& __v)
@@ -1031,8 +1309,8 @@
             {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,
+                                     __node_pointer __result) const;
     template <class _Key>
         pair<iterator, iterator>
         __equal_range_unique(const _Key& __k);
@@ -1053,12 +1331,12 @@
     __node_holder remove(const_iterator __p) _NOEXCEPT;
 private:
     typename __node_base::pointer&
-        __find_leaf_low(typename __node_base::pointer& __parent, const value_type& __v);
+        __find_leaf_low(typename __node_base::pointer& __parent, const key_type& __v);
     typename __node_base::pointer&
-        __find_leaf_high(typename __node_base::pointer& __parent, const value_type& __v);
+        __find_leaf_high(typename __node_base::pointer& __parent, const key_type& __v);
     typename __node_base::pointer&
         __find_leaf(const_iterator __hint,
-                    typename __node_base::pointer& __parent, const value_type& __v);
+                    typename __node_base::pointer& __parent, const key_type& __v);
     template <class _Key>
         typename __node_base::pointer&
         __find_equal(typename __node_base::pointer& __parent, const _Key& __v);
@@ -1067,11 +1345,11 @@
         __find_equal(const_iterator __hint, typename __node_base::pointer& __parent,
                      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;
@@ -1205,6 +1483,11 @@
 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();
@@ -1245,6 +1528,12 @@
 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();
@@ -1277,7 +1566,7 @@
         }
     }
     for (; __first != __last; ++__first)
-        __insert_multi(*__first);
+        __insert_multi(_NodeTypes::__get_value(*__first));
 }
 
 template <class _Tp, class _Compare, class _Allocator>
@@ -1401,7 +1690,7 @@
             }
         }
         while (__t.size() != 0)
-            __insert_multi(__e, _VSTD::move(__t.remove(__t.begin())->__value_));
+            __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_));
     }
 }
 
@@ -1436,7 +1725,7 @@
         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);
     }
 }
@@ -1483,7 +1772,7 @@
 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)
+                                                   const key_type& __v)
 {
     __node_pointer __nd = __root();
     if (__nd != nullptr)
@@ -1522,7 +1811,7 @@
 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)
+                                                    const key_type& __v)
 {
     __node_pointer __nd = __root();
     if (__nd != nullptr)
@@ -1565,7 +1854,7 @@
 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)
+                                               const key_type& __v)
 {
     if (__hint == end() || !value_comp()(*__hint, __v))  // check before
     {
@@ -1708,6 +1997,7 @@
     __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_);
@@ -1715,25 +2005,89 @@
     ++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
+{
+    __node_base_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
+{
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_equal(__p, __parent, __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;
@@ -1752,7 +2106,7 @@
 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;
@@ -1773,7 +2127,7 @@
 {
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
     __node_base_pointer __parent;
-    __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
+    __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()));
 }
@@ -1786,116 +2140,34 @@
 {
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
     __node_base_pointer __parent;
-    __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
+    __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>
-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>
-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 _VSTD::move(__h);  // explicitly moved for C++03
+    return _LIBCPP_EXPLICIT_MOVE(__h);  // explicitly moved for C++03
 }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif  // _LIBCPP_CXX03_LANG
 
-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);
-}
-
+#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);
+    __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());
@@ -1903,14 +2175,15 @@
 
 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);
+    __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>
@@ -1950,7 +2223,7 @@
 __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
 {
     __node_base_pointer __parent;
-    __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_);
+    __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);
 }
@@ -1961,7 +2234,7 @@
                                                        __node_pointer __nd)
 {
     __node_base_pointer __parent;
-    __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_);
+    __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);
 }
@@ -1979,7 +2252,8 @@
     __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;
 }
@@ -2044,17 +2318,17 @@
 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 __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_);
+            __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;
     }
@@ -2066,21 +2340,21 @@
 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();
+    __node_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_);
+            __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_), __rt),
+                __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)
             );
     }
     return 0;
@@ -2110,18 +2384,18 @@
 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,
+                                                 __node_pointer __result) const
 {
     while (__root != nullptr)
     {
         if (!value_comp()(__root->__value_, __v))
         {
             __result = __root;
-            __root = static_cast<__node_const_pointer>(__root->__left_);
+            __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);
 }
@@ -2150,18 +2424,18 @@
 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,
+                                                 __node_pointer __result) const
 {
     while (__root != nullptr)
     {
         if (value_comp()(__v, __root->__value_))
         {
             __result = __root;
-            __root = static_cast<__node_const_pointer>(__root->__left_);
+            __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);
 }
@@ -2201,22 +2475,22 @@
 __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();
+    __node_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_);
+            __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<__node_pointer>(__tree_min(__rt->__right_))
                             : __result));
     }
     return _Pp(const_iterator(__result), const_iterator(__result));
@@ -2254,20 +2528,20 @@
 __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();
+    __node_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_);
+            __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_), __rt),
+                      __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
     }
     return _Pp(const_iterator(__result), const_iterator(__result));
 }
diff --git a/include/__tuple b/include/__tuple
index 2837ce7..09c6839 100644
--- a/include/__tuple
+++ b/include/__tuple
@@ -86,12 +86,15 @@
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename tuple_element<_Ip, tuple<_Tp...> >::type&&
 get(tuple<_Tp...>&&) _NOEXCEPT;
+
+template <size_t _Ip, class ..._Tp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const typename tuple_element<_Ip, tuple<_Tp...> >::type&&
+get(const tuple<_Tp...>&&) _NOEXCEPT;
 #endif
 
 // pair specializations
 
-template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair;
-
 template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {};
 
 template <size_t _Ip, class _T1, class _T2>
@@ -109,6 +112,11 @@
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
 get(pair<_T1, _T2>&&) _NOEXCEPT;
+
+template <size_t _Ip, class _T1, class _T2>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
+get(const pair<_T1, _T2>&&) _NOEXCEPT;
 #endif
 
 // array specializations
@@ -132,35 +140,15 @@
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp&&
 get(array<_Tp, _Size>&&) _NOEXCEPT;
+
+template <size_t _Ip, class _Tp, size_t _Size>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Tp&&
+get(const array<_Tp, _Size>&&) _NOEXCEPT;
 #endif
 
 #if !defined(_LIBCPP_HAS_NO_VARIADICS)
 
-// __lazy_and
-
-template <bool _Last, class ..._Preds>
-struct __lazy_and_impl;
-
-template <class ..._Preds>
-struct __lazy_and_impl<false, _Preds...> : false_type {};
-
-template <>
-struct __lazy_and_impl<true> : true_type {};
-
-template <class _Pred>
-struct __lazy_and_impl<true, _Pred> : integral_constant<bool, _Pred::type::value> {};
-
-template <class _Hp, class ..._Tp>
-struct __lazy_and_impl<true, _Hp, _Tp...> : __lazy_and_impl<_Hp::type::value, _Tp...> {};
-
-template <class _P1, class ..._Pr>
-struct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {};
-
-// __lazy_not
-
-template <class _Pred>
-struct __lazy_not : integral_constant<bool, !_Pred::type::value> {};
-
 // __make_tuple_indices
 
 template <size_t...> struct __tuple_indices {};
diff --git a/include/algorithm b/include/algorithm
index c1635fc..7a6db7a 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -543,6 +543,12 @@
     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 @@
 #include <initializer_list>
 #include <type_traits>
 #include <cstring>
-#include <utility>
+#include <utility> // needed to provide swap_ranges.
 #include <memory>
 #include <iterator>
 #include <cstddef>
@@ -851,7 +857,7 @@
 {
     for (; __first != __last; ++__first)
         __f(*__first);
-    return _VSTD::move(__f);  // explicitly moved for (emulated) C++03
+    return _LIBCPP_EXPLICIT_MOVE(__f);  // explicitly moved for (emulated) C++03
 }
 
 // find
@@ -1415,20 +1421,20 @@
 // 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 @@
         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 @@
 }
 
 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 @@
         while (true)
         {
             if (__first1 == __s)
-                return __last1;
+                return make_pair(__last1, __last1);
             if (__pred(*__first1, *__first2))
                 break;
             ++__first1;
@@ -1505,7 +1512,7 @@
             if (__pred(*__first1, *__first2))
                 break;
         case 0:
-            return __last1;
+            return make_pair(__last1, __last1);
         }
     __phase2:
 #endif  // !_LIBCPP_UNROLL_LOOPS
@@ -1515,7 +1522,7 @@
          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 @@
             if (!__pred(*__m1, *__m2))
                 break;
         case 0:
-            return __first1;
+            return make_pair(__first1, __first1 + __len2);
         }
     __continue:
         ++__first1;
@@ -1571,8 +1578,9 @@
 {
     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 @@
 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>());
 }
 
@@ -1687,25 +1695,6 @@
 }
 
 // copy
-
-template <class _Iter>
-struct __libcpp_is_trivial_iterator
-{
-    static const bool value = is_pointer<_Iter>::value;
-};
-
-template <class _Iter>
-struct __libcpp_is_trivial_iterator<move_iterator<_Iter> >
-{
-    static const bool value = is_pointer<_Iter>::value;
-};
-
-template <class _Iter>
-struct __libcpp_is_trivial_iterator<__wrap_iter<_Iter> >
-{
-    static const bool value = is_pointer<_Iter>::value;
-};
-
 template <class _Iter>
 inline _LIBCPP_INLINE_VISIBILITY
 _Iter
@@ -2330,7 +2319,7 @@
     {
         if (__first == --__last)
             break;
-        swap(*__first, *__last);
+        _VSTD::iter_swap(__first, __last);
         ++__first;
     }
 }
@@ -2342,7 +2331,7 @@
 {
     if (__first != __last)
         for (; __first < --__last; ++__first)
-            swap(*__first, *__last);
+            _VSTD::iter_swap(__first, __last);
 }
 
 template <class _BidirectionalIterator>
@@ -2676,6 +2665,27 @@
 
 #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>
@@ -5744,34 +5754,6 @@
                                   __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 2e02a43..719286d5 100644
--- a/include/array
+++ b/include/array
@@ -34,7 +34,7 @@
 
     // 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;
@@ -89,12 +89,13 @@
   void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y)));
 
 template <class T> class tuple_size;
-template <int I, class T> class tuple_element;
+template <size_t I, class T> class tuple_element;
 template <class T, size_t N> struct tuple_size<array<T, N>>;
-template <int I, class T, size_t N> struct tuple_element<I, array<T, N>>;
-template <int I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14
-template <int I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14
-template <int I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14
+template <size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>;
+template <size_t I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14
+template <size_t I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14
+template <size_t I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14
+template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexcept; // constexpr in C++14
 
 }  // std
 
@@ -140,8 +141,15 @@
     _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
@@ -275,11 +283,12 @@
 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);
 }
@@ -324,6 +333,15 @@
     return _VSTD::move(__a.__elems_[_Ip]);
 }
 
+template <size_t _Ip, class _Tp, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Tp&&
+get(const array<_Tp, _Size>&& __a) _NOEXCEPT
+{
+    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array &&)");
+    return _VSTD::move(__a.__elems_[_Ip]);
+}
+
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/include/atomic b/include/atomic
index 97a998d..a0245eb 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 @@
 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 @@
 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 @@
 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;
@@ -535,25 +542,40 @@
 
 #ifdef _LIBCPP_HAS_NO_THREADS
 #error <atomic> is not supported on this single threaded system
-#else // !_LIBCPP_HAS_NO_THREADS
+#endif
+#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
+#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
 
-#if !__has_feature(cxx_atomic) && _GNUC_VER < 407
-#error <atomic> is not implemented
-#else
-
 typedef enum memory_order
 {
     memory_order_relaxed, memory_order_consume, memory_order_acquire,
     memory_order_release, memory_order_acq_rel, memory_order_seq_cst
 } memory_order;
 
-#if _GNUC_VER >= 407
+#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
 namespace __gcc_atomic {
 template <typename _Tp>
 struct __gcc_atomic_t {
-  __gcc_atomic_t() _NOEXCEPT {}
+
+#if _GNUC_VER >= 501
+    static_assert(is_trivially_copyable<_Tp>::value,
+      "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
+#endif
+
+  _LIBCPP_INLINE_VISIBILITY
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+    __gcc_atomic_t() _NOEXCEPT = default;
+#else
+    __gcc_atomic_t() _NOEXCEPT : __a_value() {}
+#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
   _LIBCPP_CONSTEXPR explicit __gcc_atomic_t(_Tp value) _NOEXCEPT
     : __a_value(value) {}
   _Tp __a_value;
@@ -574,7 +596,7 @@
       sizeof(__test_atomic_assignable<_Tp, _Td>(1)) == sizeof(char);
 };
 
-static inline constexpr int __to_gcc_order(memory_order __order) {
+static inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
   // Avoid switch statement to make this a constexpr.
   return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
          (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
@@ -584,7 +606,7 @@
               __ATOMIC_CONSUME))));
 }
 
-static inline constexpr int __to_gcc_failure_order(memory_order __order) {
+static inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
   // Avoid switch statement to make this a constexpr.
   return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
          (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
@@ -805,7 +827,7 @@
   return __atomic_fetch_xor(&__a->__a_value, __pattern,
                             __gcc_atomic::__to_gcc_order(__order));
 }
-#endif // _GNUC_VER >= 407
+#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP
 
 template <class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -815,6 +837,17 @@
     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>
@@ -822,10 +855,14 @@
 {
     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
     {
-#if __has_feature(cxx_atomic)
+#if defined(_LIBCPP_HAS_C_ATOMIC_IMP)
     return __c11_atomic_is_lock_free(sizeof(_Tp));
 #else
     return __atomic_is_lock_free(sizeof(_Tp), 0);
@@ -910,6 +947,11 @@
 #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>
@@ -1647,7 +1689,7 @@
 #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,23 +1821,6 @@
 #define ATOMIC_FLAG_INIT {false}
 #define ATOMIC_VAR_INIT(__v) {__v}
 
-// lock-free property
-
-#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
-
-#endif  //  !__has_feature(cxx_atomic)
-
 _LIBCPP_END_NAMESPACE_STD
 
-#endif  // !_LIBCPP_HAS_NO_THREADS
-
 #endif  // _LIBCPP_ATOMIC
diff --git a/include/bitset b/include/bitset
index 8c278cc..3f9b964 100644
--- a/include/bitset
+++ b/include/bitset
@@ -168,7 +168,9 @@
     typedef __bit_iterator<__bitset, false>            iterator;
     typedef __bit_iterator<__bitset, true>             const_iterator;
 
+    _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT
@@ -180,8 +182,11 @@
     _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT
         {return const_iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
 
+    _LIBCPP_INLINE_VISIBILITY
     void operator&=(const __bitset& __v) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     void operator|=(const __bitset& __v) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     void operator^=(const __bitset& __v) _NOEXCEPT;
 
     void flip() _NOEXCEPT;
@@ -192,22 +197,27 @@
 
     bool all() const _NOEXCEPT;
     bool any() const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     size_t __hash_code() const _NOEXCEPT;
 private:
 #ifdef _LIBCPP_HAS_NO_CONSTEXPR
     void __init(unsigned long long __v, false_type) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     void __init(unsigned long long __v, true_type) _NOEXCEPT;
 #endif  // _LIBCPP_HAS_NO_CONSTEXPR
     unsigned long to_ulong(false_type) const;
+    _LIBCPP_INLINE_VISIBILITY
     unsigned long to_ulong(true_type) const;
     unsigned long long to_ullong(false_type) const;
+    _LIBCPP_INLINE_VISIBILITY
     unsigned long long to_ullong(true_type) const;
+    _LIBCPP_INLINE_VISIBILITY
     unsigned long long to_ullong(true_type, false_type) const;
     unsigned long long to_ullong(true_type, true_type) const;
 };
 
 template <size_t _N_words, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _LIBCPP_CONSTEXPR
 __bitset<_N_words, _Size>::__bitset() _NOEXCEPT
 #ifndef _LIBCPP_HAS_NO_CONSTEXPR
@@ -245,7 +255,7 @@
 #endif  // _LIBCPP_HAS_NO_CONSTEXPR
 
 template <size_t _N_words, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _LIBCPP_CONSTEXPR
 __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
 #ifndef _LIBCPP_HAS_NO_CONSTEXPR
@@ -264,7 +274,7 @@
 }
 
 template <size_t _N_words, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 __bitset<_N_words, _Size>::operator&=(const __bitset& __v) _NOEXCEPT
 {
@@ -273,7 +283,7 @@
 }
 
 template <size_t _N_words, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 __bitset<_N_words, _Size>::operator|=(const __bitset& __v) _NOEXCEPT
 {
@@ -282,7 +292,7 @@
 }
 
 template <size_t _N_words, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 __bitset<_N_words, _Size>::operator^=(const __bitset& __v) _NOEXCEPT
 {
@@ -325,7 +335,7 @@
 }
 
 template <size_t _N_words, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 unsigned long
 __bitset<_N_words, _Size>::to_ulong(true_type) const
 {
@@ -348,7 +358,7 @@
 }
 
 template <size_t _N_words, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 unsigned long long
 __bitset<_N_words, _Size>::to_ullong(true_type) const
 {
@@ -356,7 +366,7 @@
 }
 
 template <size_t _N_words, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 unsigned long long
 __bitset<_N_words, _Size>::to_ullong(true_type, false_type) const
 {
@@ -414,7 +424,7 @@
 }
 
 template <size_t _N_words, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 size_t
 __bitset<_N_words, _Size>::__hash_code() const _NOEXCEPT
 {
@@ -450,7 +460,9 @@
     typedef __bit_iterator<__bitset, false>            iterator;
     typedef __bit_iterator<__bitset, true>             const_iterator;
 
+    _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT
@@ -462,23 +474,32 @@
     _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT
         {return const_iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
 
+    _LIBCPP_INLINE_VISIBILITY
     void operator&=(const __bitset& __v) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     void operator|=(const __bitset& __v) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     void operator^=(const __bitset& __v) _NOEXCEPT;
 
+    _LIBCPP_INLINE_VISIBILITY
     void flip() _NOEXCEPT;
 
+    _LIBCPP_INLINE_VISIBILITY
     unsigned long to_ulong() const;
+    _LIBCPP_INLINE_VISIBILITY
     unsigned long long to_ullong() const;
 
+    _LIBCPP_INLINE_VISIBILITY
     bool all() const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     bool any() const _NOEXCEPT;
 
+    _LIBCPP_INLINE_VISIBILITY
     size_t __hash_code() const _NOEXCEPT;
 };
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _LIBCPP_CONSTEXPR
 __bitset<1, _Size>::__bitset() _NOEXCEPT
     : __first_(0)
@@ -486,7 +507,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _LIBCPP_CONSTEXPR
 __bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
     : __first_(static_cast<__storage_type>(__v))
@@ -494,7 +515,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 __bitset<1, _Size>::operator&=(const __bitset& __v) _NOEXCEPT
 {
@@ -502,7 +523,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 __bitset<1, _Size>::operator|=(const __bitset& __v) _NOEXCEPT
 {
@@ -510,7 +531,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 __bitset<1, _Size>::operator^=(const __bitset& __v) _NOEXCEPT
 {
@@ -518,7 +539,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 __bitset<1, _Size>::flip() _NOEXCEPT
 {
@@ -528,7 +549,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 unsigned long
 __bitset<1, _Size>::to_ulong() const
 {
@@ -536,7 +557,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 unsigned long long
 __bitset<1, _Size>::to_ullong() const
 {
@@ -544,7 +565,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 __bitset<1, _Size>::all() const _NOEXCEPT
 {
@@ -553,7 +574,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 __bitset<1, _Size>::any() const _NOEXCEPT
 {
@@ -562,7 +583,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 size_t
 __bitset<1, _Size>::__hash_code() const _NOEXCEPT
 {
@@ -593,7 +614,9 @@
     typedef __bit_iterator<__bitset, false>            iterator;
     typedef __bit_iterator<__bitset, true>             const_iterator;
 
+    _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long) _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t) _NOEXCEPT
@@ -620,20 +643,20 @@
     _LIBCPP_INLINE_VISIBILITY size_t __hash_code() const _NOEXCEPT {return 0;}
 };
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _LIBCPP_CONSTEXPR
 __bitset<0, 0>::__bitset() _NOEXCEPT
 {
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _LIBCPP_CONSTEXPR
 __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
@@ -663,16 +686,23 @@
                         _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));
 
     // 23.3.5.2 bitset operations:
+    _LIBCPP_INLINE_VISIBILITY
     bitset& operator&=(const bitset& __rhs) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     bitset& operator|=(const bitset& __rhs) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     bitset& operator^=(const bitset& __rhs) _NOEXCEPT;
     bitset& operator<<=(size_t __pos) _NOEXCEPT;
     bitset& operator>>=(size_t __pos) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     bitset& set() _NOEXCEPT;
     bitset& set(size_t __pos, bool __val = true);
+    _LIBCPP_INLINE_VISIBILITY
     bitset& reset() _NOEXCEPT;
     bitset& reset(size_t __pos);
+    _LIBCPP_INLINE_VISIBILITY
     bitset  operator~() const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     bitset& flip() _NOEXCEPT;
     bitset& flip(size_t __pos);
 
@@ -680,28 +710,40 @@
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
                               const_reference operator[](size_t __p) const {return base::__make_ref(__p);}
     _LIBCPP_INLINE_VISIBILITY       reference operator[](size_t __p)       {return base::__make_ref(__p);}
+    _LIBCPP_INLINE_VISIBILITY
     unsigned long to_ulong() const;
+    _LIBCPP_INLINE_VISIBILITY
     unsigned long long to_ullong() const;
     template <class _CharT, class _Traits, class _Allocator>
         basic_string<_CharT, _Traits, _Allocator> to_string(_CharT __zero = _CharT('0'),
                                                             _CharT __one = _CharT('1')) const;
     template <class _CharT, class _Traits>
+        _LIBCPP_INLINE_VISIBILITY
         basic_string<_CharT, _Traits, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'),
                                                                     _CharT __one = _CharT('1')) const;
     template <class _CharT>
+        _LIBCPP_INLINE_VISIBILITY
         basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'),
                                                                                 _CharT __one = _CharT('1')) const;
+    _LIBCPP_INLINE_VISIBILITY
     basic_string<char, char_traits<char>, allocator<char> > to_string(char __zero = '0',
                                                                       char __one = '1') const;
+    _LIBCPP_INLINE_VISIBILITY
     size_t count() const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT {return _Size;}
+    _LIBCPP_INLINE_VISIBILITY
     bool operator==(const bitset& __rhs) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     bool operator!=(const bitset& __rhs) const _NOEXCEPT;
     bool test(size_t __pos) const;
+    _LIBCPP_INLINE_VISIBILITY
     bool all() const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     bool any() const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY bool none() const _NOEXCEPT {return !any();}
+    _LIBCPP_INLINE_VISIBILITY
     bitset operator<<(size_t __pos) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     bitset operator>>(size_t __pos) const _NOEXCEPT;
 
 private:
@@ -774,7 +816,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bitset<_Size>&
 bitset<_Size>::operator&=(const bitset& __rhs) _NOEXCEPT
 {
@@ -783,7 +825,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bitset<_Size>&
 bitset<_Size>::operator|=(const bitset& __rhs) _NOEXCEPT
 {
@@ -792,7 +834,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bitset<_Size>&
 bitset<_Size>::operator^=(const bitset& __rhs) _NOEXCEPT
 {
@@ -821,7 +863,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bitset<_Size>&
 bitset<_Size>::set() _NOEXCEPT
 {
@@ -844,7 +886,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bitset<_Size>&
 bitset<_Size>::reset() _NOEXCEPT
 {
@@ -867,7 +909,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bitset<_Size>
 bitset<_Size>::operator~() const _NOEXCEPT
 {
@@ -877,7 +919,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bitset<_Size>&
 bitset<_Size>::flip() _NOEXCEPT
 {
@@ -901,7 +943,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 unsigned long
 bitset<_Size>::to_ulong() const
 {
@@ -909,7 +951,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 unsigned long long
 bitset<_Size>::to_ullong() const
 {
@@ -932,7 +974,7 @@
 
 template <size_t _Size>
 template <class _CharT, class _Traits>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 basic_string<_CharT, _Traits, allocator<_CharT> >
 bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
 {
@@ -941,7 +983,7 @@
 
 template <size_t _Size>
 template <class _CharT>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> >
 bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
 {
@@ -949,7 +991,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 basic_string<char, char_traits<char>, allocator<char> >
 bitset<_Size>::to_string(char __zero, char __one) const
 {
@@ -957,7 +999,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 size_t
 bitset<_Size>::count() const _NOEXCEPT
 {
@@ -965,7 +1007,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 bitset<_Size>::operator==(const bitset& __rhs) const _NOEXCEPT
 {
@@ -973,7 +1015,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 bitset<_Size>::operator!=(const bitset& __rhs) const _NOEXCEPT
 {
@@ -994,7 +1036,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 bitset<_Size>::all() const _NOEXCEPT
 {
@@ -1002,7 +1044,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 bitset<_Size>::any() const _NOEXCEPT
 {
@@ -1010,7 +1052,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bitset<_Size>
 bitset<_Size>::operator<<(size_t __pos) const _NOEXCEPT
 {
@@ -1020,7 +1062,7 @@
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bitset<_Size>
 bitset<_Size>::operator>>(size_t __pos) const _NOEXCEPT
 {
diff --git a/include/cctype b/include/cctype
index 26c740f..7fc8134 100644
--- a/include/cctype
+++ b/include/cctype
@@ -37,10 +37,6 @@
 
 #include <__config>
 #include <ctype.h>
-#if defined(_LIBCPP_MSVCRT)
-#include "support/win32/support.h"
-#include "support/win32/locale_win32.h"
-#endif // _LIBCPP_MSVCRT
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -49,116 +45,76 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 #ifdef isalnum
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isalnum(int __c) {return isalnum(__c);}
 #undef isalnum
-inline _LIBCPP_INLINE_VISIBILITY int isalnum(int __c) {return __libcpp_isalnum(__c);}
-#else  // isalnum
-using ::isalnum;
-#endif  // isalnum
+#endif
 
 #ifdef isalpha
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isalpha(int __c) {return isalpha(__c);}
 #undef isalpha
-inline _LIBCPP_INLINE_VISIBILITY int isalpha(int __c) {return __libcpp_isalpha(__c);}
-#else  // isalpha
-using ::isalpha;
-#endif  // isalpha
+#endif
 
 #ifdef isblank
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isblank(int __c) {return isblank(__c);}
 #undef isblank
-inline _LIBCPP_INLINE_VISIBILITY int isblank(int __c) {return __libcpp_isblank(__c);}
-#else  // isblank
-using ::isblank;
-#endif  // isblank
+#endif
 
 #ifdef iscntrl
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iscntrl(int __c) {return iscntrl(__c);}
 #undef iscntrl
-inline _LIBCPP_INLINE_VISIBILITY int iscntrl(int __c) {return __libcpp_iscntrl(__c);}
-#else  // iscntrl
-using ::iscntrl;
-#endif  // iscntrl
+#endif
 
 #ifdef isdigit
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isdigit(int __c) {return isdigit(__c);}
 #undef isdigit
-inline _LIBCPP_INLINE_VISIBILITY int isdigit(int __c) {return __libcpp_isdigit(__c);}
-#else  // isdigit
-using ::isdigit;
-#endif  // isdigit
+#endif
 
 #ifdef isgraph
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isgraph(int __c) {return isgraph(__c);}
 #undef isgraph
-inline _LIBCPP_INLINE_VISIBILITY int isgraph(int __c) {return __libcpp_isgraph(__c);}
-#else  // isgraph
-using ::isgraph;
-#endif  // isgraph
+#endif
 
 #ifdef islower
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_islower(int __c) {return islower(__c);}
 #undef islower
-inline _LIBCPP_INLINE_VISIBILITY int islower(int __c) {return __libcpp_islower(__c);}
-#else  // islower
-using ::islower;
-#endif  // islower
+#endif
 
 #ifdef isprint
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isprint(int __c) {return isprint(__c);}
 #undef isprint
-inline _LIBCPP_INLINE_VISIBILITY int isprint(int __c) {return __libcpp_isprint(__c);}
-#else  // isprint
-using ::isprint;
-#endif  // isprint
+#endif
 
 #ifdef ispunct
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_ispunct(int __c) {return ispunct(__c);}
 #undef ispunct
-inline _LIBCPP_INLINE_VISIBILITY int ispunct(int __c) {return __libcpp_ispunct(__c);}
-#else  // ispunct
-using ::ispunct;
-#endif  // ispunct
+#endif
 
 #ifdef isspace
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isspace(int __c) {return isspace(__c);}
 #undef isspace
-inline _LIBCPP_INLINE_VISIBILITY int isspace(int __c) {return __libcpp_isspace(__c);}
-#else  // isspace
-using ::isspace;
-#endif  // isspace
+#endif
 
 #ifdef isupper
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isupper(int __c) {return isupper(__c);}
 #undef isupper
-inline _LIBCPP_INLINE_VISIBILITY int isupper(int __c) {return __libcpp_isupper(__c);}
-#else  // isupper
-using ::isupper;
-#endif  // isupper
+#endif
 
 #ifdef isxdigit
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isxdigit(int __c) {return isxdigit(__c);}
 #undef isxdigit
-inline _LIBCPP_INLINE_VISIBILITY int isxdigit(int __c) {return __libcpp_isxdigit(__c);}
-#else  // isxdigit
-using ::isxdigit;
-#endif  // isxdigit
+#endif
 
 #ifdef tolower
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_tolower(int __c) {return tolower(__c);}
 #undef tolower
-inline _LIBCPP_INLINE_VISIBILITY int tolower(int __c) {return __libcpp_tolower(__c);}
-#else  // tolower
-using ::tolower;
-#endif  // tolower
+#endif
 
 #ifdef toupper
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_toupper(int __c) {return toupper(__c);}
 #undef toupper
-inline _LIBCPP_INLINE_VISIBILITY int toupper(int __c) {return __libcpp_toupper(__c);}
-#else  // toupper
+#endif
+
+
+using ::isalnum;
+using ::isalpha;
+using ::isblank;
+using ::iscntrl;
+using ::isdigit;
+using ::isgraph;
+using ::islower;
+using ::isprint;
+using ::ispunct;
+using ::isspace;
+using ::isupper;
+using ::isxdigit;
+using ::tolower;
 using ::toupper;
-#endif  // toupper
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/include/cerrno b/include/cerrno
index 9804e4e..bab13b8 100644
--- a/include/cerrno
+++ b/include/cerrno
@@ -30,364 +30,4 @@
 #pragma GCC system_header
 #endif
 
-#if !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)
-
-#ifdef ELAST
-
-const int __elast1 = ELAST+1;
-const int __elast2 = ELAST+2;
-
-#else
-
-const int __elast1 = 104;
-const int __elast2 = 105;
-
-#endif
-
-#ifdef ENOTRECOVERABLE
-
-#define EOWNERDEAD __elast1
-
-#ifdef ELAST
-#undef ELAST
-#define ELAST EOWNERDEAD
-#endif
-
-#elif defined(EOWNERDEAD)
-
-#define ENOTRECOVERABLE __elast1
-#ifdef ELAST
-#undef ELAST
-#define ELAST ENOTRECOVERABLE
-#endif
-
-#else  // defined(EOWNERDEAD)
-
-#define EOWNERDEAD __elast1
-#define ENOTRECOVERABLE __elast2
-#ifdef ELAST
-#undef ELAST
-#define ELAST ENOTRECOVERABLE
-#endif
-
-#endif  // defined(EOWNERDEAD)
-
-#endif  // !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)
-
-//  supply errno values likely to be missing, particularly on Windows
-
-#ifndef EAFNOSUPPORT
-#define EAFNOSUPPORT 9901
-#endif
-
-#ifndef EADDRINUSE
-#define EADDRINUSE 9902
-#endif
-
-#ifndef EADDRNOTAVAIL
-#define EADDRNOTAVAIL 9903
-#endif
-
-#ifndef EISCONN
-#define EISCONN 9904
-#endif
-
-#ifndef EBADMSG
-#define EBADMSG 9905
-#endif
-
-#ifndef ECONNABORTED
-#define ECONNABORTED 9906
-#endif
-
-#ifndef EALREADY
-#define EALREADY 9907
-#endif
-
-#ifndef ECONNREFUSED
-#define ECONNREFUSED 9908
-#endif
-
-#ifndef ECONNRESET
-#define ECONNRESET 9909
-#endif
-
-#ifndef EDESTADDRREQ
-#define EDESTADDRREQ 9910
-#endif
-
-#ifndef EHOSTUNREACH
-#define EHOSTUNREACH 9911
-#endif
-
-#ifndef EIDRM
-#define EIDRM 9912
-#endif
-
-#ifndef EMSGSIZE
-#define EMSGSIZE 9913
-#endif
-
-#ifndef ENETDOWN
-#define ENETDOWN 9914
-#endif
-
-#ifndef ENETRESET
-#define ENETRESET 9915
-#endif
-
-#ifndef ENETUNREACH
-#define ENETUNREACH 9916
-#endif
-
-#ifndef ENOBUFS
-#define ENOBUFS 9917
-#endif
-
-#ifndef ENOLINK
-#define ENOLINK 9918
-#endif
-
-#ifndef ENODATA
-#define ENODATA 9919
-#endif
-
-#ifndef ENOMSG
-#define ENOMSG 9920
-#endif
-
-#ifndef ENOPROTOOPT
-#define ENOPROTOOPT 9921
-#endif
-
-#ifndef ENOSR
-#define ENOSR 9922
-#endif
-
-#ifndef ENOTSOCK
-#define ENOTSOCK 9923
-#endif
-
-#ifndef ENOSTR
-#define ENOSTR 9924
-#endif
-
-#ifndef ENOTCONN
-#define ENOTCONN 9925
-#endif
-
-#ifndef ENOTSUP
-#define ENOTSUP 9926
-#endif
-
-#ifndef ECANCELED
-#define ECANCELED 9927
-#endif
-
-#ifndef EINPROGRESS
-#define EINPROGRESS 9928
-#endif
-
-#ifndef EOPNOTSUPP
-#define EOPNOTSUPP 9929
-#endif
-
-#ifndef EWOULDBLOCK
-#define EWOULDBLOCK 9930
-#endif
-
-#ifndef EOWNERDEAD
-#define EOWNERDEAD  9931
-#endif
-
-#ifndef EPROTO
-#define EPROTO 9932
-#endif
-
-#ifndef EPROTONOSUPPORT
-#define EPROTONOSUPPORT 9933
-#endif
-
-#ifndef ENOTRECOVERABLE
-#define ENOTRECOVERABLE 9934
-#endif
-
-#ifndef ETIME
-#define ETIME 9935
-#endif
-
-#ifndef ETXTBSY
-#define ETXTBSY 9936
-#endif
-
-#ifndef ETIMEDOUT
-#define ETIMEDOUT 9938
-#endif
-
-#ifndef ELOOP
-#define ELOOP 9939
-#endif
-
-#ifndef EOVERFLOW
-#define EOVERFLOW 9940
-#endif
-
-#ifndef EPROTOTYPE
-#define EPROTOTYPE 9941
-#endif
-
-#ifndef ENOSYS
-#define ENOSYS 9942
-#endif
-
-#ifndef EINVAL
-#define EINVAL 9943
-#endif
-
-#ifndef ERANGE
-#define ERANGE 9944
-#endif
-
-#ifndef EILSEQ
-#define EILSEQ 9945
-#endif
-
-//  Windows Mobile doesn't appear to define these:
-
-#ifndef E2BIG
-#define E2BIG 9946
-#endif
-
-#ifndef EDOM
-#define EDOM 9947
-#endif
-
-#ifndef EFAULT
-#define EFAULT 9948
-#endif
-
-#ifndef EBADF
-#define EBADF 9949
-#endif
-
-#ifndef EPIPE
-#define EPIPE 9950
-#endif
-
-#ifndef EXDEV
-#define EXDEV 9951
-#endif
-
-#ifndef EBUSY
-#define EBUSY 9952
-#endif
-
-#ifndef ENOTEMPTY
-#define ENOTEMPTY 9953
-#endif
-
-#ifndef ENOEXEC
-#define ENOEXEC 9954
-#endif
-
-#ifndef EEXIST
-#define EEXIST 9955
-#endif
-
-#ifndef EFBIG
-#define EFBIG 9956
-#endif
-
-#ifndef ENAMETOOLONG
-#define ENAMETOOLONG 9957
-#endif
-
-#ifndef ENOTTY
-#define ENOTTY 9958
-#endif
-
-#ifndef EINTR
-#define EINTR 9959
-#endif
-
-#ifndef ESPIPE
-#define ESPIPE 9960
-#endif
-
-#ifndef EIO
-#define EIO 9961
-#endif
-
-#ifndef EISDIR
-#define EISDIR 9962
-#endif
-
-#ifndef ECHILD
-#define ECHILD 9963
-#endif
-
-#ifndef ENOLCK
-#define ENOLCK 9964
-#endif
-
-#ifndef ENOSPC
-#define ENOSPC 9965
-#endif
-
-#ifndef ENXIO
-#define ENXIO 9966
-#endif
-
-#ifndef ENODEV
-#define ENODEV 9967
-#endif
-
-#ifndef ENOENT
-#define ENOENT 9968
-#endif
-
-#ifndef ESRCH
-#define ESRCH 9969
-#endif
-
-#ifndef ENOTDIR
-#define ENOTDIR 9970
-#endif
-
-#ifndef ENOMEM
-#define ENOMEM 9971
-#endif
-
-#ifndef EPERM
-#define EPERM 9972
-#endif
-
-#ifndef EACCES
-#define EACCES 9973
-#endif
-
-#ifndef EROFS
-#define EROFS 9974
-#endif
-
-#ifndef EDEADLK
-#define EDEADLK 9975
-#endif
-
-#ifndef EAGAIN
-#define EAGAIN 9976
-#endif
-
-#ifndef ENFILE
-#define ENFILE 9977
-#endif
-
-#ifndef EMFILE
-#define EMFILE 9978
-#endif
-
-#ifndef EMLINK
-#define EMLINK 9979
-#endif
-
 #endif  // _LIBCPP_CERRNO
diff --git a/include/cfenv b/include/cfenv
index dd7db37..4fc6304 100644
--- a/include/cfenv
+++ b/include/cfenv
@@ -1,5 +1,5 @@
 // -*- C++ -*-
-//===---------------------------- cctype ----------------------------------===//
+//===---------------------------- cfenv -----------------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
diff --git a/include/cfloat b/include/cfloat
index 5fa5655..176fa9d 100644
--- a/include/cfloat
+++ b/include/cfloat
@@ -67,12 +67,4 @@
 #pragma GCC system_header
 #endif
 
-#ifndef FLT_EVAL_METHOD
-#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
-#endif
-
-#ifndef DECIMAL_DIG
-#define DECIMAL_DIG __DECIMAL_DIG__
-#endif
-
 #endif  // _LIBCPP_CFLOAT
diff --git a/include/chrono b/include/chrono
index 9229234..68484e9 100644
--- a/include/chrono
+++ b/include/chrono
@@ -26,6 +26,9 @@
 
 template <class Rep> struct treat_as_floating_point : is_floating_point<Rep> {};
 
+template <class Rep> constexpr bool treat_as_floating_point_v
+    = treat_as_floating_point<Rep>::value;                       // C++17
+
 template <class Rep>
 struct duration_values
 {
@@ -194,6 +197,13 @@
 template <class ToDuration, class Rep, class Period>
   ToDuration duration_cast(const duration<Rep, Period>& d);
 
+template <class ToDuration, class Rep, class Period>
+    constexpr ToDuration floor(const duration<Rep, Period>& d);    // C++17
+template <class ToDuration, class Rep, class Period>
+    constexpr ToDuration ceil(const duration<Rep, Period>& d);     // C++17
+template <class ToDuration, class Rep, class Period>
+    constexpr ToDuration round(const duration<Rep, Period>& d);    // C++17
+
 // time_point arithmetic (all constexpr in C++14)
 template <class Clock, class Duration1, class Rep2, class Period2>
   time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>
@@ -227,6 +237,20 @@
 template <class ToDuration, class Clock, class Duration>
   time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);
 
+template <class ToDuration, class Clock, class Duration>
+    constexpr time_point<Clock, ToDuration>
+    floor(const time_point<Clock, Duration>& tp);                  // C++17
+
+template <class ToDuration, class Clock, class Duration>
+    constexpr time_point<Clock, ToDuration>
+    ceil(const time_point<Clock, Duration>& tp);                   // C++17
+
+template <class ToDuration, class Clock, class Duration>
+    constexpr time_point<Clock, ToDuration>
+    round(const time_point<Clock, Duration>& tp);                  // C++17
+
+template <class Rep, class Period>
+    constexpr duration<Rep, Period> abs(duration<Rep, Period> d);  // C++17
 // Clocks
 
 class system_clock
@@ -392,6 +416,11 @@
 template <class _Rep>
 struct _LIBCPP_TYPE_VIS_ONLY treat_as_floating_point : is_floating_point<_Rep> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Rep> _LIBCPP_CONSTEXPR bool treat_as_floating_point_v
+    = treat_as_floating_point<_Rep>::value;
+#endif
+
 template <class _Rep>
 struct _LIBCPP_TYPE_VIS_ONLY duration_values
 {
@@ -401,6 +430,58 @@
     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min()  {return numeric_limits<_Rep>::lowest();}
 };
 
+#if _LIBCPP_STD_VER > 14
+template <class _ToDuration, class _Rep, class _Period>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+typename enable_if
+<
+    __is_duration<_ToDuration>::value,
+    _ToDuration
+>::type
+floor(const duration<_Rep, _Period>& __d)
+{
+    _ToDuration __t = duration_cast<_ToDuration>(__d);
+    if (__t > __d)
+        __t = __t - _ToDuration{1};
+    return __t;
+}
+
+template <class _ToDuration, class _Rep, class _Period>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+typename enable_if
+<
+    __is_duration<_ToDuration>::value,
+    _ToDuration
+>::type
+ceil(const duration<_Rep, _Period>& __d)
+{
+    _ToDuration __t = duration_cast<_ToDuration>(__d);
+    if (__t < __d)
+        __t = __t + _ToDuration{1};
+    return __t;
+}
+
+template <class _ToDuration, class _Rep, class _Period>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+typename enable_if
+<
+    __is_duration<_ToDuration>::value,
+    _ToDuration
+>::type
+round(const duration<_Rep, _Period>& __d)
+{
+    _ToDuration __lower = floor<_ToDuration>(__d);
+    _ToDuration __upper = __lower + _ToDuration{1};
+    auto __lowerDiff = __d - __lower;
+    auto __upperDiff = __upper - __d;
+    if (__lowerDiff < __upperDiff)
+        return __lower;
+    if (__lowerDiff > __upperDiff)
+        return __upper;
+    return __lower.count() & 1 ? __upper : __lower;
+}
+#endif
+
 // duration
 
 template <class _Rep, class _Period>
@@ -807,6 +888,56 @@
     return time_point<_Clock, _ToDuration>(_VSTD::chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
 }
 
+#if _LIBCPP_STD_VER > 14
+template <class _ToDuration, class _Clock, class _Duration>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+typename enable_if
+<
+    __is_duration<_ToDuration>::value,
+    time_point<_Clock, _ToDuration>
+>::type
+floor(const time_point<_Clock, _Duration>& __t)
+{
+    return time_point<_Clock, _ToDuration>{floor<_ToDuration>(__t.time_since_epoch())};
+}
+
+template <class _ToDuration, class _Clock, class _Duration>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+typename enable_if
+<
+    __is_duration<_ToDuration>::value,
+    time_point<_Clock, _ToDuration>
+>::type
+ceil(const time_point<_Clock, _Duration>& __t)
+{
+    return time_point<_Clock, _ToDuration>{ceil<_ToDuration>(__t.time_since_epoch())};
+}
+
+template <class _ToDuration, class _Clock, class _Duration>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+typename enable_if
+<
+    __is_duration<_ToDuration>::value,
+    time_point<_Clock, _ToDuration>
+>::type
+round(const time_point<_Clock, _Duration>& __t)
+{
+    return time_point<_Clock, _ToDuration>{round<_ToDuration>(__t.time_since_epoch())};
+}
+
+template <class _Rep, class _Period>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+typename enable_if
+<
+    numeric_limits<_Rep>::is_signed,
+    duration<_Rep, _Period>
+>::type
+abs(duration<_Rep, _Period> __d)
+{
+    return __d >= __d.zero() ? __d : -__d;
+}
+#endif
+
 // time_point ==
 
 template <class _Clock, class _Duration1, class _Duration2>
diff --git a/include/cinttypes b/include/cinttypes
index cfd763c..3f61b06 100644
--- a/include/cinttypes
+++ b/include/cinttypes
@@ -246,10 +246,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 using::imaxdiv_t;
-
-#undef imaxabs
 using::imaxabs;
-#undef imaxdiv
 using::imaxdiv;
 using::strtoimax;
 using::strtoumax;
diff --git a/include/cmath b/include/cmath
index 5f9aaed..b3e9594 100644
--- a/include/cmath
+++ b/include/cmath
@@ -209,6 +209,10 @@
 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);
@@ -299,340 +303,11 @@
 
 #include <__config>
 #include <math.h>
-#include <type_traits>
-
-#ifdef _LIBCPP_MSVCRT
-#include "support/win32/math_win32.h"
-#endif
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
 
-// signbit
-
-#ifdef signbit
-
-template <class _A1>
-_LIBCPP_ALWAYS_INLINE
-bool
-__libcpp_signbit(_A1 __lcpp_x) _NOEXCEPT
-{
-    return signbit(__lcpp_x);
-}
-
-#undef signbit
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
-signbit(_A1 __lcpp_x) _NOEXCEPT
-{
-    return __libcpp_signbit((typename std::__promote<_A1>::type)__lcpp_x);
-}
-
-#endif  // signbit
-
-// fpclassify
-
-#ifdef fpclassify
-
-template <class _A1>
-_LIBCPP_ALWAYS_INLINE
-int
-__libcpp_fpclassify(_A1 __lcpp_x) _NOEXCEPT
-{
-    return fpclassify(__lcpp_x);
-}
-
-#undef fpclassify
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename std::enable_if<std::is_arithmetic<_A1>::value, int>::type
-fpclassify(_A1 __lcpp_x) _NOEXCEPT
-{
-    return __libcpp_fpclassify((typename std::__promote<_A1>::type)__lcpp_x);
-}
-
-#endif  // fpclassify
-
-// isfinite
-
-#ifdef isfinite
-
-template <class _A1>
-_LIBCPP_ALWAYS_INLINE
-bool
-__libcpp_isfinite(_A1 __lcpp_x) _NOEXCEPT
-{
-    return isfinite(__lcpp_x);
-}
-
-#undef isfinite
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
-isfinite(_A1 __lcpp_x) _NOEXCEPT
-{
-    return __libcpp_isfinite((typename std::__promote<_A1>::type)__lcpp_x);
-}
-
-#endif  // isfinite
-
-// isinf
-
-#ifdef isinf
-
-template <class _A1>
-_LIBCPP_ALWAYS_INLINE
-bool
-__libcpp_isinf(_A1 __lcpp_x) _NOEXCEPT
-{
-    return isinf(__lcpp_x);
-}
-
-#undef isinf
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
-isinf(_A1 __lcpp_x) _NOEXCEPT
-{
-    return __libcpp_isinf((typename std::__promote<_A1>::type)__lcpp_x);
-}
-
-#endif  // isinf
-
-// isnan
-
-#ifdef isnan
-
-template <class _A1>
-_LIBCPP_ALWAYS_INLINE
-bool
-__libcpp_isnan(_A1 __lcpp_x) _NOEXCEPT
-{
-    return isnan(__lcpp_x);
-}
-
-#undef isnan
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
-isnan(_A1 __lcpp_x) _NOEXCEPT
-{
-    return __libcpp_isnan((typename std::__promote<_A1>::type)__lcpp_x);
-}
-
-#endif  // isnan
-
-// isnormal
-
-#ifdef isnormal
-
-template <class _A1>
-_LIBCPP_ALWAYS_INLINE
-bool
-__libcpp_isnormal(_A1 __lcpp_x) _NOEXCEPT
-{
-    return isnormal(__lcpp_x);
-}
-
-#undef isnormal
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
-isnormal(_A1 __lcpp_x) _NOEXCEPT
-{
-    return __libcpp_isnormal((typename std::__promote<_A1>::type)__lcpp_x);
-}
-
-#endif  // isnormal
-
-// isgreater
-
-#ifdef isgreater
-
-template <class _A1, class _A2>
-_LIBCPP_ALWAYS_INLINE
-bool
-__libcpp_isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    return isgreater(__lcpp_x, __lcpp_y);
-}
-
-#undef isgreater
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename std::enable_if
-<
-    std::is_arithmetic<_A1>::value &&
-    std::is_arithmetic<_A2>::value,
-    bool
->::type
-isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename std::__promote<_A1, _A2>::type type;
-    return __libcpp_isgreater((type)__lcpp_x, (type)__lcpp_y);
-}
-
-#endif  // isgreater
-
-// isgreaterequal
-
-#ifdef isgreaterequal
-
-template <class _A1, class _A2>
-_LIBCPP_ALWAYS_INLINE
-bool
-__libcpp_isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    return isgreaterequal(__lcpp_x, __lcpp_y);
-}
-
-#undef isgreaterequal
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename std::enable_if
-<
-    std::is_arithmetic<_A1>::value &&
-    std::is_arithmetic<_A2>::value,
-    bool
->::type
-isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename std::__promote<_A1, _A2>::type type;
-    return __libcpp_isgreaterequal((type)__lcpp_x, (type)__lcpp_y);
-}
-
-#endif  // isgreaterequal
-
-// isless
-
-#ifdef isless
-
-template <class _A1, class _A2>
-_LIBCPP_ALWAYS_INLINE
-bool
-__libcpp_isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    return isless(__lcpp_x, __lcpp_y);
-}
-
-#undef isless
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename std::enable_if
-<
-    std::is_arithmetic<_A1>::value &&
-    std::is_arithmetic<_A2>::value,
-    bool
->::type
-isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename std::__promote<_A1, _A2>::type type;
-    return __libcpp_isless((type)__lcpp_x, (type)__lcpp_y);
-}
-
-#endif  // isless
-
-// islessequal
-
-#ifdef islessequal
-
-template <class _A1, class _A2>
-_LIBCPP_ALWAYS_INLINE
-bool
-__libcpp_islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    return islessequal(__lcpp_x, __lcpp_y);
-}
-
-#undef islessequal
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename std::enable_if
-<
-    std::is_arithmetic<_A1>::value &&
-    std::is_arithmetic<_A2>::value,
-    bool
->::type
-islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename std::__promote<_A1, _A2>::type type;
-    return __libcpp_islessequal((type)__lcpp_x, (type)__lcpp_y);
-}
-
-#endif  // islessequal
-
-// islessgreater
-
-#ifdef islessgreater
-
-template <class _A1, class _A2>
-_LIBCPP_ALWAYS_INLINE
-bool
-__libcpp_islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    return islessgreater(__lcpp_x, __lcpp_y);
-}
-
-#undef islessgreater
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename std::enable_if
-<
-    std::is_arithmetic<_A1>::value &&
-    std::is_arithmetic<_A2>::value,
-    bool
->::type
-islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename std::__promote<_A1, _A2>::type type;
-    return __libcpp_islessgreater((type)__lcpp_x, (type)__lcpp_y);
-}
-
-#endif  // islessgreater
-
-// isunordered
-
-#ifdef isunordered
-
-template <class _A1, class _A2>
-_LIBCPP_ALWAYS_INLINE
-bool
-__libcpp_isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    return isunordered(__lcpp_x, __lcpp_y);
-}
-
-#undef isunordered
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename std::enable_if
-<
-    std::is_arithmetic<_A1>::value &&
-    std::is_arithmetic<_A2>::value,
-    bool
->::type
-isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename std::__promote<_A1, _A2>::type type;
-    return __libcpp_isunordered((type)__lcpp_x, (type)__lcpp_y);
-}
-
-#endif  // isunordered
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 using ::signbit;
@@ -652,794 +327,130 @@
 using ::float_t;
 using ::double_t;
 
-// abs
-
-#if defined(__sun__)
+#ifndef _AIX
 using ::abs;
 #endif
 
-#if !defined(_AIX) && !defined(__sun__)
-inline _LIBCPP_INLINE_VISIBILITY
-float
-abs(float __lcpp_x) _NOEXCEPT {return fabsf(__lcpp_x);}
-
-inline _LIBCPP_INLINE_VISIBILITY
-double
-abs(double __lcpp_x) _NOEXCEPT {return fabs(__lcpp_x);}
-
-inline _LIBCPP_INLINE_VISIBILITY
-long double
-abs(long double __lcpp_x) _NOEXCEPT {return fabsl(__lcpp_x);}
-#endif // !defined(_AIX)
-
 #ifndef __sun__
-
-// acos
-
 using ::acos;
 using ::acosf;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       acos(float __lcpp_x) _NOEXCEPT       {return acosf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double acos(long double __lcpp_x) _NOEXCEPT {return acosl(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-acos(_A1 __lcpp_x) _NOEXCEPT {return acos((double)__lcpp_x);}
-
-// asin
-
 using ::asin;
 using ::asinf;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       asin(float __lcpp_x) _NOEXCEPT       {return asinf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double asin(long double __lcpp_x) _NOEXCEPT {return asinl(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-asin(_A1 __lcpp_x) _NOEXCEPT {return asin((double)__lcpp_x);}
-
-// atan
-
 using ::atan;
 using ::atanf;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       atan(float __lcpp_x) _NOEXCEPT       {return atanf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double atan(long double __lcpp_x) _NOEXCEPT {return atanl(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-atan(_A1 __lcpp_x) _NOEXCEPT {return atan((double)__lcpp_x);}
-
-// atan2
-
 using ::atan2;
 using ::atan2f;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       atan2(float __lcpp_y, float __lcpp_x) _NOEXCEPT             {return atan2f(__lcpp_y, __lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double atan2(long double __lcpp_y, long double __lcpp_x) _NOEXCEPT {return atan2l(__lcpp_y, __lcpp_x);}
-#endif
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __lazy_enable_if
-<
-    is_arithmetic<_A1>::value &&
-    is_arithmetic<_A2>::value,
-    __promote<_A1, _A2>
->::type
-atan2(_A1 __lcpp_y, _A2 __lcpp_x) _NOEXCEPT
-{
-    typedef typename __promote<_A1, _A2>::type __result_type;
-    static_assert((!(is_same<_A1, __result_type>::value &&
-                      is_same<_A2, __result_type>::value)), "");
-    return atan2((__result_type)__lcpp_y, (__result_type)__lcpp_x);
-}
-
-// ceil
-
 using ::ceil;
 using ::ceilf;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       ceil(float __lcpp_x) _NOEXCEPT       {return ceilf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double ceil(long double __lcpp_x) _NOEXCEPT {return ceill(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-ceil(_A1 __lcpp_x) _NOEXCEPT {return ceil((double)__lcpp_x);}
-
-// cos
-
 using ::cos;
 using ::cosf;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       cos(float __lcpp_x) _NOEXCEPT       {return cosf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double cos(long double __lcpp_x) _NOEXCEPT {return cosl(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-cos(_A1 __lcpp_x) _NOEXCEPT {return cos((double)__lcpp_x);}
-
-// cosh
-
 using ::cosh;
 using ::coshf;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       cosh(float __lcpp_x) _NOEXCEPT       {return coshf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double cosh(long double __lcpp_x) _NOEXCEPT {return coshl(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-cosh(_A1 __lcpp_x) _NOEXCEPT {return cosh((double)__lcpp_x);}
-
 #endif // __sun__
-// exp
 
 using ::exp;
 using ::expf;
 
 #ifndef __sun__
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       exp(float __lcpp_x) _NOEXCEPT       {return expf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double exp(long double __lcpp_x) _NOEXCEPT {return expl(__lcpp_x);}
-#endif
-
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-exp(_A1 __lcpp_x) _NOEXCEPT {return exp((double)__lcpp_x);}
-
-// fabs
-
 using ::fabs;
 using ::fabsf;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       fabs(float __lcpp_x) _NOEXCEPT       {return fabsf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double fabs(long double __lcpp_x) _NOEXCEPT {return fabsl(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-fabs(_A1 __lcpp_x) _NOEXCEPT {return fabs((double)__lcpp_x);}
-
-// floor
-
 using ::floor;
 using ::floorf;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       floor(float __lcpp_x) _NOEXCEPT       {return floorf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double floor(long double __lcpp_x) _NOEXCEPT {return floorl(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-floor(_A1 __lcpp_x) _NOEXCEPT {return floor((double)__lcpp_x);}
-
-// fmod
-
 #endif //__sun__
+
 using ::fmod;
 using ::fmodf;
+
 #ifndef __sun__
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       fmod(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fmodf(__lcpp_x, __lcpp_y);}
-inline _LIBCPP_INLINE_VISIBILITY long double fmod(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fmodl(__lcpp_x, __lcpp_y);}
-#endif
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __lazy_enable_if
-<
-    is_arithmetic<_A1>::value &&
-    is_arithmetic<_A2>::value,
-    __promote<_A1, _A2>
->::type
-fmod(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename __promote<_A1, _A2>::type __result_type;
-    static_assert((!(is_same<_A1, __result_type>::value &&
-                      is_same<_A2, __result_type>::value)), "");
-    return fmod((__result_type)__lcpp_x, (__result_type)__lcpp_y);
-}
-
-
-// frexp
-
 using ::frexp;
 using ::frexpf;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       frexp(float __lcpp_x, int* __lcpp_e) _NOEXCEPT       {return frexpf(__lcpp_x, __lcpp_e);}
-inline _LIBCPP_INLINE_VISIBILITY long double frexp(long double __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexpl(__lcpp_x, __lcpp_e);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-frexp(_A1 __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexp((double)__lcpp_x, __lcpp_e);}
-
-// ldexp
-
 using ::ldexp;
 using ::ldexpf;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       ldexp(float __lcpp_x, int __lcpp_e) _NOEXCEPT       {return ldexpf(__lcpp_x, __lcpp_e);}
-inline _LIBCPP_INLINE_VISIBILITY long double ldexp(long double __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexpl(__lcpp_x, __lcpp_e);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-ldexp(_A1 __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexp((double)__lcpp_x, __lcpp_e);}
-
-// log
-
 #endif // __sun__
+
 using ::log;
 using ::logf;
+
 #ifndef __sun__
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       log(float __lcpp_x) _NOEXCEPT       {return logf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double log(long double __lcpp_x) _NOEXCEPT {return logl(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-log(_A1 __lcpp_x) _NOEXCEPT {return log((double)__lcpp_x);}
-
-
-// log10
-
 using ::log10;
 using ::log10f;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       log10(float __lcpp_x) _NOEXCEPT       {return log10f(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double log10(long double __lcpp_x) _NOEXCEPT {return log10l(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-log10(_A1 __lcpp_x) _NOEXCEPT {return log10((double)__lcpp_x);}
-
-// modf
-
 using ::modf;
 using ::modff;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       modf(float __lcpp_x, float* __lcpp_y) _NOEXCEPT             {return modff(__lcpp_x, __lcpp_y);}
-inline _LIBCPP_INLINE_VISIBILITY long double modf(long double __lcpp_x, long double* __lcpp_y) _NOEXCEPT {return modfl(__lcpp_x, __lcpp_y);}
-#endif
-
-// pow
-
 #endif // __sun__ 
+
 using ::pow;
 using ::powf;
 
 #ifndef __sun__
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       pow(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return powf(__lcpp_x, __lcpp_y);}
-inline _LIBCPP_INLINE_VISIBILITY long double pow(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return powl(__lcpp_x, __lcpp_y);}
-#endif
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __lazy_enable_if
-<
-    is_arithmetic<_A1>::value &&
-    is_arithmetic<_A2>::value,
-    __promote<_A1, _A2>
->::type
-pow(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename __promote<_A1, _A2>::type __result_type;
-    static_assert((!(is_same<_A1, __result_type>::value &&
-                      is_same<_A2, __result_type>::value)), "");
-    return pow((__result_type)__lcpp_x, (__result_type)__lcpp_y);
-}
-
-// sin
-
 using ::sin;
 using ::sinf;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       sin(float __lcpp_x) _NOEXCEPT       {return sinf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double sin(long double __lcpp_x) _NOEXCEPT {return sinl(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-sin(_A1 __lcpp_x) _NOEXCEPT {return sin((double)__lcpp_x);}
-
-// sinh
-
 using ::sinh;
 using ::sinhf;
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       sinh(float __lcpp_x) _NOEXCEPT       {return sinhf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double sinh(long double __lcpp_x) _NOEXCEPT {return sinhl(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-sinh(_A1 __lcpp_x) _NOEXCEPT {return sinh((double)__lcpp_x);}
-
-// sqrt
-
 #endif // __sun__
+
 using ::sqrt;
 using ::sqrtf;
-
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(__sun__) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       sqrt(float __lcpp_x) _NOEXCEPT       {return sqrtf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double sqrt(long double __lcpp_x) _NOEXCEPT {return sqrtl(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-sqrt(_A1 __lcpp_x) _NOEXCEPT {return sqrt((double)__lcpp_x);}
-
-// tan
-
 using ::tan;
 using ::tanf;
+
 #ifndef __sun__
-
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       tan(float __lcpp_x) _NOEXCEPT       {return tanf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double tan(long double __lcpp_x) _NOEXCEPT {return tanl(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-tan(_A1 __lcpp_x) _NOEXCEPT {return tan((double)__lcpp_x);}
-
-// tanh
-
 using ::tanh;
 using ::tanhf;
 
-#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       tanh(float __lcpp_x) _NOEXCEPT       {return tanhf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double tanh(long double __lcpp_x) _NOEXCEPT {return tanhl(__lcpp_x);}
-#endif
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-tanh(_A1 __lcpp_x) _NOEXCEPT {return tanh((double)__lcpp_x);}
-
-// acosh
-
 #ifndef _LIBCPP_MSVCRT
 using ::acosh;
 using ::acoshf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       acosh(float __lcpp_x) _NOEXCEPT       {return acoshf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double acosh(long double __lcpp_x) _NOEXCEPT {return acoshl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-acosh(_A1 __lcpp_x) _NOEXCEPT {return acosh((double)__lcpp_x);}
-#endif
-
-// asinh
-
-#ifndef _LIBCPP_MSVCRT
 using ::asinh;
 using ::asinhf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       asinh(float __lcpp_x) _NOEXCEPT       {return asinhf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double asinh(long double __lcpp_x) _NOEXCEPT {return asinhl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-asinh(_A1 __lcpp_x) _NOEXCEPT {return asinh((double)__lcpp_x);}
-#endif
-
-// atanh
-
-#ifndef _LIBCPP_MSVCRT
 using ::atanh;
 using ::atanhf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       atanh(float __lcpp_x) _NOEXCEPT       {return atanhf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double atanh(long double __lcpp_x) _NOEXCEPT {return atanhl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-atanh(_A1 __lcpp_x) _NOEXCEPT {return atanh((double)__lcpp_x);}
-#endif
-
-// cbrt
-
-#ifndef _LIBCPP_MSVCRT
 using ::cbrt;
 using ::cbrtf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       cbrt(float __lcpp_x) _NOEXCEPT       {return cbrtf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double cbrt(long double __lcpp_x) _NOEXCEPT {return cbrtl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-cbrt(_A1 __lcpp_x) _NOEXCEPT {return cbrt((double)__lcpp_x);}
 #endif
 
-// copysign
-
 using ::copysign;
 using ::copysignf;
 
-#if !defined(_VC_CRT_MAJOR_VERSION) || (_VC_CRT_MAJOR_VERSION < 12)
-inline _LIBCPP_INLINE_VISIBILITY float copysign(float __lcpp_x,
-                                                float __lcpp_y) _NOEXCEPT {
-  return copysignf(__lcpp_x, __lcpp_y);
-}
-inline _LIBCPP_INLINE_VISIBILITY long double
-copysign(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {
-  return copysignl(__lcpp_x, __lcpp_y);
-}
-#endif
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __lazy_enable_if
-<
-    is_arithmetic<_A1>::value &&
-    is_arithmetic<_A2>::value,
-    __promote<_A1, _A2>
->::type
-copysign(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename __promote<_A1, _A2>::type __result_type;
-    static_assert((!(is_same<_A1, __result_type>::value &&
-                      is_same<_A2, __result_type>::value)), "");
-    return copysign((__result_type)__lcpp_x, (__result_type)__lcpp_y);
-}
-
 #ifndef _LIBCPP_MSVCRT
-
-// erf
-
 using ::erf;
 using ::erff;
-
-inline _LIBCPP_INLINE_VISIBILITY float       erf(float __lcpp_x) _NOEXCEPT       {return erff(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double erf(long double __lcpp_x) _NOEXCEPT {return erfl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-erf(_A1 __lcpp_x) _NOEXCEPT {return erf((double)__lcpp_x);}
-
-// erfc
-
 using ::erfc;
 using ::erfcf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       erfc(float __lcpp_x) _NOEXCEPT       {return erfcf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double erfc(long double __lcpp_x) _NOEXCEPT {return erfcl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-erfc(_A1 __lcpp_x) _NOEXCEPT {return erfc((double)__lcpp_x);}
-
-// exp2
-
 using ::exp2;
 using ::exp2f;
-
-inline _LIBCPP_INLINE_VISIBILITY float       exp2(float __lcpp_x) _NOEXCEPT       {return exp2f(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double exp2(long double __lcpp_x) _NOEXCEPT {return exp2l(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-exp2(_A1 __lcpp_x) _NOEXCEPT {return exp2((double)__lcpp_x);}
-
-// expm1
-
 using ::expm1;
 using ::expm1f;
-
-inline _LIBCPP_INLINE_VISIBILITY float       expm1(float __lcpp_x) _NOEXCEPT       {return expm1f(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double expm1(long double __lcpp_x) _NOEXCEPT {return expm1l(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-expm1(_A1 __lcpp_x) _NOEXCEPT {return expm1((double)__lcpp_x);}
-
-// fdim
-
 using ::fdim;
 using ::fdimf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       fdim(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fdimf(__lcpp_x, __lcpp_y);}
-inline _LIBCPP_INLINE_VISIBILITY long double fdim(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fdiml(__lcpp_x, __lcpp_y);}
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __lazy_enable_if
-<
-    is_arithmetic<_A1>::value &&
-    is_arithmetic<_A2>::value,
-    __promote<_A1, _A2>
->::type
-fdim(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename __promote<_A1, _A2>::type __result_type;
-    static_assert((!(is_same<_A1, __result_type>::value &&
-                      is_same<_A2, __result_type>::value)), "");
-    return fdim((__result_type)__lcpp_x, (__result_type)__lcpp_y);
-}
-
-// fma
-
 using ::fmaf;
 using ::fma;
-
-inline _LIBCPP_INLINE_VISIBILITY float       fma(float __lcpp_x, float __lcpp_y, float __lcpp_z) _NOEXCEPT                   {return fmaf(__lcpp_x, __lcpp_y, __lcpp_z);}
-inline _LIBCPP_INLINE_VISIBILITY long double fma(long double __lcpp_x, long double __lcpp_y, long double __lcpp_z) _NOEXCEPT {return fmal(__lcpp_x, __lcpp_y, __lcpp_z);}
-
-template <class _A1, class _A2, class _A3>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __lazy_enable_if
-<
-    is_arithmetic<_A1>::value &&
-    is_arithmetic<_A2>::value &&
-    is_arithmetic<_A3>::value,
-    __promote<_A1, _A2, _A3>
->::type
-fma(_A1 __lcpp_x, _A2 __lcpp_y, _A3 __lcpp_z) _NOEXCEPT
-{
-    typedef typename __promote<_A1, _A2, _A3>::type __result_type;
-    static_assert((!(is_same<_A1, __result_type>::value &&
-                      is_same<_A2, __result_type>::value &&
-                      is_same<_A3, __result_type>::value)), "");
-    return fma((__result_type)__lcpp_x, (__result_type)__lcpp_y, (__result_type)__lcpp_z);
-}
-
-// fmax
-
 using ::fmax;
 using ::fmaxf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       fmax(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fmaxf(__lcpp_x, __lcpp_y);}
-inline _LIBCPP_INLINE_VISIBILITY long double fmax(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fmaxl(__lcpp_x, __lcpp_y);}
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __lazy_enable_if
-<
-    is_arithmetic<_A1>::value &&
-    is_arithmetic<_A2>::value,
-    __promote<_A1, _A2>
->::type
-fmax(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename __promote<_A1, _A2>::type __result_type;
-    static_assert((!(is_same<_A1, __result_type>::value &&
-                      is_same<_A2, __result_type>::value)), "");
-    return fmax((__result_type)__lcpp_x, (__result_type)__lcpp_y);
-}
-
-// fmin
-
 using ::fmin;
 using ::fminf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       fmin(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fminf(__lcpp_x, __lcpp_y);}
-inline _LIBCPP_INLINE_VISIBILITY long double fmin(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fminl(__lcpp_x, __lcpp_y);}
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __lazy_enable_if
-<
-    is_arithmetic<_A1>::value &&
-    is_arithmetic<_A2>::value,
-    __promote<_A1, _A2>
->::type
-fmin(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename __promote<_A1, _A2>::type __result_type;
-    static_assert((!(is_same<_A1, __result_type>::value &&
-                      is_same<_A2, __result_type>::value)), "");
-    return fmin((__result_type)__lcpp_x, (__result_type)__lcpp_y);
-}
-
-// hypot
-
 using ::hypot;
 using ::hypotf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       hypot(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return hypotf(__lcpp_x, __lcpp_y);}
-inline _LIBCPP_INLINE_VISIBILITY long double hypot(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return hypotl(__lcpp_x, __lcpp_y);}
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __lazy_enable_if
-<
-    is_arithmetic<_A1>::value &&
-    is_arithmetic<_A2>::value,
-    __promote<_A1, _A2>
->::type
-hypot(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename __promote<_A1, _A2>::type __result_type;
-    static_assert((!(is_same<_A1, __result_type>::value &&
-                      is_same<_A2, __result_type>::value)), "");
-    return hypot((__result_type)__lcpp_x, (__result_type)__lcpp_y);
-}
-
-// ilogb
-
 using ::ilogb;
 using ::ilogbf;
-
-inline _LIBCPP_INLINE_VISIBILITY int ilogb(float __lcpp_x) _NOEXCEPT       {return ilogbf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY int ilogb(long double __lcpp_x) _NOEXCEPT {return ilogbl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, int>::type
-ilogb(_A1 __lcpp_x) _NOEXCEPT {return ilogb((double)__lcpp_x);}
-
-// lgamma
-
 using ::lgamma;
 using ::lgammaf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       lgamma(float __lcpp_x) _NOEXCEPT       {return lgammaf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double lgamma(long double __lcpp_x) _NOEXCEPT {return lgammal(__lcpp_x);}
-
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-lgamma(_A1 __lcpp_x) _NOEXCEPT {return lgamma((double)__lcpp_x);}
-
-
-// llrint
-
 using ::llrint;
 using ::llrintf;
-
-inline _LIBCPP_INLINE_VISIBILITY long long llrint(float __lcpp_x) _NOEXCEPT       {return llrintf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long long llrint(long double __lcpp_x) _NOEXCEPT {return llrintl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, long long>::type
-llrint(_A1 __lcpp_x) _NOEXCEPT {return llrint((double)__lcpp_x);}
-
-// llround
-
 using ::llround;
 using ::llroundf;
-
-inline _LIBCPP_INLINE_VISIBILITY long long llround(float __lcpp_x) _NOEXCEPT       {return llroundf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long long llround(long double __lcpp_x) _NOEXCEPT {return llroundl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, long long>::type
-llround(_A1 __lcpp_x) _NOEXCEPT {return llround((double)__lcpp_x);}
-
-// log1p
-
 using ::log1p;
 using ::log1pf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       log1p(float __lcpp_x) _NOEXCEPT       {return log1pf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double log1p(long double __lcpp_x) _NOEXCEPT {return log1pl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-log1p(_A1 __lcpp_x) _NOEXCEPT {return log1p((double)__lcpp_x);}
-
-// log2
-
 using ::log2;
 using ::log2f;
-
-inline _LIBCPP_INLINE_VISIBILITY float       log2(float __lcpp_x) _NOEXCEPT       {return log2f(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __lcpp_x) _NOEXCEPT {return log2l(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-log2(_A1 __lcpp_x) _NOEXCEPT {return log2((double)__lcpp_x);}
-
-// logb
-
 using ::logb;
 using ::logbf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       logb(float __lcpp_x) _NOEXCEPT       {return logbf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double logb(long double __lcpp_x) _NOEXCEPT {return logbl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-logb(_A1 __lcpp_x) _NOEXCEPT {return logb((double)__lcpp_x);}
-
-// lrint
-
 using ::lrint;
 using ::lrintf;
-
-inline _LIBCPP_INLINE_VISIBILITY long lrint(float __lcpp_x) _NOEXCEPT       {return lrintf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long lrint(long double __lcpp_x) _NOEXCEPT {return lrintl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, long>::type
-lrint(_A1 __lcpp_x) _NOEXCEPT {return lrint((double)__lcpp_x);}
-
-// lround
-
 using ::lround;
 using ::lroundf;
-
-inline _LIBCPP_INLINE_VISIBILITY long lround(float __lcpp_x) _NOEXCEPT       {return lroundf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long lround(long double __lcpp_x) _NOEXCEPT {return lroundl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, long>::type
-lround(_A1 __lcpp_x) _NOEXCEPT {return lround((double)__lcpp_x);}
-
 #endif // _LIBCPP_MSVCRT
 #endif // __sun__
 
-// nan
-
 #ifndef _LIBCPP_MSVCRT
 using ::nan;
 using ::nanf;
@@ -1447,183 +458,28 @@
 
 #ifndef __sun__
 #ifndef _LIBCPP_MSVCRT
-
-// nearbyint
-
 using ::nearbyint;
 using ::nearbyintf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       nearbyint(float __lcpp_x) _NOEXCEPT       {return nearbyintf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double nearbyint(long double __lcpp_x) _NOEXCEPT {return nearbyintl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-nearbyint(_A1 __lcpp_x) _NOEXCEPT {return nearbyint((double)__lcpp_x);}
-
-// nextafter
-
 using ::nextafter;
 using ::nextafterf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       nextafter(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return nextafterf(__lcpp_x, __lcpp_y);}
-inline _LIBCPP_INLINE_VISIBILITY long double nextafter(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nextafterl(__lcpp_x, __lcpp_y);}
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __lazy_enable_if
-<
-    is_arithmetic<_A1>::value &&
-    is_arithmetic<_A2>::value,
-    __promote<_A1, _A2>
->::type
-nextafter(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename __promote<_A1, _A2>::type __result_type;
-    static_assert((!(is_same<_A1, __result_type>::value &&
-                      is_same<_A2, __result_type>::value)), "");
-    return nextafter((__result_type)__lcpp_x, (__result_type)__lcpp_y);
-}
-
-// nexttoward
-
 using ::nexttoward;
 using ::nexttowardf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       nexttoward(float __lcpp_x, long double __lcpp_y) _NOEXCEPT       {return nexttowardf(__lcpp_x, __lcpp_y);}
-inline _LIBCPP_INLINE_VISIBILITY long double nexttoward(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nexttowardl(__lcpp_x, __lcpp_y);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-nexttoward(_A1 __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nexttoward((double)__lcpp_x, __lcpp_y);}
-
-// remainder
-
 using ::remainder;
 using ::remainderf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       remainder(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return remainderf(__lcpp_x, __lcpp_y);}
-inline _LIBCPP_INLINE_VISIBILITY long double remainder(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return remainderl(__lcpp_x, __lcpp_y);}
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __lazy_enable_if
-<
-    is_arithmetic<_A1>::value &&
-    is_arithmetic<_A2>::value,
-    __promote<_A1, _A2>
->::type
-remainder(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
-{
-    typedef typename __promote<_A1, _A2>::type __result_type;
-    static_assert((!(is_same<_A1, __result_type>::value &&
-                      is_same<_A2, __result_type>::value)), "");
-    return remainder((__result_type)__lcpp_x, (__result_type)__lcpp_y);
-}
-
-// remquo
-
 using ::remquo;
 using ::remquof;
-
-inline _LIBCPP_INLINE_VISIBILITY float       remquo(float __lcpp_x, float __lcpp_y, int* __lcpp_z) _NOEXCEPT             {return remquof(__lcpp_x, __lcpp_y, __lcpp_z);}
-inline _LIBCPP_INLINE_VISIBILITY long double remquo(long double __lcpp_x, long double __lcpp_y, int* __lcpp_z) _NOEXCEPT {return remquol(__lcpp_x, __lcpp_y, __lcpp_z);}
-
-template <class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __lazy_enable_if
-<
-    is_arithmetic<_A1>::value &&
-    is_arithmetic<_A2>::value,
-    __promote<_A1, _A2>
->::type
-remquo(_A1 __lcpp_x, _A2 __lcpp_y, int* __lcpp_z) _NOEXCEPT
-{
-    typedef typename __promote<_A1, _A2>::type __result_type;
-    static_assert((!(is_same<_A1, __result_type>::value &&
-                      is_same<_A2, __result_type>::value)), "");
-    return remquo((__result_type)__lcpp_x, (__result_type)__lcpp_y, __lcpp_z);
-}
-
-// rint
-
 using ::rint;
 using ::rintf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       rint(float __lcpp_x) _NOEXCEPT       {return rintf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double rint(long double __lcpp_x) _NOEXCEPT {return rintl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-rint(_A1 __lcpp_x) _NOEXCEPT {return rint((double)__lcpp_x);}
-
-// round
-
 using ::round;
 using ::roundf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       round(float __lcpp_x) _NOEXCEPT       {return roundf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double round(long double __lcpp_x) _NOEXCEPT {return roundl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-round(_A1 __lcpp_x) _NOEXCEPT {return round((double)__lcpp_x);}
-
-// scalbln
-
 using ::scalbln;
 using ::scalblnf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       scalbln(float __lcpp_x, long __lcpp_y) _NOEXCEPT       {return scalblnf(__lcpp_x, __lcpp_y);}
-inline _LIBCPP_INLINE_VISIBILITY long double scalbln(long double __lcpp_x, long __lcpp_y) _NOEXCEPT {return scalblnl(__lcpp_x, __lcpp_y);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-scalbln(_A1 __lcpp_x, long __lcpp_y) _NOEXCEPT {return scalbln((double)__lcpp_x, __lcpp_y);}
-
-// scalbn
-
 using ::scalbn;
 using ::scalbnf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       scalbn(float __lcpp_x, int __lcpp_y) _NOEXCEPT       {return scalbnf(__lcpp_x, __lcpp_y);}
-inline _LIBCPP_INLINE_VISIBILITY long double scalbn(long double __lcpp_x, int __lcpp_y) _NOEXCEPT {return scalbnl(__lcpp_x, __lcpp_y);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-scalbn(_A1 __lcpp_x, int __lcpp_y) _NOEXCEPT {return scalbn((double)__lcpp_x, __lcpp_y);}
-
-// tgamma
-
 using ::tgamma;
 using ::tgammaf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       tgamma(float __lcpp_x) _NOEXCEPT       {return tgammaf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double tgamma(long double __lcpp_x) _NOEXCEPT {return tgammal(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-tgamma(_A1 __lcpp_x) _NOEXCEPT {return tgamma((double)__lcpp_x);}
-
-// trunc
-
 using ::trunc;
 using ::truncf;
-
-inline _LIBCPP_INLINE_VISIBILITY float       trunc(float __lcpp_x) _NOEXCEPT       {return truncf(__lcpp_x);}
-inline _LIBCPP_INLINE_VISIBILITY long double trunc(long double __lcpp_x) _NOEXCEPT {return truncl(__lcpp_x);}
-
-template <class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<is_integral<_A1>::value, double>::type
-trunc(_A1 __lcpp_x) _NOEXCEPT {return trunc((double)__lcpp_x);}
-
 #endif // !_LIBCPP_MSVCRT
 
 using ::acosl;
@@ -1647,6 +503,7 @@
 using ::sinhl;
 using ::sqrtl;
 using ::tanl;
+
 #ifndef _LIBCPP_MSVCRT
 using ::tanhl;
 using ::acoshl;
@@ -1654,7 +511,9 @@
 using ::atanhl;
 using ::cbrtl;
 #endif  // !_LIBCPP_MSVCRT
+
 using ::copysignl;
+
 #ifndef _LIBCPP_MSVCRT
 using ::erfl;
 using ::erfcl;
@@ -1692,6 +551,31 @@
 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 2943da1..f56138f 100644
--- a/include/complex
+++ b/include/complex
@@ -332,7 +332,9 @@
 
     _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 @@
 
     _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 @@
 
     _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 @@
         }
 };
 
-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 @@
     }
     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/complex.h b/include/complex.h
index 7003d31..c235966 100644
--- a/include/complex.h
+++ b/include/complex.h
@@ -18,6 +18,12 @@
 
 */
 
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
 #ifdef __cplusplus
 
 #include <ccomplex>
@@ -28,8 +34,4 @@
 
 #endif  // __cplusplus
 
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
 #endif  // _LIBCPP_COMPLEX_H
diff --git a/include/condition_variable b/include/condition_variable
index 1af2484..10e0077 100644
--- a/include/condition_variable
+++ b/include/condition_variable
@@ -124,14 +124,18 @@
     condition_variable __cv_;
     shared_ptr<mutex>  __mut_;
 public:
+    _LIBCPP_INLINE_VISIBILITY
     condition_variable_any();
 
+    _LIBCPP_INLINE_VISIBILITY
     void notify_one() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     void notify_all() _NOEXCEPT;
 
     template <class _Lock>
         void wait(_Lock& __lock);
     template <class _Lock, class _Predicate>
+        _LIBCPP_INLINE_VISIBILITY
         void wait(_Lock& __lock, _Predicate __pred);
 
     template <class _Lock, class _Clock, class _Duration>
@@ -141,27 +145,30 @@
 
     template <class _Lock, class _Clock, class _Duration, class _Predicate>
         bool
+        _LIBCPP_INLINE_VISIBILITY
         wait_until(_Lock& __lock,
                    const chrono::time_point<_Clock, _Duration>& __t,
                    _Predicate __pred);
 
     template <class _Lock, class _Rep, class _Period>
         cv_status
+        _LIBCPP_INLINE_VISIBILITY
         wait_for(_Lock& __lock,
                  const chrono::duration<_Rep, _Period>& __d);
 
     template <class _Lock, class _Rep, class _Period, class _Predicate>
         bool
+        _LIBCPP_INLINE_VISIBILITY
         wait_for(_Lock& __lock,
                  const chrono::duration<_Rep, _Period>& __d,
                  _Predicate __pred);
 };
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 condition_variable_any::condition_variable_any()
     : __mut_(make_shared<mutex>()) {}
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 condition_variable_any::notify_one() _NOEXCEPT
 {
@@ -169,7 +176,7 @@
     __cv_.notify_one();
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 condition_variable_any::notify_all() _NOEXCEPT
 {
@@ -196,7 +203,7 @@
 }  // __mut_.unlock(), __lock.lock()
 
 template <class _Lock, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 condition_variable_any::wait(_Lock& __lock, _Predicate __pred)
 {
@@ -218,7 +225,7 @@
 }  // __mut_.unlock(), __lock.lock()
 
 template <class _Lock, class _Clock, class _Duration, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 condition_variable_any::wait_until(_Lock& __lock,
                                    const chrono::time_point<_Clock, _Duration>& __t,
@@ -231,7 +238,7 @@
 }
 
 template <class _Lock, class _Rep, class _Period>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 cv_status
 condition_variable_any::wait_for(_Lock& __lock,
                                  const chrono::duration<_Rep, _Period>& __d)
@@ -240,7 +247,7 @@
 }
 
 template <class _Lock, class _Rep, class _Period, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 condition_variable_any::wait_for(_Lock& __lock,
                                  const chrono::duration<_Rep, _Period>& __d,
diff --git a/include/csetjmp b/include/csetjmp
index d0b2c07..58a9c73 100644
--- a/include/csetjmp
+++ b/include/csetjmp
@@ -38,10 +38,6 @@
 #pragma GCC system_header
 #endif
 
-#ifndef setjmp
-#define setjmp(env) setjmp(env)
-#endif
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 using ::jmp_buf;
diff --git a/include/cstddef b/include/cstddef
index c3ca64a..edd106c 100644
--- a/include/cstddef
+++ b/include/cstddef
@@ -35,12 +35,14 @@
 
 #include <__config>
 
-#include <stddef.h>
-
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
 
+// Don't include our own <stddef.h>; we don't want to declare ::nullptr_t.
+#include_next <stddef.h>
+#include <__nullptr>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 using ::ptrdiff_t;
@@ -53,50 +55,6 @@
 typedef long double max_align_t;
 #endif
 
-#ifdef _LIBCPP_HAS_NO_NULLPTR
-
-struct _LIBCPP_TYPE_VIS_ONLY nullptr_t
-{
-    void* __lx;
-
-    struct __nat {int __for_bool_;};
-
-    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {}
-    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}
-
-    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}
-
-    template <class _Tp>
-        _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR
-        operator _Tp* () const {return 0;}
-
-    template <class _Tp, class _Up>
-        _LIBCPP_ALWAYS_INLINE
-        operator _Tp _Up::* () const {return 0;}
-
-    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;}
-    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;}
-    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator<(nullptr_t, nullptr_t) {return false;}
-    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator<=(nullptr_t, nullptr_t) {return true;}
-    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator>(nullptr_t, nullptr_t) {return false;}
-    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator>=(nullptr_t, nullptr_t) {return true;}
-};
-
-inline _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);}
-
-#define nullptr _VSTD::__get_nullptr_t()
-
-#endif  // _LIBCPP_HAS_NO_NULLPTR
-
 _LIBCPP_END_NAMESPACE_STD
 
-#ifndef _LIBCPP_HAS_NO_NULLPTR
-
-namespace std
-{
-    typedef decltype(nullptr) nullptr_t;
-}
-
-#endif  // _LIBCPP_HAS_NO_NULLPTR
-
 #endif  // _LIBCPP_CSTDDEF
diff --git a/include/cstdio b/include/cstdio
index d8ba6c2..50fdd34 100644
--- a/include/cstdio
+++ b/include/cstdio
@@ -103,41 +103,6 @@
 #pragma GCC system_header
 #endif
 
-// snprintf
-#if defined(_LIBCPP_MSVCRT)
-#include "support/win32/support.h"
-#endif
-
-#ifdef getc
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_getc(FILE* __stream) {return getc(__stream);}
-#undef getc
-inline _LIBCPP_INLINE_VISIBILITY int getc(FILE* __stream) {return __libcpp_getc(__stream);}
-#endif  // getc
-
-#ifdef putc
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_putc(int __c, FILE* __stream) {return putc(__c, __stream);}
-#undef putc
-inline _LIBCPP_INLINE_VISIBILITY int putc(int __c, FILE* __stream) {return __libcpp_putc(__c, __stream);}
-#endif  // putc
-
-#ifdef clearerr
-inline _LIBCPP_INLINE_VISIBILITY void __libcpp_clearerr(FILE* __stream) { return clearerr(__stream); }
-#undef clearerr
-inline _LIBCPP_INLINE_VISIBILITY void clearerr(FILE* __stream) { return __libcpp_clearerr(__stream); }
-#endif  // clearerr
-
-#ifdef feof
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_feof(FILE* __stream) { return feof(__stream); }
-#undef feof
-inline _LIBCPP_INLINE_VISIBILITY int feof(FILE* __stream) { return __libcpp_feof(__stream); }
-#endif  // feof
-
-#ifdef ferror
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_ferror(FILE* __stream) { return ferror(__stream); }
-#undef ferror
-inline _LIBCPP_INLINE_VISIBILITY int ferror(FILE* __stream) { return __libcpp_ferror(__stream); }
-#endif  // ferror
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 using ::FILE;
diff --git a/include/cstdlib b/include/cstdlib
index 55e15c8..10ed231 100644
--- a/include/cstdlib
+++ b/include/cstdlib
@@ -84,9 +84,6 @@
 
 #include <__config>
 #include <stdlib.h>
-#ifdef _LIBCPP_MSVCRT
-#include "support/win32/locale_win32.h"
-#endif // _LIBCPP_MSVCRT
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -131,20 +128,14 @@
 using ::system;
 using ::bsearch;
 using ::qsort;
-#undef abs
 using ::abs;
-#undef labs
 using ::labs;
 #ifndef _LIBCPP_HAS_NO_LONG_LONG
-#undef llabs
 using ::llabs;
 #endif // _LIBCPP_HAS_NO_LONG_LONG
-#undef div
 using ::div;
-#undef ldiv
 using ::ldiv;
 #ifndef _LIBCPP_HAS_NO_LONG_LONG
-#undef lldiv
 using ::lldiv;
 #endif // _LIBCPP_HAS_NO_LONG_LONG
 #ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
@@ -162,19 +153,6 @@
 using ::aligned_alloc;
 #endif
 
-// MSVCRT already has the correct prototype in <stdlib.h> #ifdef __cplusplus
-#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
-inline _LIBCPP_INLINE_VISIBILITY long      abs(     long __x) _NOEXCEPT {return  labs(__x);}
-#ifndef _LIBCPP_HAS_NO_LONG_LONG
-inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {return llabs(__x);}
-#endif // _LIBCPP_HAS_NO_LONG_LONG
-
-inline _LIBCPP_INLINE_VISIBILITY  ldiv_t div(     long __x,      long __y) _NOEXCEPT {return  ldiv(__x, __y);}
-#ifndef _LIBCPP_HAS_NO_LONG_LONG
-inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x, long long __y) _NOEXCEPT {return lldiv(__x, __y);}
-#endif // _LIBCPP_HAS_NO_LONG_LONG
-#endif // _LIBCPP_MSVCRT
-
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_CSTDLIB
diff --git a/include/cstring b/include/cstring
index d60b992..d550695 100644
--- a/include/cstring
+++ b/include/cstring
@@ -78,30 +78,13 @@
 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/ctype.h b/include/ctype.h
new file mode 100644
index 0000000..22d6c49
--- /dev/null
+++ b/include/ctype.h
@@ -0,0 +1,69 @@
+// -*- C++ -*-
+//===---------------------------- ctype.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_CTYPE_H
+#define _LIBCPP_CTYPE_H
+
+/*
+    ctype.h synopsis
+
+int isalnum(int c);
+int isalpha(int c);
+int isblank(int c);  // C99
+int iscntrl(int c);
+int isdigit(int c);
+int isgraph(int c);
+int islower(int c);
+int isprint(int c);
+int ispunct(int c);
+int isspace(int c);
+int isupper(int c);
+int isxdigit(int c);
+int tolower(int c);
+int toupper(int c);
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <ctype.h>
+
+#ifdef __cplusplus
+
+#if defined(_LIBCPP_MSVCRT)
+// We support including .h headers inside 'extern "C"' contexts, so switch
+// back to C++ linkage before including these C++ headers.
+extern "C++" {
+  #include "support/win32/support.h"
+  #include "support/win32/locale_win32.h"
+}
+#endif // _LIBCPP_MSVCRT
+
+#undef isalnum
+#undef isalpha
+#undef isblank
+#undef iscntrl
+#undef isdigit
+#undef isgraph
+#undef islower
+#undef isprint
+#undef ispunct
+#undef isspace
+#undef isupper
+#undef isxdigit
+#undef tolower
+#undef toupper
+
+#endif
+
+#endif  // _LIBCPP_CTYPE_H
diff --git a/include/cwchar b/include/cwchar
index 797a177..52dde9e 100644
--- a/include/cwchar
+++ b/include/cwchar
@@ -106,9 +106,6 @@
 #include <__config>
 #include <cwctype>
 #include <wchar.h>
-#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
-#include <support/win32/support.h> // pull in *swprintf defines
-#endif // _LIBCPP_MSVCRT
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -160,34 +157,11 @@
 using ::wcscoll;
 using ::wcsncmp;
 using ::wcsxfrm;
-
-#if defined(_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_)
-
 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/cwctype b/include/cwctype
index 4f89b52..25b2489 100644
--- a/include/cwctype
+++ b/include/cwctype
@@ -63,150 +63,24 @@
 using ::wint_t;
 using ::wctrans_t;
 using ::wctype_t;
-
-#ifdef iswalnum
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswalnum(wint_t __wc) {return iswalnum(__wc);}
-#undef iswalnum
-inline _LIBCPP_INLINE_VISIBILITY int iswalnum(wint_t __wc) {return __libcpp_iswalnum(__wc);}
-#else  // iswalnum
 using ::iswalnum;
-#endif
-
-#ifdef iswalpha
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswalpha(wint_t __wc) {return iswalpha(__wc);}
-#undef iswalpha
-inline _LIBCPP_INLINE_VISIBILITY int iswalpha(wint_t __wc) {return __libcpp_iswalpha(__wc);}
-#else  // iswalpha
 using ::iswalpha;
-#endif
-
-#ifdef iswblank
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswblank(wint_t __wc) {return iswblank(__wc);}
-#undef iswblank
-inline _LIBCPP_INLINE_VISIBILITY int iswblank(wint_t __wc) {return __libcpp_iswblank(__wc);}
-#else  // iswblank
 using ::iswblank;
-#endif
-
-#ifdef iswcntrl
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswcntrl(wint_t __wc) {return iswcntrl(__wc);}
-#undef iswcntrl
-inline _LIBCPP_INLINE_VISIBILITY int iswcntrl(wint_t __wc) {return __libcpp_iswcntrl(__wc);}
-#else  // iswcntrl
 using ::iswcntrl;
-#endif
-
-#ifdef iswdigit
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswdigit(wint_t __wc) {return iswdigit(__wc);}
-#undef iswdigit
-inline _LIBCPP_INLINE_VISIBILITY int iswdigit(wint_t __wc) {return __libcpp_iswdigit(__wc);}
-#else  // iswdigit
 using ::iswdigit;
-#endif
-
-#ifdef iswgraph
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswgraph(wint_t __wc) {return iswgraph(__wc);}
-#undef iswgraph
-inline _LIBCPP_INLINE_VISIBILITY int iswgraph(wint_t __wc) {return __libcpp_iswgraph(__wc);}
-#else  // iswgraph
 using ::iswgraph;
-#endif
-
-#ifdef iswlower
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswlower(wint_t __wc) {return iswlower(__wc);}
-#undef iswlower
-inline _LIBCPP_INLINE_VISIBILITY int iswlower(wint_t __wc) {return __libcpp_iswlower(__wc);}
-#else  // iswlower
 using ::iswlower;
-#endif
-
-#ifdef iswprint
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswprint(wint_t __wc) {return iswprint(__wc);}
-#undef iswprint
-inline _LIBCPP_INLINE_VISIBILITY int iswprint(wint_t __wc) {return __libcpp_iswprint(__wc);}
-#else  // iswprint
 using ::iswprint;
-#endif
-
-#ifdef iswpunct
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswpunct(wint_t __wc) {return iswpunct(__wc);}
-#undef iswpunct
-inline _LIBCPP_INLINE_VISIBILITY int iswpunct(wint_t __wc) {return __libcpp_iswpunct(__wc);}
-#else  // iswpunct
 using ::iswpunct;
-#endif
-
-#ifdef iswspace
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswspace(wint_t __wc) {return iswspace(__wc);}
-#undef iswspace
-inline _LIBCPP_INLINE_VISIBILITY int iswspace(wint_t __wc) {return __libcpp_iswspace(__wc);}
-#else  // iswspace
 using ::iswspace;
-#endif
-
-#ifdef iswupper
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswupper(wint_t __wc) {return iswupper(__wc);}
-#undef iswupper
-inline _LIBCPP_INLINE_VISIBILITY int iswupper(wint_t __wc) {return __libcpp_iswupper(__wc);}
-#else  // iswupper
 using ::iswupper;
-#endif
-
-#ifdef iswxdigit
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswxdigit(wint_t __wc) {return iswxdigit(__wc);}
-#undef iswxdigit
-inline _LIBCPP_INLINE_VISIBILITY int iswxdigit(wint_t __wc) {return __libcpp_iswxdigit(__wc);}
-#else  // iswxdigit
 using ::iswxdigit;
-#endif
-
-#ifdef iswctype
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswctype(wint_t __w, wctype_t __d) {return iswctype(__w, __d);}
-#undef iswctype
-inline _LIBCPP_INLINE_VISIBILITY int iswctype(wint_t __w, wctype_t __d) {return __libcpp_iswctype(__w, __d);}
-#else  // iswctype
 using ::iswctype;
-#endif
-
-#ifdef wctype
-inline _LIBCPP_INLINE_VISIBILITY wctype_t __libcpp_wctype(const char* __p) {return wctype(__p);}
-#undef wctype
-inline _LIBCPP_INLINE_VISIBILITY wctype_t wctype(const char* __p) {return __libcpp_wctype(__p);}
-#else  // wctype
 using ::wctype;
-#endif
-
-#ifdef towlower
-inline _LIBCPP_INLINE_VISIBILITY wint_t __libcpp_towlower(wint_t __wc) {return towlower(__wc);}
-#undef towlower
-inline _LIBCPP_INLINE_VISIBILITY wint_t towlower(wint_t __wc) {return __libcpp_towlower(__wc);}
-#else  // towlower
 using ::towlower;
-#endif
-
-#ifdef towupper
-inline _LIBCPP_INLINE_VISIBILITY wint_t __libcpp_towupper(wint_t __wc) {return towupper(__wc);}
-#undef towupper
-inline _LIBCPP_INLINE_VISIBILITY wint_t towupper(wint_t __wc) {return __libcpp_towupper(__wc);}
-#else  // towupper
 using ::towupper;
-#endif
-
-#ifdef towctrans
-inline _LIBCPP_INLINE_VISIBILITY wint_t __libcpp_towctrans(wint_t __wc, wctype_t __d) {return towctrans(__wc, __d);}
-#undef towctrans
-inline _LIBCPP_INLINE_VISIBILITY wint_t towctrans(wint_t __wc, wctype_t __d) {return __libcpp_towctrans(__wc, __d);}
-#else  // towctrans
 using ::towctrans;
-#endif
-
-#ifdef wctrans
-inline _LIBCPP_INLINE_VISIBILITY wctrans_t __libcpp_wctrans(const char* __p) {return wctrans(__p);}
-#undef wctrans
-inline _LIBCPP_INLINE_VISIBILITY wctrans_t wctrans(const char* __p) {return __libcpp_wctrans(__p);}
-#else  // wctrans
 using ::wctrans;
-#endif
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/include/deque b/include/deque
index 87ff8bf..c6fbd51 100644
--- a/include/deque
+++ b/include/deque
@@ -261,8 +261,21 @@
               __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
               __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
 
+template <class _ValueType, class _DiffType>
+struct __deque_block_size {
+  static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16;
+};
+
 template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
-          class _DiffType, _DiffType _BlockSize>
+          class _DiffType, _DiffType _BS =
+#ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
+// Keep template parameter to avoid changing all template declarations thoughout
+// this file.
+                               0
+#else
+                               __deque_block_size<_ValueType, _DiffType>::value
+#endif
+          >
 class _LIBCPP_TYPE_VIS_ONLY __deque_iterator
 {
     typedef _MapPointer __map_iterator;
@@ -273,7 +286,7 @@
     __map_iterator __m_iter_;
     pointer        __ptr_;
 
-    static const difference_type __block_size = _BlockSize;
+    static const difference_type __block_size;
 public:
     typedef _ValueType                  value_type;
     typedef random_access_iterator_tag  iterator_category;
@@ -287,7 +300,7 @@
 
     template <class _Pp, class _Rp, class _MP>
     _LIBCPP_INLINE_VISIBILITY
-    __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, __block_size>& __it,
+    __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it,
                 typename enable_if<is_convertible<_Pp, pointer>::value>::type* = 0) _NOEXCEPT
         : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}
 
@@ -520,6 +533,12 @@
                   __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
 };
 
+template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
+          class _DiffType, _DiffType _BlockSize>
+const _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer,
+                                 _DiffType, _BlockSize>::__block_size =
+    __deque_block_size<_ValueType, _DiffType>::value;
+
 // copy
 
 template <class _RAIter,
@@ -532,10 +551,11 @@
 {
     typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
     typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
+    const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
     while (__f != __l)
     {
         pointer __rb = __r.__ptr_;
-        pointer __re = *__r.__m_iter_ + _B2;
+        pointer __re = *__r.__m_iter_ + __block_size;
         difference_type __bs = __re - __rb;
         difference_type __n = __l - __f;
         _RAIter __m = __l;
@@ -560,11 +580,12 @@
 {
     typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
     typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+    const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
     difference_type __n = __l - __f;
     while (__n > 0)
     {
         pointer __fb = __f.__ptr_;
-        pointer __fe = *__f.__m_iter_ + _B1;
+        pointer __fe = *__f.__m_iter_ + __block_size;
         difference_type __bs = __fe - __fb;
         if (__bs > __n)
         {
@@ -587,11 +608,12 @@
 {
     typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
     typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+    const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
     difference_type __n = __l - __f;
     while (__n > 0)
     {
         pointer __fb = __f.__ptr_;
-        pointer __fe = *__f.__m_iter_ + _B1;
+        pointer __fe = *__f.__m_iter_ + __block_size;
         difference_type __bs = __fe - __fb;
         if (__bs > __n)
         {
@@ -705,10 +727,11 @@
 {
     typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
     typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
+    const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
     while (__f != __l)
     {
         pointer __rb = __r.__ptr_;
-        pointer __re = *__r.__m_iter_ + _B2;
+        pointer __re = *__r.__m_iter_ + __block_size;
         difference_type __bs = __re - __rb;
         difference_type __n = __l - __f;
         _RAIter __m = __l;
@@ -733,11 +756,12 @@
 {
     typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
     typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+    const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
     difference_type __n = __l - __f;
     while (__n > 0)
     {
         pointer __fb = __f.__ptr_;
-        pointer __fe = *__f.__m_iter_ + _B1;
+        pointer __fe = *__f.__m_iter_ + __block_size;
         difference_type __bs = __fe - __fb;
         if (__bs > __n)
         {
@@ -760,11 +784,12 @@
 {
     typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
     typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+    const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
     difference_type __n = __l - __f;
     while (__n > 0)
     {
         pointer __fb = __f.__ptr_;
-        pointer __fe = *__f.__m_iter_ + _B1;
+        pointer __fe = *__f.__m_iter_ + __block_size;
         difference_type __bs = __fe - __fb;
         if (__bs > __n)
         {
@@ -909,7 +934,7 @@
     typedef typename __alloc_traits::pointer         pointer;
     typedef typename __alloc_traits::const_pointer   const_pointer;
 
-    static const difference_type __block_size = sizeof(value_type) < 256 ? 4096 / sizeof(value_type) : 16;
+    static const difference_type __block_size;
 
     typedef typename __rebind_alloc_helper<__alloc_traits, pointer>::type __pointer_allocator;
     typedef allocator_traits<__pointer_allocator>        __map_traits;
@@ -919,9 +944,9 @@
     typedef __split_buffer<pointer, __pointer_allocator> __map;
 
     typedef __deque_iterator<value_type, pointer, reference, __map_pointer,
-                             difference_type, __block_size>    iterator;
+                             difference_type>    iterator;
     typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,
-                             difference_type, __block_size>    const_iterator;
+                             difference_type>    const_iterator;
 
     __map __map_;
     size_type __start_;
@@ -939,8 +964,10 @@
     _LIBCPP_INLINE_VISIBILITY
     const allocator_type& __alloc() const _NOEXCEPT {return __size_.second();}
 
+    _LIBCPP_INLINE_VISIBILITY
     __deque_base()
         _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
+    _LIBCPP_INLINE_VISIBILITY
     explicit __deque_base(const allocator_type& __a);
 public:
     ~__deque_base();
@@ -997,6 +1024,11 @@
 };
 
 template <class _Tp, class _Allocator>
+const typename __deque_base<_Tp, _Allocator>::difference_type
+    __deque_base<_Tp, _Allocator>::__block_size =
+        __deque_block_size<value_type, difference_type>::value;
+
+template <class _Tp, class _Allocator>
 bool
 __deque_base<_Tp, _Allocator>::__invariants() const
 {
@@ -1060,13 +1092,13 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __deque_base<_Tp, _Allocator>::__deque_base()
     _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
     : __start_(0), __size_(0) {}
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __deque_base<_Tp, _Allocator>::__deque_base(const allocator_type& __a)
     : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {}
 
@@ -1164,6 +1196,9 @@
     typedef _Tp value_type;
     typedef _Allocator allocator_type;
 
+    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
+                  "Allocator::value_type must be same type as value_type");
+
     typedef __deque_base<value_type, allocator_type> __base;
 
     typedef typename __base::__alloc_traits        __alloc_traits;
@@ -1211,8 +1246,11 @@
 #endif   // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
+    _LIBCPP_INLINE_VISIBILITY
     deque(deque&& __c, const allocator_type& __a);
+    _LIBCPP_INLINE_VISIBILITY
     deque& operator=(deque&& __c)
         _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
                    is_nothrow_move_assignable<allocator_type>::value);
@@ -1231,6 +1269,7 @@
     void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
+    _LIBCPP_INLINE_VISIBILITY
     allocator_type get_allocator() const _NOEXCEPT;
 
     // iterators:
@@ -1283,13 +1322,21 @@
     bool empty() const _NOEXCEPT {return __base::size() == 0;}
 
     // element access:
+    _LIBCPP_INLINE_VISIBILITY
     reference operator[](size_type __i);
+    _LIBCPP_INLINE_VISIBILITY
     const_reference operator[](size_type __i) const;
+    _LIBCPP_INLINE_VISIBILITY
     reference at(size_type __i);
+    _LIBCPP_INLINE_VISIBILITY
     const_reference at(size_type __i) const;
+    _LIBCPP_INLINE_VISIBILITY
     reference front();
+    _LIBCPP_INLINE_VISIBILITY
     const_reference front() const;
+    _LIBCPP_INLINE_VISIBILITY
     reference back();
+    _LIBCPP_INLINE_VISIBILITY
     const_reference back() const;
 
     // 23.2.2.3 modifiers:
@@ -1328,6 +1375,7 @@
     iterator erase(const_iterator __p);
     iterator erase(const_iterator __f, const_iterator __l);
 
+    _LIBCPP_INLINE_VISIBILITY
     void swap(deque& __c)
 #if _LIBCPP_STD_VER >= 14
         _NOEXCEPT;
@@ -1335,6 +1383,7 @@
         _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
                    __is_nothrow_swappable<allocator_type>::value);
 #endif
+    _LIBCPP_INLINE_VISIBILITY
     void clear() _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
@@ -1507,7 +1556,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 deque<_Tp, _Allocator>::deque(deque&& __c)
     _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
     : __base(_VSTD::move(__c))
@@ -1515,7 +1564,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 deque<_Tp, _Allocator>::deque(deque&& __c, const allocator_type& __a)
     : __base(_VSTD::move(__c), __a)
 {
@@ -1527,7 +1576,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 deque<_Tp, _Allocator>&
 deque<_Tp, _Allocator>::operator=(deque&& __c)
         _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
@@ -1611,7 +1660,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _Allocator
 deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT
 {
@@ -1670,7 +1719,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename deque<_Tp, _Allocator>::reference
 deque<_Tp, _Allocator>::operator[](size_type __i)
 {
@@ -1679,7 +1728,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename deque<_Tp, _Allocator>::const_reference
 deque<_Tp, _Allocator>::operator[](size_type __i) const
 {
@@ -1688,7 +1737,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename deque<_Tp, _Allocator>::reference
 deque<_Tp, _Allocator>::at(size_type __i)
 {
@@ -1699,7 +1748,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename deque<_Tp, _Allocator>::const_reference
 deque<_Tp, _Allocator>::at(size_type __i) const
 {
@@ -1710,7 +1759,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename deque<_Tp, _Allocator>::reference
 deque<_Tp, _Allocator>::front()
 {
@@ -1719,7 +1768,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename deque<_Tp, _Allocator>::const_reference
 deque<_Tp, _Allocator>::front() const
 {
@@ -1728,7 +1777,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename deque<_Tp, _Allocator>::reference
 deque<_Tp, _Allocator>::back()
 {
@@ -1737,7 +1786,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename deque<_Tp, _Allocator>::const_reference
 deque<_Tp, _Allocator>::back() const
 {
@@ -2776,7 +2825,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 deque<_Tp, _Allocator>::swap(deque& __c)
 #if _LIBCPP_STD_VER >= 14
@@ -2790,7 +2839,7 @@
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 deque<_Tp, _Allocator>::clear() _NOEXCEPT
 {
diff --git a/include/errno.h b/include/errno.h
new file mode 100644
index 0000000..ee64291
--- /dev/null
+++ b/include/errno.h
@@ -0,0 +1,398 @@
+// -*- C++ -*-
+//===-------------------------- errno.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_ERRNO_H
+#define _LIBCPP_ERRNO_H
+
+/*
+    errno.h synopsis
+
+Macros:
+
+    EDOM
+    EILSEQ  // C99
+    ERANGE
+    errno
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <errno.h>
+
+#ifdef __cplusplus
+
+#if !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)
+
+#ifdef ELAST
+
+static const int __elast1 = ELAST+1;
+static const int __elast2 = ELAST+2;
+
+#else
+
+static const int __elast1 = 104;
+static const int __elast2 = 105;
+
+#endif
+
+#ifdef ENOTRECOVERABLE
+
+#define EOWNERDEAD __elast1
+
+#ifdef ELAST
+#undef ELAST
+#define ELAST EOWNERDEAD
+#endif
+
+#elif defined(EOWNERDEAD)
+
+#define ENOTRECOVERABLE __elast1
+#ifdef ELAST
+#undef ELAST
+#define ELAST ENOTRECOVERABLE
+#endif
+
+#else  // defined(EOWNERDEAD)
+
+#define EOWNERDEAD __elast1
+#define ENOTRECOVERABLE __elast2
+#ifdef ELAST
+#undef ELAST
+#define ELAST ENOTRECOVERABLE
+#endif
+
+#endif  // defined(EOWNERDEAD)
+
+#endif  // !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)
+
+//  supply errno values likely to be missing, particularly on Windows
+
+#ifndef EAFNOSUPPORT
+#define EAFNOSUPPORT 9901
+#endif
+
+#ifndef EADDRINUSE
+#define EADDRINUSE 9902
+#endif
+
+#ifndef EADDRNOTAVAIL
+#define EADDRNOTAVAIL 9903
+#endif
+
+#ifndef EISCONN
+#define EISCONN 9904
+#endif
+
+#ifndef EBADMSG
+#define EBADMSG 9905
+#endif
+
+#ifndef ECONNABORTED
+#define ECONNABORTED 9906
+#endif
+
+#ifndef EALREADY
+#define EALREADY 9907
+#endif
+
+#ifndef ECONNREFUSED
+#define ECONNREFUSED 9908
+#endif
+
+#ifndef ECONNRESET
+#define ECONNRESET 9909
+#endif
+
+#ifndef EDESTADDRREQ
+#define EDESTADDRREQ 9910
+#endif
+
+#ifndef EHOSTUNREACH
+#define EHOSTUNREACH 9911
+#endif
+
+#ifndef EIDRM
+#define EIDRM 9912
+#endif
+
+#ifndef EMSGSIZE
+#define EMSGSIZE 9913
+#endif
+
+#ifndef ENETDOWN
+#define ENETDOWN 9914
+#endif
+
+#ifndef ENETRESET
+#define ENETRESET 9915
+#endif
+
+#ifndef ENETUNREACH
+#define ENETUNREACH 9916
+#endif
+
+#ifndef ENOBUFS
+#define ENOBUFS 9917
+#endif
+
+#ifndef ENOLINK
+#define ENOLINK 9918
+#endif
+
+#ifndef ENODATA
+#define ENODATA 9919
+#endif
+
+#ifndef ENOMSG
+#define ENOMSG 9920
+#endif
+
+#ifndef ENOPROTOOPT
+#define ENOPROTOOPT 9921
+#endif
+
+#ifndef ENOSR
+#define ENOSR 9922
+#endif
+
+#ifndef ENOTSOCK
+#define ENOTSOCK 9923
+#endif
+
+#ifndef ENOSTR
+#define ENOSTR 9924
+#endif
+
+#ifndef ENOTCONN
+#define ENOTCONN 9925
+#endif
+
+#ifndef ENOTSUP
+#define ENOTSUP 9926
+#endif
+
+#ifndef ECANCELED
+#define ECANCELED 9927
+#endif
+
+#ifndef EINPROGRESS
+#define EINPROGRESS 9928
+#endif
+
+#ifndef EOPNOTSUPP
+#define EOPNOTSUPP 9929
+#endif
+
+#ifndef EWOULDBLOCK
+#define EWOULDBLOCK 9930
+#endif
+
+#ifndef EOWNERDEAD
+#define EOWNERDEAD  9931
+#endif
+
+#ifndef EPROTO
+#define EPROTO 9932
+#endif
+
+#ifndef EPROTONOSUPPORT
+#define EPROTONOSUPPORT 9933
+#endif
+
+#ifndef ENOTRECOVERABLE
+#define ENOTRECOVERABLE 9934
+#endif
+
+#ifndef ETIME
+#define ETIME 9935
+#endif
+
+#ifndef ETXTBSY
+#define ETXTBSY 9936
+#endif
+
+#ifndef ETIMEDOUT
+#define ETIMEDOUT 9938
+#endif
+
+#ifndef ELOOP
+#define ELOOP 9939
+#endif
+
+#ifndef EOVERFLOW
+#define EOVERFLOW 9940
+#endif
+
+#ifndef EPROTOTYPE
+#define EPROTOTYPE 9941
+#endif
+
+#ifndef ENOSYS
+#define ENOSYS 9942
+#endif
+
+#ifndef EINVAL
+#define EINVAL 9943
+#endif
+
+#ifndef ERANGE
+#define ERANGE 9944
+#endif
+
+#ifndef EILSEQ
+#define EILSEQ 9945
+#endif
+
+//  Windows Mobile doesn't appear to define these:
+
+#ifndef E2BIG
+#define E2BIG 9946
+#endif
+
+#ifndef EDOM
+#define EDOM 9947
+#endif
+
+#ifndef EFAULT
+#define EFAULT 9948
+#endif
+
+#ifndef EBADF
+#define EBADF 9949
+#endif
+
+#ifndef EPIPE
+#define EPIPE 9950
+#endif
+
+#ifndef EXDEV
+#define EXDEV 9951
+#endif
+
+#ifndef EBUSY
+#define EBUSY 9952
+#endif
+
+#ifndef ENOTEMPTY
+#define ENOTEMPTY 9953
+#endif
+
+#ifndef ENOEXEC
+#define ENOEXEC 9954
+#endif
+
+#ifndef EEXIST
+#define EEXIST 9955
+#endif
+
+#ifndef EFBIG
+#define EFBIG 9956
+#endif
+
+#ifndef ENAMETOOLONG
+#define ENAMETOOLONG 9957
+#endif
+
+#ifndef ENOTTY
+#define ENOTTY 9958
+#endif
+
+#ifndef EINTR
+#define EINTR 9959
+#endif
+
+#ifndef ESPIPE
+#define ESPIPE 9960
+#endif
+
+#ifndef EIO
+#define EIO 9961
+#endif
+
+#ifndef EISDIR
+#define EISDIR 9962
+#endif
+
+#ifndef ECHILD
+#define ECHILD 9963
+#endif
+
+#ifndef ENOLCK
+#define ENOLCK 9964
+#endif
+
+#ifndef ENOSPC
+#define ENOSPC 9965
+#endif
+
+#ifndef ENXIO
+#define ENXIO 9966
+#endif
+
+#ifndef ENODEV
+#define ENODEV 9967
+#endif
+
+#ifndef ENOENT
+#define ENOENT 9968
+#endif
+
+#ifndef ESRCH
+#define ESRCH 9969
+#endif
+
+#ifndef ENOTDIR
+#define ENOTDIR 9970
+#endif
+
+#ifndef ENOMEM
+#define ENOMEM 9971
+#endif
+
+#ifndef EPERM
+#define EPERM 9972
+#endif
+
+#ifndef EACCES
+#define EACCES 9973
+#endif
+
+#ifndef EROFS
+#define EROFS 9974
+#endif
+
+#ifndef EDEADLK
+#define EDEADLK 9975
+#endif
+
+#ifndef EAGAIN
+#define EAGAIN 9976
+#endif
+
+#ifndef ENFILE
+#define ENFILE 9977
+#endif
+
+#ifndef EMFILE
+#define EMFILE 9978
+#endif
+
+#ifndef EMLINK
+#define EMLINK 9979
+#endif
+
+#endif // __cplusplus
+
+#endif  // _LIBCPP_ERRNO_H
diff --git a/include/exception b/include/exception
index 5a905e7..186d379 100644
--- a/include/exception
+++ b/include/exception
@@ -80,6 +80,10 @@
 #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
@@ -235,7 +239,7 @@
                                    is_polymorphic<_Ep>::value
                                                    >::type* = 0)
 {
-    const nested_exception* __nep = dynamic_cast<const nested_exception*>(&__e);
+    const nested_exception* __nep = dynamic_cast<const nested_exception*>(_VSTD::addressof(__e));
     if (__nep)
         __nep->rethrow_nested();
 }
@@ -251,4 +255,19 @@
 
 }  // 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 f64a3a9..046a70a 100644
--- a/include/experimental/__config
+++ b/include/experimental/__config
@@ -25,6 +25,10 @@
 #define _LIBCPP_END_NAMESPACE_LFTS  } } }
 #define _VSTD_LFTS _VSTD_EXPERIMENTAL::fundamentals_v1
 
+#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 } } }
diff --git a/include/experimental/__memory b/include/experimental/__memory
new file mode 100644
index 0000000..229fea6
--- /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 ffaa793..3902111 100644
--- a/include/experimental/algorithm
+++ b/include/experimental/algorithm
@@ -53,7 +53,7 @@
 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 a38397a..4c73249 100644
--- a/include/experimental/any
+++ b/include/experimental/any
@@ -82,6 +82,7 @@
 #include <typeinfo>
 #include <type_traits>
 #include <cstdlib>
+#include <cassert>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -92,9 +93,6 @@
 class _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast
 {
 public:
-     //TODO(EricWF) Enable or delete these.
-    //bad_any_cast() _NOEXCEPT;
-    //virtual ~bad_any_cast() _NOEXCEPT;
     virtual const char* what() const _NOEXCEPT;
 };
 
@@ -106,7 +104,7 @@
 #ifndef _LIBCPP_NO_EXCEPTIONS
     throw bad_any_cast();
 #else
-    _VSTD::abort();
+    assert(!"bad_any_cast");
 #endif
 }
 
@@ -115,10 +113,12 @@
 
 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
@@ -187,6 +187,7 @@
       class _ValueType
     , class = __any_imp::_EnableIfNotAny<_ValueType>
     >
+  _LIBCPP_INLINE_VISIBILITY
   any(_ValueType && __value);
 
   _LIBCPP_INLINE_VISIBILITY
@@ -214,6 +215,7 @@
       class _ValueType
     , class = __any_imp::_EnableIfNotAny<_ValueType>
     >
+  _LIBCPP_INLINE_VISIBILITY
   any & operator=(_ValueType && __rhs);
 
   // 6.3.3 any modifiers
@@ -223,6 +225,7 @@
     if (__h) this->__call(_Action::_Destroy);
   }
 
+  _LIBCPP_INLINE_VISIBILITY
   void swap(any & __rhs) _NOEXCEPT;
 
   // 6.3.4 any observers
@@ -459,7 +462,6 @@
 
 
 template <class _ValueType, class>
-_LIBCPP_INLINE_VISIBILITY
 any::any(_ValueType && __v) : __h(nullptr)
 {
   typedef typename decay<_ValueType>::type _Tp;
@@ -470,7 +472,6 @@
 }
 
 template <class _ValueType, class>
-_LIBCPP_INLINE_VISIBILITY
 any & any::operator=(_ValueType && __v)
 {
   typedef typename decay<_ValueType>::type _Tp;
@@ -480,7 +481,7 @@
   return *this;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void any::swap(any & __rhs) _NOEXCEPT
 {
     if (__h && __rhs.__h) {
@@ -552,7 +553,7 @@
 }
 
 template <class _ValueType>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename add_pointer<typename add_const<_ValueType>::type>::type
 any_cast(any const * __any) _NOEXCEPT
 {
@@ -562,7 +563,6 @@
 }
 
 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 0000000..f849574
--- /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 a025862..4a06908 100644
--- a/include/experimental/dynarray
+++ b/include/experimental/dynarray
@@ -137,7 +137,7 @@
 private:
     size_t                  __size_;
     value_type *            __base_;
-    _LIBCPP_ALWAYS_INLINE dynarray () noexcept : __base_(nullptr), __size_(0) {}
+    _LIBCPP_ALWAYS_INLINE dynarray () noexcept :  __size_(0), __base_(nullptr) {}
     
     static inline _LIBCPP_INLINE_VISIBILITY value_type* __allocate ( size_t count )
     {
@@ -159,9 +159,13 @@
 
 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 @@
 //       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 @@
 };
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 dynarray<_Tp>::dynarray(size_type __c) : dynarray ()
 {
     __base_ = __allocate (__c);
@@ -229,7 +234,7 @@
 }
 
 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 @@
 }
 
 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 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray ()
 {
     size_t sz = __d.size();
@@ -263,7 +268,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 dynarray<_Tp>::~dynarray()
 { 
     value_type *__data = data () + __size_;
diff --git a/include/experimental/forward_list b/include/experimental/forward_list
new file mode 100644
index 0000000..55e195f
--- /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 f5a905f..75fc8e9 100644
--- a/include/experimental/functional
+++ b/include/experimental/functional
@@ -20,7 +20,7 @@
 namespace experimental {
 inline namespace fundamentals_v1 {
 
-    // See C++14 §20.9.9, Function object binders
+    // See C++14 20.9.9, Function object binders
     template <class T> constexpr bool is_bind_expression_v
       = is_bind_expression<T>::value;
     template <class T> constexpr int is_placeholder_v
@@ -89,7 +89,12 @@
 
 #include <experimental/__config>
 #include <functional>
+
 #include <algorithm>
+#include <type_traits>
+#include <vector>
+#include <array>
+#include <unordered_map>
 
 #include <__undef_min_max>
 
@@ -101,18 +106,26 @@
 
 _LIBCPP_BEGIN_NAMESPACE_LFTS
 
+#if _LIBCPP_STD_VER > 11
 // default searcher
 template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
+_LIBCPP_TYPE_VIS
 class default_searcher {
 public:
+    _LIBCPP_INLINE_VISIBILITY
     default_searcher(_ForwardIterator __f, _ForwardIterator __l, 
                        _BinaryPredicate __p = _BinaryPredicate())
         : __first_(__f), __last_(__l), __pred_(__p) {}
 
     template <typename _ForwardIterator2>
-    _ForwardIterator2 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const {
-        return _VSTD::search(__f, __l, __first_, __last_, __pred_);
-        }
+    _LIBCPP_INLINE_VISIBILITY
+    pair<_ForwardIterator2, _ForwardIterator2>
+    operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const
+    {
+        return _VSTD::__search(__f, __l, __first_, __last_, __pred_,
+            typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category(),
+            typename _VSTD::iterator_traits<_ForwardIterator2>::iterator_category());
+    }
 
 private:
     _ForwardIterator __first_;
@@ -121,12 +134,325 @@
     };
 
 template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
+_LIBCPP_INLINE_VISIBILITY
 default_searcher<_ForwardIterator, _BinaryPredicate>
 make_default_searcher( _ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate ())
 {
     return default_searcher<_ForwardIterator, _BinaryPredicate>(__f, __l, __p);
 }
 
+template<class _Key, class _Value, class _Hash, class _BinaryPredicate, bool /*useArray*/> class _BMSkipTable;
+
+//  General case for BM data searching; use a map
+template<class _Key, typename _Value, class _Hash, class _BinaryPredicate>
+class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> {
+public: // TODO private:
+    typedef _Value value_type;
+    typedef _Key   key_type;
+
+    const _Value __default_value_;
+    std::unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table;
+    
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    _BMSkipTable(std::size_t __sz, _Value __default, _Hash __hf, _BinaryPredicate __pred)
+        : __default_value_(__default), __table(__sz, __hf, __pred) {}
+    
+    _LIBCPP_INLINE_VISIBILITY
+    void insert(const key_type &__key, value_type __val)
+    {
+        __table [__key] = __val;    // Would skip_.insert (val) be better here?
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type operator [](const key_type & __key) const
+    {
+        auto __it = __table.find (__key);
+        return __it == __table.end() ? __default_value_ : __it->second;
+    }
+};
+    
+
+//  Special case small numeric values; use an array
+template<class _Key, typename _Value, class _Hash, class _BinaryPredicate>
+class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> {
+private:
+    typedef _Value value_type;
+    typedef _Key   key_type;
+
+    typedef typename std::make_unsigned<key_type>::type unsigned_key_type;
+    typedef std::array<value_type, _VSTD::numeric_limits<unsigned_key_type>::max()> skip_map;
+    skip_map __table;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    _BMSkipTable(std::size_t /*__sz*/, _Value __default, _Hash /*__hf*/, _BinaryPredicate /*__pred*/)
+    {
+        std::fill_n(__table.begin(), __table.size(), __default);
+    }
+    
+    _LIBCPP_INLINE_VISIBILITY
+    void insert(key_type __key, value_type __val)
+    {
+        __table[static_cast<unsigned_key_type>(__key)] = __val;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type operator [](key_type __key) const
+    {
+        return __table[static_cast<unsigned_key_type>(__key)];
+    }
+};
+
+
+template <class _RandomAccessIterator1, 
+          class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>, 
+          class _BinaryPredicate = equal_to<>>
+_LIBCPP_TYPE_VIS
+class boyer_moore_searcher {
+private:
+    typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
+    typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type      value_type;
+    typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate,
+                    _VSTD::is_integral<value_type>::value && // what about enums?
+                    sizeof(value_type) == 1 &&
+                    is_same<_Hash, hash<value_type>>::value &&
+                    is_same<_BinaryPredicate, equal_to<>>::value
+            > skip_table_type;
+    
+public:
+    boyer_moore_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, 
+                _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate())
+            : __first_(__f), __last_(__l), __pred_(__pred),
+              __pattern_length_(_VSTD::distance(__first_, __last_)),
+              __skip_{make_shared<skip_table_type>(__pattern_length_, -1, __hf, __pred_)},
+              __suffix_{make_shared<vector<difference_type>>(__pattern_length_ + 1)}
+        {
+    //  build the skip table
+        for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i )
+            __skip_->insert(*__f, __i);
+
+        this->__build_suffix_table ( __first_, __last_, __pred_ );
+        }
+        
+    template <typename _RandomAccessIterator2>
+    pair<_RandomAccessIterator2, _RandomAccessIterator2>
+    operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
+    {
+        static_assert ( std::is_same<
+                typename std::decay<typename std::iterator_traits<_RandomAccessIterator1>::value_type>::type, 
+                typename std::decay<typename std::iterator_traits<_RandomAccessIterator2>::value_type>::type
+                    >::value,
+                "Corpus and Pattern iterators must point to the same type" );
+
+        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 make_pair(__l, __l);
+
+    //  Do the search 
+        return this->__search(__f, __l);
+    }
+        
+public: // TODO private:
+    _RandomAccessIterator1               __first_;
+    _RandomAccessIterator1               __last_;
+    _BinaryPredicate                     __pred_;
+    difference_type                      __pattern_length_;
+    shared_ptr<skip_table_type>          __skip_;
+    shared_ptr<vector<difference_type>>  __suffix_;
+
+    template <typename _RandomAccessIterator2>
+    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();
+        const vector<difference_type> & __suffix = *__suffix_.get();
+        
+        while (__cur <= __last)
+        {
+
+        //  Do we match right where we are?
+            difference_type __j = __pattern_length_;
+            while (__pred_(__first_ [__j-1], __cur [__j-1])) {
+                __j--;
+            //  We matched - we're done!
+                if ( __j == 0 )
+                    return make_pair(__cur, __cur + __pattern_length_);
+                }
+            
+        //  Since we didn't match, figure out how far to skip forward
+            difference_type __k = __skip[__cur [ __j - 1 ]];
+            difference_type __m = __j - __k - 1;
+            if (__k < __j && __m > __suffix[ __j ])
+                __cur += __m;
+            else
+                __cur += __suffix[ __j ];
+        }
+    
+        return make_pair(__l, __l);     // We didn't find anything
+    }
+
+
+    template<typename _Iterator, typename _Container>
+    void __compute_bm_prefix ( _Iterator __f, _Iterator __l, _BinaryPredicate __pred, _Container &__prefix )
+    {
+        const std::size_t __count = _VSTD::distance(__f, __l);
+                        
+        __prefix[0] = 0;
+        std::size_t __k = 0;
+        for ( std::size_t __i = 1; __i < __count; ++__i )
+        {
+            while ( __k > 0 && !__pred ( __f[__k], __f[__i] ))
+                __k = __prefix [ __k - 1 ];
+                
+            if ( __pred ( __f[__k], __f[__i] ))
+                __k++;
+            __prefix [ __i ] = __k;
+        }
+    }
+
+    void __build_suffix_table(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, 
+                                                    _BinaryPredicate __pred)
+    {
+        const std::size_t __count = _VSTD::distance(__f, __l);
+        vector<difference_type> & __suffix = *__suffix_.get();
+        if (__count > 0)
+        {
+            _VSTD::vector<value_type> __scratch(__count);
+            
+            __compute_bm_prefix(__f, __l, __pred, __scratch);
+            for ( std::size_t __i = 0; __i <= __count; __i++ )
+                __suffix[__i] = __count - __scratch[__count-1];
+    
+            typedef _VSTD::reverse_iterator<_RandomAccessIterator1> _RevIter;
+            __compute_bm_prefix(_RevIter(__l), _RevIter(__f), __pred, __scratch);
+     
+            for ( std::size_t __i = 0; __i < __count; __i++ )
+            {
+                const std::size_t     __j = __count - __scratch[__i];
+                const difference_type __k = __i     - __scratch[__i] + 1;
+     
+                if (__suffix[__j] > __k)
+                    __suffix[__j] = __k;
+            }
+        }
+    }
+
+};
+
+template<class _RandomAccessIterator, 
+         class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>, 
+         class _BinaryPredicate = equal_to<>>
+_LIBCPP_INLINE_VISIBILITY
+boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
+make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, 
+                    _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
+{
+    return boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p);
+}
+
+// boyer-moore-horspool
+template <class _RandomAccessIterator1, 
+          class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>, 
+          class _BinaryPredicate = equal_to<>>
+_LIBCPP_TYPE_VIS
+class boyer_moore_horspool_searcher {
+private:
+    typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
+    typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type      value_type;
+    typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate,
+                    _VSTD::is_integral<value_type>::value && // what about enums?
+                    sizeof(value_type) == 1 &&
+                    is_same<_Hash, hash<value_type>>::value &&
+                    is_same<_BinaryPredicate, equal_to<>>::value
+            > skip_table_type;
+
+public:
+    boyer_moore_horspool_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, 
+                _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate())
+            : __first_(__f), __last_(__l), __pred_(__pred),
+              __pattern_length_(_VSTD::distance(__first_, __last_)),
+              __skip_{_VSTD::make_shared<skip_table_type>(__pattern_length_, __pattern_length_, __hf, __pred_)}
+        {
+    //  build the skip table
+            if ( __f != __l )
+            {
+                __l = __l - 1;
+                for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i )
+                    __skip_->insert(*__f, __pattern_length_ - 1 - __i);
+            }
+        }
+            
+    template <typename _RandomAccessIterator2>
+    pair<_RandomAccessIterator2, _RandomAccessIterator2>
+    operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
+    {
+        static_assert ( std::is_same<
+                typename std::decay<typename std::iterator_traits<_RandomAccessIterator1>::value_type>::type, 
+                typename std::decay<typename std::iterator_traits<_RandomAccessIterator2>::value_type>::type
+                    >::value,
+                "Corpus and Pattern iterators must point to the same type" );
+
+        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 make_pair(__l, __l);
+
+    //  Do the search 
+        return this->__search(__f, __l);
+    }
+        
+private:
+    _RandomAccessIterator1      __first_;
+    _RandomAccessIterator1      __last_;
+    _BinaryPredicate            __pred_;
+    difference_type             __pattern_length_;
+    shared_ptr<skip_table_type> __skip_;
+
+    template <typename _RandomAccessIterator2>
+    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();
+
+        while (__cur <= __last)
+        {
+        //  Do we match right where we are?
+            difference_type __j = __pattern_length_;
+            while (__pred_(__first_[__j-1], __cur[__j-1]))
+            {
+                __j--;
+            //  We matched - we're done!
+                if ( __j == 0 )
+                    return make_pair(__cur, __cur + __pattern_length_);
+            }
+            __cur += __skip[__cur[__pattern_length_-1]];
+        }
+        
+        return make_pair(__l, __l);
+    }
+};
+
+template<class _RandomAccessIterator, 
+         class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>, 
+         class _BinaryPredicate = equal_to<>>
+_LIBCPP_INLINE_VISIBILITY
+boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
+make_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, 
+                    _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
+{
+    return boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p);
+}
+
+#endif // _LIBCPP_STD_VER > 11
 
 _LIBCPP_END_NAMESPACE_LFTS
 
diff --git a/include/experimental/iterator b/include/experimental/iterator
new file mode 100644
index 0000000..da593fe
--- /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 0000000..1678ee3
--- /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 0000000..cff2c5e
--- /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 0000000..f54ef0b
--- /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 &) = default;
+
+    // 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/regex b/include/experimental/regex
new file mode 100644
index 0000000..d38891c
--- /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 0000000..20cf6d4
--- /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 0000000..8b85451
--- /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 2a20d7c..93f77f3 100644
--- a/include/experimental/string_view
+++ b/include/experimental/string_view
@@ -227,7 +227,7 @@
         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
@@ -413,7 +413,7 @@
         _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 +428,7 @@
         _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 +436,7 @@
         _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 +445,7 @@
         _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 +460,7 @@
         _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 +468,7 @@
         _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 +477,7 @@
         _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 +489,7 @@
         _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 +497,7 @@
         _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 +506,7 @@
         _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 +518,7 @@
         _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 +526,7 @@
         _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 +535,7 @@
         _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 +550,7 @@
         _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 +558,7 @@
         _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 +567,7 @@
         _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 +582,7 @@
         _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 +590,7 @@
         _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 50d1e05..e00d2ec 100644
--- a/include/experimental/tuple
+++ b/include/experimental/tuple
@@ -57,9 +57,10 @@
 
 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 0000000..1f998c2
--- /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 0000000..d00a837
--- /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 0000000..bd10492
--- /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 31fcedf..5e1e9f5 100644
--- a/include/ext/hash_map
+++ b/include/ext/hash_map
@@ -309,7 +309,7 @@
 {
     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:
@@ -368,7 +368,6 @@
 {
     _HashIterator __i_;
 
-    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;
     typedef const typename _HashIterator::value_type::first_type key_type;
     typedef typename _HashIterator::value_type::second_type      mapped_type;
 public:
@@ -376,13 +375,8 @@
     typedef pair<key_type, mapped_type>                          value_type;
     typedef typename _HashIterator::difference_type              difference_type;
     typedef value_type&                                          reference;
-    typedef typename __pointer_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<value_type>
-#else
-            rebind<value_type>::other
-#endif
-                                                                 pointer;
+    typedef typename __rebind_pointer<typename _HashIterator::pointer, value_type>::type
+        pointer;
 
     _LIBCPP_INLINE_VISIBILITY __hash_map_iterator() {}
 
@@ -419,7 +413,6 @@
 {
     _HashIterator __i_;
 
-    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;
     typedef const typename _HashIterator::value_type::first_type key_type;
     typedef typename _HashIterator::value_type::second_type      mapped_type;
 public:
@@ -427,13 +420,8 @@
     typedef pair<key_type, mapped_type>                          value_type;
     typedef typename _HashIterator::difference_type              difference_type;
     typedef const value_type&                                    reference;
-    typedef typename __pointer_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<const value_type>
-#else
-            rebind<const value_type>::other
-#endif
-                                                                 pointer;
+    typedef typename __rebind_pointer<typename _HashIterator::pointer, const value_type>::type
+        pointer;
 
     _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator() {}
 
@@ -561,6 +549,7 @@
     _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
@@ -681,12 +670,12 @@
     __h.get_deleter().__first_constructed = true;
     __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
     __h.get_deleter().__second_constructed = true;
-    return _VSTD::move(__h);  // explicitly moved for C++03
+    return _LIBCPP_EXPLICIT_MOVE(__h);  // explicitly moved for C++03
 }
 
 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)
@@ -832,6 +821,7 @@
     _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
@@ -939,7 +929,7 @@
 
 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 c4bb898..91850b5 100644
--- a/include/ext/hash_set
+++ b/include/ext/hash_set
@@ -282,6 +282,7 @@
     _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 @@
 
 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 @@
     _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 @@
 
 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/float.h b/include/float.h
new file mode 100644
index 0000000..1acfdc6
--- /dev/null
+++ b/include/float.h
@@ -0,0 +1,83 @@
+// -*- C++ -*-
+//===--------------------------- float.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_FLOAT_H
+#define _LIBCPP_FLOAT_H
+
+/*
+    float.h synopsis
+
+Macros:
+
+    FLT_ROUNDS
+    FLT_EVAL_METHOD     // C99
+    FLT_RADIX
+
+    FLT_MANT_DIG
+    DBL_MANT_DIG
+    LDBL_MANT_DIG
+
+    DECIMAL_DIG         // C99
+
+    FLT_DIG
+    DBL_DIG
+    LDBL_DIG
+
+    FLT_MIN_EXP
+    DBL_MIN_EXP
+    LDBL_MIN_EXP
+
+    FLT_MIN_10_EXP
+    DBL_MIN_10_EXP
+    LDBL_MIN_10_EXP
+
+    FLT_MAX_EXP
+    DBL_MAX_EXP
+    LDBL_MAX_EXP
+
+    FLT_MAX_10_EXP
+    DBL_MAX_10_EXP
+    LDBL_MAX_10_EXP
+
+    FLT_MAX
+    DBL_MAX
+    LDBL_MAX
+
+    FLT_EPSILON
+    DBL_EPSILON
+    LDBL_EPSILON
+
+    FLT_MIN
+    DBL_MIN
+    LDBL_MIN
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <float.h>
+
+#ifdef __cplusplus
+
+#ifndef FLT_EVAL_METHOD
+#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
+#endif
+
+#ifndef DECIMAL_DIG
+#define DECIMAL_DIG __DECIMAL_DIG__
+#endif
+
+#endif // __cplusplus
+
+#endif  // _LIBCPP_FLOAT_H
diff --git a/include/forward_list b/include/forward_list
index 8a87fc5..18b300d 100644
--- a/include/forward_list
+++ b/include/forward_list
@@ -183,29 +183,77 @@
 _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>
 struct _LIBCPP_HIDDEN __begin_node_of
 {
-    typedef __forward_begin_node
-        <
-             typename pointer_traits<_VoidPtr>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-                 rebind<__forward_list_node<_Tp, _VoidPtr> >
-#else
-                 rebind<__forward_list_node<_Tp, _VoidPtr> >::other
-#endif
-         > type;
+    typedef __forward_begin_node<
+        typename __rebind_pointer<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> >::type
+    > type;
 };
 
 template <class _Tp, class _VoidPtr>
@@ -217,49 +265,68 @@
     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
-    explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
+    __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(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;
-    typedef typename pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<value_type>
-#else
-            rebind<value_type>::other
-#endif
-                                                              pointer;
+    typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer;
 
     _LIBCPP_INLINE_VISIBILITY
     __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
@@ -283,40 +350,49 @@
 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;
 
-    __node_const_pointer __ptr_;
+    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;
+
+    __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) {}
 
-    typedef typename remove_const
-        <
-            typename pointer_traits<__node_const_pointer>::element_type
-        >::type                                               __node;
-    typedef typename pointer_traits<__node_const_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<__node>
-#else
-            rebind<__node>::other
-#endif
-                                                              __node_pointer;
+    _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)) {}
+
 
     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 pointer_traits<__node_const_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<const value_type>
-#else
-            rebind<const value_type>::other
-#endif
+    typedef typename __rebind_pointer<__node_pointer, const value_type>::type
                                                               pointer;
 
     _LIBCPP_INLINE_VISIBILITY
@@ -326,14 +402,15 @@
         : __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
@@ -367,21 +444,21 @@
     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
@@ -403,8 +480,10 @@
 
 #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
 
@@ -429,6 +508,7 @@
               __node_traits::propagate_on_container_move_assignment::value>());}
 
 public:
+    _LIBCPP_INLINE_VISIBILITY
     void swap(__forward_list_base& __x)
 #if _LIBCPP_STD_VER >= 14
         _NOEXCEPT;
@@ -462,7 +542,7 @@
 #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_))
@@ -471,7 +551,7 @@
 }
 
 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))
@@ -492,7 +572,7 @@
 }
 
 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
@@ -529,14 +609,18 @@
 {
     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;
     typedef _Alloc allocator_type;
 
+    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
+                  "Allocator::value_type must be same type as value_type");
+
     typedef value_type&                                                reference;
     typedef const value_type&                                          const_reference;
     typedef typename allocator_traits<allocator_type>::pointer         pointer;
@@ -551,6 +635,7 @@
     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
@@ -587,12 +672,14 @@
 
     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
 
@@ -605,6 +692,7 @@
         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
 
@@ -735,7 +823,7 @@
     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:
@@ -758,7 +846,7 @@
 };
 
 template <class _Tp, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
     : base(__a)
 {
@@ -772,8 +860,8 @@
         __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_));
@@ -793,8 +881,8 @@
         __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_));
@@ -932,7 +1020,7 @@
 }
 
 template <class _Tp, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 forward_list<_Tp, _Alloc>&
 forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
     _NOEXCEPT_(
@@ -949,7 +1037,7 @@
 #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)
 {
@@ -997,7 +1085,7 @@
 #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)
 {
@@ -1070,7 +1158,7 @@
 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));
@@ -1087,7 +1175,7 @@
 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));
@@ -1103,7 +1191,7 @@
 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));
@@ -1118,7 +1206,7 @@
 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();
@@ -1153,7 +1241,7 @@
 #endif  // _LIBCPP_NO_EXCEPTIONS
         __last->__next_ = __r->__next_;
         __r->__next_ = __first;
-        __r = __last;
+        __r = static_cast<__begin_node_pointer>(__last);
     }
     return iterator(__r);
 }
@@ -1168,7 +1256,7 @@
 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();
@@ -1203,7 +1291,7 @@
 #endif  // _LIBCPP_NO_EXCEPTIONS
         __last->__next_ = __r->__next_;
         __r->__next_ = __first;
-        __r = __last;
+        __r = static_cast<__begin_node_pointer>(__last);
     }
     return iterator(__r);
 }
@@ -1212,7 +1300,7 @@
 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();
@@ -1225,21 +1313,22 @@
 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);
         }
     }
@@ -1266,8 +1355,8 @@
             __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_));
@@ -1298,8 +1387,8 @@
             __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);
@@ -1317,14 +1406,14 @@
 {
     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;
     }
 }
@@ -1338,9 +1427,9 @@
     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();
     }
 }
 
@@ -1353,13 +1442,13 @@
     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();
         }
     }
 }
@@ -1403,9 +1492,9 @@
 {
     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)
@@ -1426,9 +1515,9 @@
 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)
@@ -1453,7 +1542,7 @@
         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;
     }
@@ -1520,7 +1609,7 @@
 
 template <class _Tp, class _Alloc>
 template <class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 forward_list<_Tp, _Alloc>::sort(_Compare __comp)
 {
@@ -1551,7 +1640,7 @@
     }
     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 1f289ed..d51da45 100644
--- a/include/fstream
+++ b/include/fstream
@@ -200,14 +200,17 @@
 
     // 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 @@
 }
 
 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 @@
 }
 
 template <class _CharT, class _Traits>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 basic_filebuf<_CharT, _Traits>::is_open() const
 {
@@ -547,7 +550,7 @@
 }
 
 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)
 {
@@ -1008,26 +1011,35 @@
     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 +1047,7 @@
 };
 
 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 +1055,7 @@
 
 #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 +1064,7 @@
 }
 
 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 +1076,7 @@
 #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 +1085,7 @@
 }
 
 template <class _CharT, class _Traits>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 basic_ifstream<_CharT, _Traits>&
 basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs)
 {
@@ -1085,7 +1097,7 @@
 #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 +1114,7 @@
 }
 
 template <class _CharT, class _Traits>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 basic_filebuf<_CharT, _Traits>*
 basic_ifstream<_CharT, _Traits>::rdbuf() const
 {
@@ -1110,7 +1122,7 @@
 }
 
 template <class _CharT, class _Traits>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 basic_ifstream<_CharT, _Traits>::is_open() const
 {
@@ -1140,7 +1152,7 @@
 #endif
 
 template <class _CharT, class _Traits>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 basic_ifstream<_CharT, _Traits>::close()
 {
@@ -1161,24 +1173,33 @@
     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 +1207,7 @@
 };
 
 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 +1215,7 @@
 
 #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 +1224,7 @@
 }
 
 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 +1236,7 @@
 #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 +1245,7 @@
 }
 
 template <class _CharT, class _Traits>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 basic_ofstream<_CharT, _Traits>&
 basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs)
 {
@@ -1236,7 +1257,7 @@
 #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 +1274,7 @@
 }
 
 template <class _CharT, class _Traits>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 basic_filebuf<_CharT, _Traits>*
 basic_ofstream<_CharT, _Traits>::rdbuf() const
 {
@@ -1261,7 +1282,7 @@
 }
 
 template <class _CharT, class _Traits>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 basic_ofstream<_CharT, _Traits>::is_open() const
 {
@@ -1291,7 +1312,7 @@
 #endif
 
 template <class _CharT, class _Traits>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 basic_ofstream<_CharT, _Traits>::close()
 {
@@ -1312,26 +1333,35 @@
     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 +1369,7 @@
 };
 
 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 +1377,7 @@
 
 #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 +1386,7 @@
 }
 
 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 +1398,7 @@
 #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 +1407,7 @@
 }
 
 template <class _CharT, class _Traits>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 basic_fstream<_CharT, _Traits>&
 basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs)
 {
@@ -1389,7 +1419,7 @@
 #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 +1436,7 @@
 }
 
 template <class _CharT, class _Traits>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 basic_filebuf<_CharT, _Traits>*
 basic_fstream<_CharT, _Traits>::rdbuf() const
 {
@@ -1414,7 +1444,7 @@
 }
 
 template <class _CharT, class _Traits>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 basic_fstream<_CharT, _Traits>::is_open() const
 {
@@ -1444,7 +1474,7 @@
 #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 6c57de0..4fcd4b5 100644
--- a/include/functional
+++ b/include/functional
@@ -407,7 +407,7 @@
     // 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;
@@ -1249,7 +1249,7 @@
     type __f_;
 
 public:
-    _LIBCPP_INLINE_VISIBILITY __mem_fn(type __f) : __f_(__f) {}
+    _LIBCPP_INLINE_VISIBILITY __mem_fn(type __f) _NOEXCEPT : __f_(__f) {}
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
     // invoke
@@ -1262,29 +1262,109 @@
 #else
 
     template <class _A0>
+    _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return0<type, _A0>::type
     operator() (_A0& __a0) const {
         return __invoke(__f_, __a0);
     }
 
+    template <class _A0>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return0<type, _A0 const>::type
+    operator() (_A0 const& __a0) const {
+        return __invoke(__f_, __a0);
+    }
+
     template <class _A0, class _A1>
+    _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return1<type, _A0, _A1>::type
     operator() (_A0& __a0, _A1& __a1) const {
         return __invoke(__f_, __a0, __a1);
     }
 
+    template <class _A0, class _A1>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return1<type, _A0 const, _A1>::type
+    operator() (_A0 const& __a0, _A1& __a1) const {
+        return __invoke(__f_, __a0, __a1);
+    }
+
+    template <class _A0, class _A1>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return1<type, _A0, _A1 const>::type
+    operator() (_A0& __a0, _A1 const& __a1) const {
+        return __invoke(__f_, __a0, __a1);
+    }
+
+    template <class _A0, class _A1>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return1<type, _A0 const, _A1 const>::type
+    operator() (_A0 const& __a0, _A1 const& __a1) const {
+        return __invoke(__f_, __a0, __a1);
+    }
+
     template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0, _A1, _A2>::type
     operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
         return __invoke(__f_, __a0, __a1, __a2);
     }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0 const, _A1, _A2>::type
+    operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const {
+        return __invoke(__f_, __a0, __a1, __a2);
+    }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0, _A1 const, _A2>::type
+    operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const {
+        return __invoke(__f_, __a0, __a1, __a2);
+    }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0, _A1, _A2 const>::type
+    operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const {
+        return __invoke(__f_, __a0, __a1, __a2);
+    }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type
+    operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const {
+        return __invoke(__f_, __a0, __a1, __a2);
+    }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type
+    operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const {
+        return __invoke(__f_, __a0, __a1, __a2);
+    }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type
+    operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const {
+        return __invoke(__f_, __a0, __a1, __a2);
+    }
+
+    template <class _A0, class _A1, class _A2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type
+    operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const {
+        return __invoke(__f_, __a0, __a1, __a2);
+    }
 #endif
 };
 
 template<class _Rp, class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
 __mem_fn<_Rp _Tp::*>
-mem_fn(_Rp _Tp::* __pm)
+mem_fn(_Rp _Tp::* __pm) _NOEXCEPT
 {
     return __mem_fn<_Rp _Tp::*>(__pm);
 }
@@ -1327,6 +1407,22 @@
 {
 };
 
+template <class _Fp>
+_LIBCPP_INLINE_VISIBILITY
+bool __not_null(_Fp const&) { return true; }
+
+template <class _Fp>
+_LIBCPP_INLINE_VISIBILITY
+bool __not_null(_Fp* __ptr) { return __ptr; }
+
+template <class _Ret, class _Class>
+_LIBCPP_INLINE_VISIBILITY
+bool __not_null(_Ret _Class::*__ptr) { return __ptr; }
+
+template <class _Fp>
+_LIBCPP_INLINE_VISIBILITY
+bool __not_null(function<_Fp> const& __f) { return !!__f; }
+
 } // namespace __function
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
@@ -1468,27 +1564,9 @@
     typename aligned_storage<3*sizeof(void*)>::type __buf_;
     __base* __f_;
 
-    template <class _Fp>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(const _Fp&) {return true;}
-    template <class _R2, class ..._Ap>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (*__p)(_Ap...)) {return __p;}
-    template <class _R2, class _Cp, class ..._Ap>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)(_Ap...)) {return __p;}
-    template <class _R2, class _Cp, class ..._Ap>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const) {return __p;}
-    template <class _R2, class _Cp, class ..._Ap>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)(_Ap...) volatile) {return __p;}
-    template <class _R2, class _Cp, class ..._Ap>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const volatile) {return __p;}
-    template <class _R2, class ..._Ap>
-        _LIBCPP_INLINE_VISIBILITY
-        static bool __not_null(const function<_R2(_Ap...)>& __p) {return !!__p;}
+    _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>
@@ -1552,10 +1630,13 @@
 
     // 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
@@ -1583,9 +1664,9 @@
 {
     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
@@ -1599,9 +1680,9 @@
 {
     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
@@ -1613,9 +1694,9 @@
 {
     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
@@ -1632,9 +1713,9 @@
 {
     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
@@ -1654,13 +1735,12 @@
                                      >::type*)
     : __f_(0)
 {
-    if (__not_null(__f))
+    if (__function::__not_null(__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
         {
@@ -1681,7 +1761,7 @@
     : __f_(0)
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    if (__not_null(__f))
+    if (__function::__not_null(__f))
     {
         typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF;
         typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
@@ -1689,8 +1769,7 @@
         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
         {
@@ -1714,16 +1793,16 @@
 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
@@ -1738,7 +1817,7 @@
 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();
@@ -1763,7 +1842,7 @@
 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();
@@ -1773,34 +1852,34 @@
 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_);
@@ -2394,6 +2473,22 @@
 {
 };
 
+#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>
diff --git a/include/future b/include/future
index 5b5afe6..957a23c 100644
--- a/include/future
+++ b/include/future
@@ -512,6 +512,16 @@
     virtual ~future_error() _NOEXCEPT;
 };
 
+inline _LIBCPP_ALWAYS_INLINE
+void __throw_future_error(future_errc _Ev)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    throw future_error(make_error_code(_Ev));
+#else
+    assert(!"future_error");
+#endif
+}
+
 class _LIBCPP_TYPE_VIS __assoc_sub_state
     : public __shared_count
 {
@@ -566,6 +576,7 @@
     void wait();
     template <class _Rep, class _Period>
         future_status
+        _LIBCPP_INLINE_VISIBILITY
         wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
     template <class _Clock, class _Duration>
         future_status
@@ -589,7 +600,7 @@
 }
 
 template <class _Rep, class _Period>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 future_status
 __assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
 {
@@ -645,10 +656,8 @@
 #endif
 {
     unique_lock<mutex> __lk(this->__mut_);
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (this->__has_value())
-        throw future_error(make_error_code(future_errc::promise_already_satisfied));
-#endif
+        __throw_future_error(future_errc::promise_already_satisfied);
     ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
     this->__state_ |= base::__constructed | base::ready;
     __cv_.notify_all();
@@ -664,10 +673,8 @@
 #endif
 {
     unique_lock<mutex> __lk(this->__mut_);
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (this->__has_value())
-        throw future_error(make_error_code(future_errc::promise_already_satisfied));
-#endif
+        __throw_future_error(future_errc::promise_already_satisfied);
     ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
     this->__state_ |= base::__constructed;
     __thread_local_data()->__make_ready_at_thread_exit(this);
@@ -725,10 +732,8 @@
 __assoc_state<_Rp&>::set_value(_Rp& __arg)
 {
     unique_lock<mutex> __lk(this->__mut_);
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (this->__has_value())
-        throw future_error(make_error_code(future_errc::promise_already_satisfied));
-#endif
+        __throw_future_error(future_errc::promise_already_satisfied);
     __value_ = _VSTD::addressof(__arg);
     this->__state_ |= base::__constructed | base::ready;
     __cv_.notify_all();
@@ -739,10 +744,8 @@
 __assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
 {
     unique_lock<mutex> __lk(this->__mut_);
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (this->__has_value())
-        throw future_error(make_error_code(future_errc::promise_already_satisfied));
-#endif
+        __throw_future_error(future_errc::promise_already_satisfied);
     __value_ = _VSTD::addressof(__arg);
     this->__state_ |= base::__constructed;
     __thread_local_data()->__make_ready_at_thread_exit(this);
@@ -849,6 +852,7 @@
 
 public:
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     explicit __deferred_assoc_state(_Fp&& __f);
 #endif
 
@@ -858,7 +862,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Rp, class _Fp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
     : __func_(_VSTD::forward<_Fp>(__f))
 {
@@ -895,6 +899,7 @@
 
 public:
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     explicit __deferred_assoc_state(_Fp&& __f);
 #endif
 
@@ -904,7 +909,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Fp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
     : __func_(_VSTD::forward<_Fp>(__f))
 {
@@ -943,6 +948,7 @@
     virtual void __on_zero_shared() _NOEXCEPT;
 public:
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     explicit __async_assoc_state(_Fp&& __f);
 #endif
 
@@ -952,7 +958,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Rp, class _Fp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
     : __func_(_VSTD::forward<_Fp>(__f))
 {
@@ -997,6 +1003,7 @@
     virtual void __on_zero_shared() _NOEXCEPT;
 public:
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     explicit __async_assoc_state(_Fp&& __f);
 #endif
 
@@ -1006,7 +1013,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Fp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
     : __func_(_VSTD::forward<_Fp>(__f))
 {
@@ -1108,6 +1115,7 @@
 public:
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     ~future();
+    _LIBCPP_INLINE_VISIBILITY
     shared_future<_Rp> share();
 
     // retrieving the value
@@ -1138,10 +1146,8 @@
 future<_Rp>::future(__assoc_state<_Rp>* __state)
     : __state_(__state)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__state_->__has_future_attached())
-        throw future_error(make_error_code(future_errc::future_already_retrieved));
-#endif
+        __throw_future_error(future_errc::future_already_retrieved);
     __state_->__add_shared();
     __state_->__set_future_attached();
 }
@@ -1212,6 +1218,7 @@
 public:
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     ~future();
+    _LIBCPP_INLINE_VISIBILITY
     shared_future<_Rp&> share();
 
     // retrieving the value
@@ -1242,10 +1249,8 @@
 future<_Rp&>::future(__assoc_state<_Rp&>* __state)
     : __state_(__state)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__state_->__has_future_attached())
-        throw future_error(make_error_code(future_errc::future_already_retrieved));
-#endif
+        __throw_future_error(future_errc::future_already_retrieved);
     __state_->__add_shared();
     __state_->__set_future_attached();
 }
@@ -1311,6 +1316,7 @@
 public:
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     ~future();
+    _LIBCPP_INLINE_VISIBILITY
     shared_future<void> share();
 
     // retrieving the value
@@ -1445,10 +1451,8 @@
 future<_Rp>
 promise<_Rp>::get_future()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
-#endif
+        __throw_future_error(future_errc::no_state);
     return future<_Rp>(__state_);
 }
 
@@ -1456,10 +1460,8 @@
 void
 promise<_Rp>::set_value(const _Rp& __r)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
-#endif
+        __throw_future_error(future_errc::no_state);
     __state_->set_value(__r);
 }
 
@@ -1469,10 +1471,8 @@
 void
 promise<_Rp>::set_value(_Rp&& __r)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
-#endif
+        __throw_future_error(future_errc::no_state);
     __state_->set_value(_VSTD::move(__r));
 }
 
@@ -1482,10 +1482,9 @@
 void
 promise<_Rp>::set_exception(exception_ptr __p)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
     if (__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
-#endif
+        __throw_future_error(future_errc::no_state);
     __state_->set_exception(__p);
 }
 
@@ -1493,10 +1492,8 @@
 void
 promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
-#endif
+        __throw_future_error(future_errc::no_state);
     __state_->set_value_at_thread_exit(__r);
 }
 
@@ -1506,10 +1503,8 @@
 void
 promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
-#endif
+        __throw_future_error(future_errc::no_state);
     __state_->set_value_at_thread_exit(_VSTD::move(__r));
 }
 
@@ -1519,10 +1514,8 @@
 void
 promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
-#endif
+        __throw_future_error(future_errc::no_state);
     __state_->set_exception_at_thread_exit(__p);
 }
 
@@ -1619,10 +1612,8 @@
 future<_Rp&>
 promise<_Rp&>::get_future()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
-#endif
+        __throw_future_error(future_errc::no_state);
     return future<_Rp&>(__state_);
 }
 
@@ -1630,10 +1621,8 @@
 void
 promise<_Rp&>::set_value(_Rp& __r)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
-#endif
+        __throw_future_error(future_errc::no_state);
     __state_->set_value(__r);
 }
 
@@ -1641,10 +1630,9 @@
 void
 promise<_Rp&>::set_exception(exception_ptr __p)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
     if (__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
-#endif
+        __throw_future_error(future_errc::no_state);
     __state_->set_exception(__p);
 }
 
@@ -1652,10 +1640,8 @@
 void
 promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
-#endif
+        __throw_future_error(future_errc::no_state);
     __state_->set_value_at_thread_exit(__r);
 }
 
@@ -1663,10 +1649,8 @@
 void
 promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
-#endif
+        __throw_future_error(future_errc::no_state);
     __state_->set_exception_at_thread_exit(__p);
 }
 
@@ -1861,6 +1845,7 @@
 
     void swap(__packaged_task_function&) _NOEXCEPT;
 
+    _LIBCPP_INLINE_VISIBILITY
     _Rp operator()(_ArgTypes...) const;
 };
 
@@ -2000,7 +1985,7 @@
 }
 
 template<class _Rp, class ..._ArgTypes>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _Rp
 __packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
 {
@@ -2087,11 +2072,11 @@
 void
 packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__p_.__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
+        __throw_future_error(future_errc::no_state);
     if (__p_.__state_->__has_value())
-        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+        __throw_future_error(future_errc::promise_already_satisfied);
+#ifndef _LIBCPP_NO_EXCEPTIONS
     try
     {
 #endif  // _LIBCPP_NO_EXCEPTIONS
@@ -2109,11 +2094,11 @@
 void
 packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__p_.__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
+        __throw_future_error(future_errc::no_state);
     if (__p_.__state_->__has_value())
-        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+        __throw_future_error(future_errc::promise_already_satisfied);
+#ifndef _LIBCPP_NO_EXCEPTIONS
     try
     {
 #endif  // _LIBCPP_NO_EXCEPTIONS
@@ -2131,10 +2116,8 @@
 void
 packaged_task<_Rp(_ArgTypes...)>::reset()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (!valid())
-        throw future_error(make_error_code(future_errc::no_state));
-#endif  // _LIBCPP_NO_EXCEPTIONS
+        __throw_future_error(future_errc::no_state);
     __p_ = promise<result_type>();
 }
 
@@ -2218,11 +2201,11 @@
 void
 packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__p_.__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
+        __throw_future_error(future_errc::no_state);
     if (__p_.__state_->__has_value())
-        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+        __throw_future_error(future_errc::promise_already_satisfied);
+#ifndef _LIBCPP_NO_EXCEPTIONS
     try
     {
 #endif  // _LIBCPP_NO_EXCEPTIONS
@@ -2241,11 +2224,11 @@
 void
 packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (__p_.__state_ == nullptr)
-        throw future_error(make_error_code(future_errc::no_state));
+        __throw_future_error(future_errc::no_state);
     if (__p_.__state_->__has_value())
-        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+        __throw_future_error(future_errc::promise_already_satisfied);
+#ifndef _LIBCPP_NO_EXCEPTIONS
     try
     {
 #endif  // _LIBCPP_NO_EXCEPTIONS
@@ -2264,10 +2247,8 @@
 void
 packaged_task<void(_ArgTypes...)>::reset()
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (!valid())
-        throw future_error(make_error_code(future_errc::no_state));
-#endif  // _LIBCPP_NO_EXCEPTIONS
+        __throw_future_error(future_errc::no_state);
     __p_ = promise<result_type>();
 }
 
@@ -2592,7 +2573,7 @@
 }
 
 template <class _Rp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 shared_future<_Rp>
 future<_Rp>::share()
 {
@@ -2600,7 +2581,7 @@
 }
 
 template <class _Rp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 shared_future<_Rp&>
 future<_Rp&>::share()
 {
@@ -2609,7 +2590,7 @@
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 shared_future<void>
 future<void>::share()
 {
diff --git a/include/inttypes.h b/include/inttypes.h
new file mode 100644
index 0000000..5c5618b
--- /dev/null
+++ b/include/inttypes.h
@@ -0,0 +1,251 @@
+// -*- C++ -*-
+//===--------------------------- inttypes.h -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_INTTYPES_H
+#define _LIBCPP_INTTYPES_H
+
+/*
+    inttypes.h synopsis
+
+This entire header is C99 / C++0X
+
+#include <stdint.h>  // <cinttypes> includes <cstdint>
+
+Macros:
+
+    PRId8
+    PRId16
+    PRId32
+    PRId64
+
+    PRIdLEAST8
+    PRIdLEAST16
+    PRIdLEAST32
+    PRIdLEAST64
+
+    PRIdFAST8
+    PRIdFAST16
+    PRIdFAST32
+    PRIdFAST64
+
+    PRIdMAX
+    PRIdPTR
+
+    PRIi8
+    PRIi16
+    PRIi32
+    PRIi64
+
+    PRIiLEAST8
+    PRIiLEAST16
+    PRIiLEAST32
+    PRIiLEAST64
+
+    PRIiFAST8
+    PRIiFAST16
+    PRIiFAST32
+    PRIiFAST64
+
+    PRIiMAX
+    PRIiPTR
+
+    PRIo8
+    PRIo16
+    PRIo32
+    PRIo64
+
+    PRIoLEAST8
+    PRIoLEAST16
+    PRIoLEAST32
+    PRIoLEAST64
+
+    PRIoFAST8
+    PRIoFAST16
+    PRIoFAST32
+    PRIoFAST64
+
+    PRIoMAX
+    PRIoPTR
+
+    PRIu8
+    PRIu16
+    PRIu32
+    PRIu64
+
+    PRIuLEAST8
+    PRIuLEAST16
+    PRIuLEAST32
+    PRIuLEAST64
+
+    PRIuFAST8
+    PRIuFAST16
+    PRIuFAST32
+    PRIuFAST64
+
+    PRIuMAX
+    PRIuPTR
+
+    PRIx8
+    PRIx16
+    PRIx32
+    PRIx64
+
+    PRIxLEAST8
+    PRIxLEAST16
+    PRIxLEAST32
+    PRIxLEAST64
+
+    PRIxFAST8
+    PRIxFAST16
+    PRIxFAST32
+    PRIxFAST64
+
+    PRIxMAX
+    PRIxPTR
+
+    PRIX8
+    PRIX16
+    PRIX32
+    PRIX64
+
+    PRIXLEAST8
+    PRIXLEAST16
+    PRIXLEAST32
+    PRIXLEAST64
+
+    PRIXFAST8
+    PRIXFAST16
+    PRIXFAST32
+    PRIXFAST64
+
+    PRIXMAX
+    PRIXPTR
+
+    SCNd8
+    SCNd16
+    SCNd32
+    SCNd64
+
+    SCNdLEAST8
+    SCNdLEAST16
+    SCNdLEAST32
+    SCNdLEAST64
+
+    SCNdFAST8
+    SCNdFAST16
+    SCNdFAST32
+    SCNdFAST64
+
+    SCNdMAX
+    SCNdPTR
+
+    SCNi8
+    SCNi16
+    SCNi32
+    SCNi64
+
+    SCNiLEAST8
+    SCNiLEAST16
+    SCNiLEAST32
+    SCNiLEAST64
+
+    SCNiFAST8
+    SCNiFAST16
+    SCNiFAST32
+    SCNiFAST64
+
+    SCNiMAX
+    SCNiPTR
+
+    SCNo8
+    SCNo16
+    SCNo32
+    SCNo64
+
+    SCNoLEAST8
+    SCNoLEAST16
+    SCNoLEAST32
+    SCNoLEAST64
+
+    SCNoFAST8
+    SCNoFAST16
+    SCNoFAST32
+    SCNoFAST64
+
+    SCNoMAX
+    SCNoPTR
+
+    SCNu8
+    SCNu16
+    SCNu32
+    SCNu64
+
+    SCNuLEAST8
+    SCNuLEAST16
+    SCNuLEAST32
+    SCNuLEAST64
+
+    SCNuFAST8
+    SCNuFAST16
+    SCNuFAST32
+    SCNuFAST64
+
+    SCNuMAX
+    SCNuPTR
+
+    SCNx8
+    SCNx16
+    SCNx32
+    SCNx64
+
+    SCNxLEAST8
+    SCNxLEAST16
+    SCNxLEAST32
+    SCNxLEAST64
+
+    SCNxFAST8
+    SCNxFAST16
+    SCNxFAST32
+    SCNxFAST64
+
+    SCNxMAX
+    SCNxPTR
+
+Types:
+
+    imaxdiv_t
+
+intmax_t  imaxabs(intmax_t j);
+imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom);
+intmax_t  strtoimax(const char* restrict nptr, char** restrict endptr, int base);
+uintmax_t strtoumax(const char* restrict nptr, char** restrict endptr, int base);
+intmax_t  wcstoimax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);
+uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <inttypes.h>
+
+#ifdef __cplusplus
+
+#include <stdint.h>
+
+#undef imaxabs
+#undef imaxdiv
+
+#endif // __cplusplus
+
+#endif  // _LIBCPP_INTTYPES_H
diff --git a/include/ios b/include/ios
index ff79998..cbea478 100644
--- a/include/ios
+++ b/include/ios
@@ -114,9 +114,9 @@
 public:
     // types:
     typedef charT char_type;
-    typedef typename traits::int_type int_type;
-    typedef typename traits::pos_type pos_type;
-    typedef typename traits::off_type off_type;
+    typedef typename traits::int_type int_type;  // removed in C++17
+    typedef typename traits::pos_type pos_type;  // removed in C++17
+    typedef typename traits::off_type off_type;  // removed in C++17
     typedef traits traits_type;
 
     operator unspecified-bool-type() const;
@@ -216,7 +216,7 @@
 #include <__locale>
 #include <system_error>
 
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
 #include <atomic>     // for __xindex_
 #endif
 
@@ -231,7 +231,7 @@
 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;
@@ -254,14 +254,12 @@
     static const fmtflags floatfield  = scientific | fixed;
 
     typedef unsigned int iostate;
-    typedef iostate      io_state;
     static const iostate badbit  = 0x1;
     static const iostate eofbit  = 0x2;
     static const iostate failbit = 0x4;
     static const iostate goodbit = 0x0;
 
     typedef unsigned int openmode;
-    typedef openmode     open_mode;
     static const openmode app    = 0x01;
     static const openmode ate    = 0x02;
     static const openmode binary = 0x04;
@@ -270,10 +268,15 @@
     static const openmode trunc  = 0x20;
 
     enum seekdir {beg, cur, end};
-    typedef seekdir seek_dir;
+
+#if _LIBCPP_STD_VER <= 14
+    typedef iostate      io_state;
+    typedef openmode     open_mode;
+    typedef seekdir      seek_dir;
 
     typedef _VSTD::streamoff streamoff;
     typedef _VSTD::streampos streampos;
+#endif
 
     class _LIBCPP_TYPE_VIS Init;
 
@@ -367,7 +370,9 @@
     int*            __index_;
     size_t          __event_size_;
     size_t          __event_cap_;
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+// 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)
     static atomic<int> __xindex_;
 #else
     static int      __xindex_;
diff --git a/include/iosfwd b/include/iosfwd
index eccfd34..e4149ef 100644
--- a/include/iosfwd
+++ b/include/iosfwd
@@ -194,6 +194,11 @@
 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 168a4d0..0bcc7ee 100644
--- a/include/istream
+++ b/include/istream
@@ -1407,6 +1407,7 @@
     try
     {
 #endif  // _LIBCPP_NO_EXCEPTIONS
+        this->clear(this->rdstate() & ~ios_base::eofbit);
         sentry __sen(*this, true);
         if (__sen)
         {
diff --git a/include/iterator b/include/iterator
index 9ac4351..15be793 100644
--- a/include/iterator
+++ b/include/iterator
@@ -340,10 +340,10 @@
 */
 
 #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>
@@ -437,6 +437,12 @@
 template <class _Tp>
 struct __is_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {};
 
+template <class _Tp>
+struct __is_exactly_input_iterator
+    : public integral_constant<bool, 
+    	 __has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value && 
+    	!__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {};
+
 template<class _Category, class _Tp, class _Distance = ptrdiff_t,
          class _Pointer = _Tp*, class _Reference = _Tp&>
 struct _LIBCPP_TYPE_VIS_ONLY iterator
@@ -513,12 +519,12 @@
     return __distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
 }
 
-template <class _ForwardIter>
+template <class _InputIter>
 inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIter
-next(_ForwardIter __x,
-     typename iterator_traits<_ForwardIter>::difference_type __n = 1,
-     typename enable_if<__is_forward_iterator<_ForwardIter>::value>::type* = 0)
+_InputIter
+next(_InputIter __x,
+     typename iterator_traits<_InputIter>::difference_type __n = 1,
+     typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0)
 {
     _VSTD::advance(__x, __n);
     return __x;
@@ -766,14 +772,14 @@
     _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_))
@@ -805,9 +811,9 @@
     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_;
@@ -943,9 +949,14 @@
     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
@@ -958,10 +969,7 @@
     _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;}
@@ -1181,7 +1189,7 @@
         _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
     {
@@ -1406,6 +1414,23 @@
     return __x;
 }
 
+template <class _Iter>
+struct __libcpp_is_trivial_iterator
+	: public _LIBCPP_BOOL_CONSTANT(is_pointer<_Iter>::value) {};
+	
+template <class _Iter>
+struct __libcpp_is_trivial_iterator<move_iterator<_Iter> >
+	: public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
+
+template <class _Iter>
+struct __libcpp_is_trivial_iterator<reverse_iterator<_Iter> >
+	: public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
+
+template <class _Iter>
+struct __libcpp_is_trivial_iterator<__wrap_iter<_Iter> >
+	: public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
+
+
 template <class _Tp, size_t _Np>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp*
diff --git a/include/limits b/include/limits
index ce967ea..80a1be4 100644
--- a/include/limits
+++ b/include/limits
@@ -237,7 +237,8 @@
     static _LIBCPP_CONSTEXPR const bool is_bounded = true;
     static _LIBCPP_CONSTEXPR const bool is_modulo = !_VSTD::is_signed<_Tp>::value;
 
-#if defined(__i386__) || defined(__x86_64__) || defined(__pnacl__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__pnacl__) || \
+    defined(__wasm__)
     static _LIBCPP_CONSTEXPR const bool traps = true;
 #else
     static _LIBCPP_CONSTEXPR const bool traps = false;
diff --git a/include/list b/include/list
index 14201a8..cff0a85 100644
--- a/include/list
+++ b/include/list
@@ -175,6 +175,7 @@
 #include <initializer_list>
 #include <iterator>
 #include <algorithm>
+#include <type_traits>
 
 #include <__undef_min_max>
 
@@ -187,34 +188,66 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class _VoidPtr> struct __list_node;
+template <class _Tp, class _VoidPtr> struct __list_node_base;
+
+template <class _Tp, class _VoidPtr>
+struct __list_node_pointer_traits {
+  typedef typename __rebind_pointer<_VoidPtr, __list_node<_Tp, _VoidPtr> >::type
+        __node_pointer;
+  typedef typename __rebind_pointer<_VoidPtr, __list_node_base<_Tp, _VoidPtr> >::type
+        __base_pointer;
+
+#if defined(_LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB)
+  typedef __base_pointer __link_pointer;
+#else
+  typedef typename conditional<
+          is_pointer<_VoidPtr>::value,
+          __base_pointer,
+          __node_pointer
+  >::type __link_pointer;
+#endif
+
+  typedef typename conditional<
+          is_same<__link_pointer, __node_pointer>::value,
+          __base_pointer,
+          __node_pointer
+  >::type __non_link_pointer;
+
+  static _LIBCPP_INLINE_VISIBILITY
+  __link_pointer __unsafe_link_pointer_cast(__link_pointer __p) {
+      return __p;
+  }
+
+  static _LIBCPP_INLINE_VISIBILITY
+  __link_pointer __unsafe_link_pointer_cast(__non_link_pointer __p) {
+      return static_cast<__link_pointer>(static_cast<_VoidPtr>(__p));
+  }
+
+};
 
 template <class _Tp, class _VoidPtr>
 struct __list_node_base
 {
-    typedef typename pointer_traits<_VoidPtr>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-        rebind<__list_node<_Tp, _VoidPtr> > pointer;
-#else
-        rebind<__list_node<_Tp, _VoidPtr> >::other pointer;
-#endif
+    typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits;
+    typedef typename _NodeTraits::__node_pointer __node_pointer;
+    typedef typename _NodeTraits::__base_pointer __base_pointer;
+    typedef typename _NodeTraits::__link_pointer __link_pointer;
 
-    typedef typename pointer_traits<_VoidPtr>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-        rebind<__list_node_base> __base_pointer;
-#else
-        rebind<__list_node_base>::other __base_pointer;
-#endif
-
-    pointer __prev_;
-    pointer __next_;
+    __link_pointer __prev_;
+    __link_pointer __next_;
 
     _LIBCPP_INLINE_VISIBILITY
-    __list_node_base() : __prev_(__self()), __next_(__self()) {}
+    __list_node_base() : __prev_(_NodeTraits::__unsafe_link_pointer_cast(__self())),
+                         __next_(_NodeTraits::__unsafe_link_pointer_cast(__self())) {}
 
     _LIBCPP_INLINE_VISIBILITY
-    pointer __self()
-    {
-        return static_cast<pointer>(pointer_traits<__base_pointer>::pointer_to(*this));
+    __base_pointer __self() {
+        return pointer_traits<__base_pointer>::pointer_to(*this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __node_pointer __as_node() {
+        return static_cast<__node_pointer>(__self());
     }
 };
 
@@ -223,6 +256,14 @@
     : public __list_node_base<_Tp, _VoidPtr>
 {
     _Tp __value_;
+
+    typedef __list_node_base<_Tp, _VoidPtr> __base;
+    typedef typename __base::__link_pointer __link_pointer;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __link_pointer __as_link() {
+        return static_cast<__link_pointer>(__base::__self());
+    }
 };
 
 template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TYPE_VIS_ONLY list;
@@ -232,25 +273,21 @@
 template <class _Tp, class _VoidPtr>
 class _LIBCPP_TYPE_VIS_ONLY __list_iterator
 {
-    typedef typename pointer_traits<_VoidPtr>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-        rebind<__list_node<_Tp, _VoidPtr> > __node_pointer;
-#else
-        rebind<__list_node<_Tp, _VoidPtr> >::other __node_pointer;
-#endif
+    typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits;
+    typedef typename _NodeTraits::__link_pointer __link_pointer;
 
-    __node_pointer __ptr_;
+    __link_pointer __ptr_;
 
 #if _LIBCPP_DEBUG_LEVEL >= 2
     _LIBCPP_INLINE_VISIBILITY
-    explicit __list_iterator(__node_pointer __p, const void* __c) _NOEXCEPT
+    explicit __list_iterator(__link_pointer __p, const void* __c) _NOEXCEPT
         : __ptr_(__p)
     {
         __get_db()->__insert_ic(this, __c);
     }
 #else
     _LIBCPP_INLINE_VISIBILITY
-    explicit __list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
+    explicit __list_iterator(__link_pointer __p) _NOEXCEPT : __ptr_(__p) {}
 #endif
 
 
@@ -262,13 +299,7 @@
     typedef bidirectional_iterator_tag       iterator_category;
     typedef _Tp                              value_type;
     typedef value_type&                      reference;
-    typedef typename pointer_traits<_VoidPtr>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<value_type>
-#else
-            rebind<value_type>::other
-#endif
-                                             pointer;
+    typedef typename __rebind_pointer<_VoidPtr, value_type>::type pointer;
     typedef typename pointer_traits<pointer>::difference_type difference_type;
 
     _LIBCPP_INLINE_VISIBILITY
@@ -314,7 +345,7 @@
         _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
                        "Attempted to dereference a non-dereferenceable list::iterator");
 #endif
-        return __ptr_->__value_;
+        return __ptr_->__as_node()->__value_;
     }
     _LIBCPP_INLINE_VISIBILITY
     pointer operator->() const
@@ -323,7 +354,7 @@
         _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
                        "Attempted to dereference a non-dereferenceable list::iterator");
 #endif
-        return pointer_traits<pointer>::pointer_to(__ptr_->__value_);
+        return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_);
     }
 
     _LIBCPP_INLINE_VISIBILITY
@@ -365,25 +396,21 @@
 template <class _Tp, class _VoidPtr>
 class _LIBCPP_TYPE_VIS_ONLY __list_const_iterator
 {
-    typedef typename pointer_traits<_VoidPtr>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-        rebind<__list_node<_Tp, _VoidPtr> > __node_pointer;
-#else
-        rebind<__list_node<_Tp, _VoidPtr> >::other __node_pointer;
-#endif
+    typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits;
+    typedef typename _NodeTraits::__link_pointer __link_pointer;
 
-    __node_pointer __ptr_;
+    __link_pointer __ptr_;
 
 #if _LIBCPP_DEBUG_LEVEL >= 2
     _LIBCPP_INLINE_VISIBILITY
-    explicit __list_const_iterator(__node_pointer __p, const void* __c) _NOEXCEPT
+    explicit __list_const_iterator(__link_pointer __p, const void* __c) _NOEXCEPT
         : __ptr_(__p)
     {
         __get_db()->__insert_ic(this, __c);
     }
 #else
     _LIBCPP_INLINE_VISIBILITY
-    explicit __list_const_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
+    explicit __list_const_iterator(__link_pointer __p) _NOEXCEPT : __ptr_(__p) {}
 #endif
 
     template<class, class> friend class list;
@@ -392,13 +419,7 @@
     typedef bidirectional_iterator_tag       iterator_category;
     typedef _Tp                              value_type;
     typedef const value_type&                reference;
-    typedef typename pointer_traits<_VoidPtr>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<const value_type>
-#else
-            rebind<const value_type>::other
-#endif
-                                             pointer;
+    typedef typename __rebind_pointer<_VoidPtr, const value_type>::type pointer;
     typedef typename pointer_traits<pointer>::difference_type difference_type;
 
     _LIBCPP_INLINE_VISIBILITY
@@ -451,7 +472,7 @@
         _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
                        "Attempted to dereference a non-dereferenceable list::const_iterator");
 #endif
-        return __ptr_->__value_;
+        return __ptr_->__as_node()->__value_;
     }
     _LIBCPP_INLINE_VISIBILITY
     pointer operator->() const
@@ -460,7 +481,7 @@
         _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
                        "Attempted to dereference a non-dereferenceable list::iterator");
 #endif
-        return pointer_traits<pointer>::pointer_to(__ptr_->__value_);
+        return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_);
     }
 
     _LIBCPP_INLINE_VISIBILITY
@@ -518,6 +539,9 @@
     typedef allocator_traits<__node_allocator>                       __node_alloc_traits;
     typedef typename __node_alloc_traits::pointer                    __node_pointer;
     typedef typename __node_alloc_traits::pointer                    __node_const_pointer;
+    typedef __list_node_pointer_traits<value_type, __void_pointer> __node_pointer_traits;
+    typedef typename __node_pointer_traits::__link_pointer __link_pointer;
+    typedef __link_pointer __link_const_pointer;
     typedef typename __alloc_traits::pointer                         pointer;
     typedef typename __alloc_traits::const_pointer                   const_pointer;
     typedef typename __alloc_traits::difference_type                 difference_type;
@@ -529,6 +553,12 @@
     __compressed_pair<size_type, __node_allocator> __size_alloc_;
 
     _LIBCPP_INLINE_VISIBILITY
+    __link_pointer __end_as_link() const _NOEXCEPT {
+        return __node_pointer_traits::__unsafe_link_pointer_cast(
+                const_cast<__node_base&>(__end_).__self());
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
           size_type& __sz() _NOEXCEPT {return __size_alloc_.first();}
     _LIBCPP_INLINE_VISIBILITY
     const size_type& __sz() const _NOEXCEPT
@@ -540,10 +570,13 @@
     const __node_allocator& __node_alloc() const _NOEXCEPT
         {return __size_alloc_.second();}
 
-    static void __unlink_nodes(__node_pointer __f, __node_pointer __l) _NOEXCEPT;
+    _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;
@@ -572,22 +605,18 @@
     iterator end() _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
-        return iterator(static_cast<__node_pointer>(
-                pointer_traits<__node_base_pointer>::pointer_to(__end_)), this);
+        return iterator(__end_as_link(), this);
 #else
-        return iterator(static_cast<__node_pointer>(
-                      pointer_traits<__node_base_pointer>::pointer_to(__end_)));
+        return iterator(__end_as_link());
 #endif
     }
     _LIBCPP_INLINE_VISIBILITY
     const_iterator end() const _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
-        return const_iterator(static_cast<__node_const_pointer>(
-        pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(__end_))), this);
+        return const_iterator(__end_as_link(), this);
 #else
-        return const_iterator(static_cast<__node_const_pointer>(
-        pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(__end_))));
+        return const_iterator(__end_as_link());
 #endif
     }
 
@@ -640,9 +669,9 @@
 
 // Unlink nodes [__f, __l]
 template <class _Tp, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
-__list_imp<_Tp, _Alloc>::__unlink_nodes(__node_pointer __f, __node_pointer __l)
+__list_imp<_Tp, _Alloc>::__unlink_nodes(__link_pointer __f, __link_pointer __l)
     _NOEXCEPT
 {
     __f->__prev_->__next_ = __l->__next_;
@@ -650,7 +679,7 @@
 }
 
 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)
@@ -658,7 +687,7 @@
 }
 
 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))
 {
@@ -680,17 +709,16 @@
     if (!empty())
     {
         __node_allocator& __na = __node_alloc();
-        __node_pointer __f = __end_.__next_;
-        __node_pointer __l = static_cast<__node_pointer>(
-                       pointer_traits<__node_base_pointer>::pointer_to(__end_));
+        __link_pointer __f = __end_.__next_;
+        __link_pointer __l = __end_as_link();
         __unlink_nodes(__f, __l->__prev_);
         __sz() = 0;
         while (__f != __l)
         {
-            __node_pointer __n = __f;
+            __node_pointer __np = __f->__as_node();
             __f = __f->__next_;
-            __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
-            __node_alloc_traits::deallocate(__na, __n, 1);
+            __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
+            __node_alloc_traits::deallocate(__na, __np, 1);
         }
 #if _LIBCPP_DEBUG_LEVEL >= 2
         __c_node* __c = __get_db()->__find_c_and_lock(this);
@@ -729,13 +757,13 @@
     swap(__sz(), __c.__sz());
     swap(__end_, __c.__end_);
     if (__sz() == 0)
-        __end_.__next_ = __end_.__prev_ = __end_.__self();
+        __end_.__next_ = __end_.__prev_ = __end_as_link();
     else
-        __end_.__prev_->__next_ = __end_.__next_->__prev_ = __end_.__self();
+        __end_.__prev_->__next_ = __end_.__next_->__prev_ = __end_as_link();
     if (__c.__sz() == 0)
-        __c.__end_.__next_ = __c.__end_.__prev_ = __c.__end_.__self();
+        __c.__end_.__next_ = __c.__end_.__prev_ = __c.__end_as_link();
     else
-        __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_.__self();
+        __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_as_link();
 
 #if _LIBCPP_DEBUG_LEVEL >= 2
     __libcpp_db* __db = __get_db();
@@ -748,8 +776,7 @@
     {
         --__p;
         const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
-        if (__i->__ptr_ == static_cast<__node_pointer>(
-                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))
+        if (__i->__ptr_ == __c.__end_as_link())
         {
             __cn2->__add(*__p);
             if (--__cn1->end_ != __p)
@@ -762,8 +789,7 @@
     {
         --__p;
         const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
-        if (__i->__ptr_ == static_cast<__node_pointer>(
-                       pointer_traits<__node_base_pointer>::pointer_to(__end_)))
+        if (__i->__ptr_ == __end_as_link())
         {
             __cn1->__add(*__p);
             if (--__cn2->end_ != __p)
@@ -787,6 +813,7 @@
     typedef typename base::__node_alloc_traits __node_alloc_traits;
     typedef typename base::__node_base         __node_base;
     typedef typename base::__node_base_pointer __node_base_pointer;
+    typedef typename base::__link_pointer __link_pointer;
 
 public:
     typedef _Tp                                      value_type;
@@ -834,15 +861,19 @@
 
     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 &&
@@ -864,6 +895,7 @@
         {assign(__il.begin(), __il.end());}
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
+    _LIBCPP_INLINE_VISIBILITY
     allocator_type get_allocator() const _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
@@ -910,25 +942,25 @@
     reference front()
     {
         _LIBCPP_ASSERT(!empty(), "list::front called on empty list");
-        return base::__end_.__next_->__value_;
+        return base::__end_.__next_->__as_node()->__value_;
     }
     _LIBCPP_INLINE_VISIBILITY
     const_reference front() const
     {
         _LIBCPP_ASSERT(!empty(), "list::front called on empty list");
-        return base::__end_.__next_->__value_;
+        return base::__end_.__next_->__as_node()->__value_;
     }
     _LIBCPP_INLINE_VISIBILITY
     reference back()
     {
         _LIBCPP_ASSERT(!empty(), "list::back called on empty list");
-        return base::__end_.__prev_->__value_;
+        return base::__end_.__prev_->__as_node()->__value_;
     }
     _LIBCPP_INLINE_VISIBILITY
     const_reference back() const
     {
         _LIBCPP_ASSERT(!empty(), "list::back called on empty list");
-        return base::__end_.__prev_->__value_;
+        return base::__end_.__prev_->__as_node()->__value_;
     }
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1000,9 +1032,11 @@
 
     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
@@ -1015,8 +1049,10 @@
     _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;
@@ -1033,9 +1069,12 @@
 #endif  // _LIBCPP_DEBUG_LEVEL >= 2
 
 private:
-    static void __link_nodes  (__node_pointer __p, __node_pointer __f, __node_pointer __l);
-    void __link_nodes_at_front(__node_pointer __f, __node_pointer __l);
-    void __link_nodes_at_back (__node_pointer __f, __node_pointer __l);
+    _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>
         static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp);
@@ -1047,9 +1086,9 @@
 
 // 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(__node_pointer __p, __node_pointer __f, __node_pointer __l)
+list<_Tp, _Alloc>::__link_nodes(__link_pointer __p, __link_pointer __f, __link_pointer __l)
 {
     __p->__prev_->__next_ = __f;
     __f->__prev_ = __p->__prev_;
@@ -1059,11 +1098,11 @@
 
 // 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(__node_pointer __f, __node_pointer __l)
+list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l)
 {
-    __f->__prev_ = base::__end_.__self();
+    __f->__prev_ = base::__end_as_link();
     __l->__next_ = base::__end_.__next_;
     __l->__next_->__prev_ = __l;
     base::__end_.__next_ = __f;
@@ -1071,11 +1110,11 @@
 
 // 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(__node_pointer __f, __node_pointer __l)
+list<_Tp, _Alloc>::__link_nodes_at_back(__link_pointer __f, __link_pointer __l)
 {
-    __l->__next_ = base::__end_.__self();
+    __l->__next_ = base::__end_as_link();
     __f->__prev_ = base::__end_.__prev_;
     __f->__prev_->__next_ = __f;
     base::__end_.__prev_ = __l;
@@ -1083,7 +1122,7 @@
 
 
 template <class _Tp, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename list<_Tp, _Alloc>::iterator
 list<_Tp, _Alloc>::__iterator(size_type __n)
 {
@@ -1219,7 +1258,7 @@
 #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)
 {
@@ -1234,7 +1273,7 @@
 #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())))
@@ -1246,7 +1285,7 @@
 }
 
 template <class _Tp, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 list<_Tp, _Alloc>::list(list&& __c, const allocator_type& __a)
     : base(__a)
 {
@@ -1263,7 +1302,7 @@
 }
 
 template <class _Tp, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 list<_Tp, _Alloc>&
 list<_Tp, _Alloc>::operator=(list&& __c)
         _NOEXCEPT_(
@@ -1331,7 +1370,7 @@
 }
 
 template <class _Tp, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _Alloc
 list<_Tp, _Alloc>::get_allocator() const _NOEXCEPT
 {
@@ -1352,12 +1391,12 @@
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __hold->__prev_ = 0;
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
-    __link_nodes(__p.__ptr_, __hold.get(), __hold.get());
+    __link_nodes(__p.__ptr_, __hold->__as_link(), __hold->__as_link());
     ++base::__sz();
 #if _LIBCPP_DEBUG_LEVEL >= 2
-    return iterator(__hold.release(), this);
+    return iterator(__hold.release()->__as_link(), this);
 #else
-    return iterator(__hold.release());
+    return iterator(__hold.release()->__as_link());
 #endif
 }
 
@@ -1383,9 +1422,9 @@
         __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
         ++__ds;
 #if _LIBCPP_DEBUG_LEVEL >= 2
-        __r = iterator(__hold.get(), this);
+        __r = iterator(__hold->__as_link(), this);
 #else
-        __r = iterator(__hold.get());
+        __r = iterator(__hold->__as_link());
 #endif
         __hold.release();
         iterator __e = __r;
@@ -1397,7 +1436,7 @@
             {
                 __hold.reset(__node_alloc_traits::allocate(__na, 1));
                 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
-                __e.__ptr_->__next_ = __hold.get();
+                __e.__ptr_->__next_ = __hold->__as_link();
                 __hold->__prev_ = __e.__ptr_;
                 __hold.release();
             }
@@ -1408,8 +1447,8 @@
             while (true)
             {
                 __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));
-                __node_pointer __prev = __e.__ptr_->__prev_;
-                __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
+                __link_pointer __prev = __e.__ptr_->__prev_;
+                __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
                 if (__prev == 0)
                     break;
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1451,9 +1490,9 @@
         __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f);
         ++__ds;
 #if _LIBCPP_DEBUG_LEVEL >= 2
-        __r = iterator(__hold.get(), this);
+        __r = iterator(__hold.get()->__as_link(), this);
 #else
-        __r = iterator(__hold.get());
+        __r = iterator(__hold.get()->__as_link());
 #endif
         __hold.release();
         iterator __e = __r;
@@ -1465,7 +1504,7 @@
             {
                 __hold.reset(__node_alloc_traits::allocate(__na, 1));
                 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f);
-                __e.__ptr_->__next_ = __hold.get();
+                __e.__ptr_->__next_ = __hold.get()->__as_link();
                 __hold->__prev_ = __e.__ptr_;
                 __hold.release();
             }
@@ -1476,8 +1515,8 @@
             while (true)
             {
                 __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));
-                __node_pointer __prev = __e.__ptr_->__prev_;
-                __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
+                __link_pointer __prev = __e.__ptr_->__prev_;
+                __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
                 if (__prev == 0)
                     break;
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1503,7 +1542,8 @@
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
-    __link_nodes_at_front(__hold.get(), __hold.get());
+    __link_pointer __nl = __hold->__as_link();
+    __link_nodes_at_front(__nl, __nl);
     ++base::__sz();
     __hold.release();
 }
@@ -1516,7 +1556,7 @@
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
-    __link_nodes_at_back(__hold.get(), __hold.get());
+    __link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link());
     ++base::__sz();
     __hold.release();
 }
@@ -1531,7 +1571,7 @@
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
-    __link_nodes_at_front(__hold.get(), __hold.get());
+    __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link());
     ++base::__sz();
     __hold.release();
 }
@@ -1544,7 +1584,7 @@
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
-    __link_nodes_at_back(__hold.get(), __hold.get());
+    __link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link());
     ++base::__sz();
     __hold.release();
 }
@@ -1560,7 +1600,7 @@
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
-    __link_nodes_at_front(__hold.get(), __hold.get());
+    __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link());
     ++base::__sz();
     __hold.release();
 }
@@ -1574,7 +1614,8 @@
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
-    __link_nodes_at_back(__hold.get(), __hold.get());
+    __link_pointer __nl = __hold->__as_link();
+    __link_nodes_at_back(__nl, __nl);
     ++base::__sz();
     __hold.release();
 }
@@ -1594,12 +1635,14 @@
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __hold->__prev_ = 0;
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
-    __link_nodes(__p.__ptr_, __hold.get(), __hold.get());
+    __link_pointer __nl = __hold.get()->__as_link();
+    __link_nodes(__p.__ptr_, __nl, __nl);
     ++base::__sz();
+    __hold.release();
 #if _LIBCPP_DEBUG_LEVEL >= 2
-    return iterator(__hold.release(), this);
+    return iterator(__nl, this);
 #else
-    return iterator(__hold.release());
+    return iterator(__nl);
 #endif
 }
 
@@ -1619,12 +1662,14 @@
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __hold->__prev_ = 0;
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
-    __link_nodes(__p.__ptr_, __hold.get(), __hold.get());
+    __link_pointer __nl = __hold->__as_link();
+    __link_nodes(__p.__ptr_, __nl, __nl);
     ++base::__sz();
+    __hold.release();
 #if _LIBCPP_DEBUG_LEVEL >= 2
-    return iterator(__hold.release(), this);
+    return iterator(__nl, this);
 #else
-    return iterator(__hold.release());
+    return iterator(__nl);
 #endif
 }
 
@@ -1636,7 +1681,7 @@
 {
     _LIBCPP_ASSERT(!empty(), "list::pop_front() called with empty list");
     __node_allocator& __na = base::__node_alloc();
-    __node_pointer __n = base::__end_.__next_;
+    __link_pointer __n = base::__end_.__next_;
     base::__unlink_nodes(__n, __n);
     --base::__sz();
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1654,8 +1699,9 @@
     }
     __get_db()->unlock();
 #endif
-    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
-    __node_alloc_traits::deallocate(__na, __n, 1);
+    __node_pointer __np = __n->__as_node();
+    __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
+    __node_alloc_traits::deallocate(__na, __np, 1);
 }
 
 template <class _Tp, class _Alloc>
@@ -1664,7 +1710,7 @@
 {
     _LIBCPP_ASSERT(!empty(), "list::pop_back() called with empty list");
     __node_allocator& __na = base::__node_alloc();
-    __node_pointer __n = base::__end_.__prev_;
+    __link_pointer __n = base::__end_.__prev_;
     base::__unlink_nodes(__n, __n);
     --base::__sz();
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1682,8 +1728,9 @@
     }
     __get_db()->unlock();
 #endif
-    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
-    __node_alloc_traits::deallocate(__na, __n, 1);
+    __node_pointer __np = __n->__as_node();
+    __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
+    __node_alloc_traits::deallocate(__na, __np, 1);
 }
 
 template <class _Tp, class _Alloc>
@@ -1698,8 +1745,8 @@
     _LIBCPP_ASSERT(__p != end(),
         "list::erase(iterator) called with a non-dereferenceable iterator");
     __node_allocator& __na = base::__node_alloc();
-    __node_pointer __n = __p.__ptr_;
-    __node_pointer __r = __n->__next_;
+    __link_pointer __n = __p.__ptr_;
+    __link_pointer __r = __n->__next_;
     base::__unlink_nodes(__n, __n);
     --base::__sz();
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1717,8 +1764,9 @@
     }
     __get_db()->unlock();
 #endif
-    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
-    __node_alloc_traits::deallocate(__na, __n, 1);
+    __node_pointer __np = __n->__as_node();
+    __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
+    __node_alloc_traits::deallocate(__na, __np, 1);
 #if _LIBCPP_DEBUG_LEVEL >= 2
     return iterator(__r, this);
 #else
@@ -1741,7 +1789,7 @@
         base::__unlink_nodes(__f.__ptr_, __l.__ptr_->__prev_);
         while (__f != __l)
         {
-            __node_pointer __n = __f.__ptr_;
+            __link_pointer __n = __f.__ptr_;
             ++__f;
             --base::__sz();
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1759,8 +1807,9 @@
             }
             __get_db()->unlock();
 #endif
-            __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
-            __node_alloc_traits::deallocate(__na, __n, 1);
+            __node_pointer __np = __n->__as_node();
+            __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
+            __node_alloc_traits::deallocate(__na, __np, 1);
         }
     }
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1787,9 +1836,9 @@
         __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_));
         ++__ds;
 #if _LIBCPP_DEBUG_LEVEL >= 2
-        iterator __r = iterator(__hold.release(), this);
+        iterator __r = iterator(__hold.release()->__as_link(), this);
 #else
-        iterator __r = iterator(__hold.release());
+        iterator __r = iterator(__hold.release()->__as_link());
 #endif
         iterator __e = __r;
 #ifndef _LIBCPP_NO_EXCEPTIONS
@@ -1800,7 +1849,7 @@
             {
                 __hold.reset(__node_alloc_traits::allocate(__na, 1));
                 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_));
-                __e.__ptr_->__next_ = __hold.get();
+                __e.__ptr_->__next_ = __hold.get()->__as_link();
                 __hold->__prev_ = __e.__ptr_;
                 __hold.release();
             }
@@ -1811,8 +1860,8 @@
             while (true)
             {
                 __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));
-                __node_pointer __prev = __e.__ptr_->__prev_;
-                __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
+                __link_pointer __prev = __e.__ptr_->__prev_;
+                __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
                 if (__prev == 0)
                     break;
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1845,10 +1894,11 @@
         __hold->__prev_ = 0;
         __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
         ++__ds;
+        __link_pointer __nl = __hold.release()->__as_link();
 #if _LIBCPP_DEBUG_LEVEL >= 2
-        iterator __r = iterator(__hold.release(), this);
+        iterator __r = iterator(__nl, this);
 #else
-        iterator __r = iterator(__hold.release());
+        iterator __r = iterator(__nl);
 #endif
         iterator __e = __r;
 #ifndef _LIBCPP_NO_EXCEPTIONS
@@ -1859,7 +1909,7 @@
             {
                 __hold.reset(__node_alloc_traits::allocate(__na, 1));
                 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
-                __e.__ptr_->__next_ = __hold.get();
+                __e.__ptr_->__next_ = __hold.get()->__as_link();
                 __hold->__prev_ = __e.__ptr_;
                 __hold.release();
             }
@@ -1870,8 +1920,8 @@
             while (true)
             {
                 __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));
-                __node_pointer __prev = __e.__ptr_->__prev_;
-                __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
+                __link_pointer __prev = __e.__ptr_->__prev_;
+                __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
                 if (__prev == 0)
                     break;
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1883,8 +1933,7 @@
             throw;
         }
 #endif  // _LIBCPP_NO_EXCEPTIONS
-        __link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::
-                         pointer_to(base::__end_)), __r.__ptr_, __e.__ptr_);
+        __link_nodes(base::__end_as_link(), __r.__ptr_, __e.__ptr_);
         base::__sz() += __ds;
     }
 }
@@ -1902,8 +1951,8 @@
 #endif
     if (!__c.empty())
     {
-        __node_pointer __f = __c.__end_.__next_;
-        __node_pointer __l = __c.__end_.__prev_;
+        __link_pointer __f = __c.__end_.__next_;
+        __link_pointer __l = __c.__end_.__prev_;
         base::__unlink_nodes(__f, __l);
         __link_nodes(__p.__ptr_, __f, __l);
         base::__sz() += __c.__sz();
@@ -1916,8 +1965,7 @@
         {
             --__p;
             iterator* __i = static_cast<iterator*>((*__p)->__i_);
-            if (__i->__ptr_ != static_cast<__node_pointer>(
-                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))
+            if (__i->__ptr_ != __c.__end_as_link())
             {
                 __cn1->__add(*__p);
                 (*__p)->__c_ = __cn1;
@@ -1947,7 +1995,7 @@
 #endif
     if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_)
     {
-        __node_pointer __f = __i.__ptr_;
+        __link_pointer __f = __i.__ptr_;
         base::__unlink_nodes(__f, __f);
         __link_nodes(__p.__ptr_, __f, __f);
         --__c.__sz();
@@ -2001,9 +2049,9 @@
             __c.__sz() -= __s;
             base::__sz() += __s;
         }
-        __node_pointer __first = __f.__ptr_;
+        __link_pointer __first = __f.__ptr_;
         --__l;
-        __node_pointer __last = __l.__ptr_;
+        __link_pointer __last = __l.__ptr_;
         base::__unlink_nodes(__first, __last);
         __link_nodes(__p.__ptr_, __first, __last);
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -2014,7 +2062,7 @@
         {
             --__p;
             iterator* __j = static_cast<iterator*>((*__p)->__i_);
-            for (__node_pointer __k = __f.__ptr_;
+            for (__link_pointer __k = __f.__ptr_;
                                           __k != __l.__ptr_; __k = __k->__next_)
             {
                 if (__j->__ptr_ == __k)
@@ -2075,7 +2123,7 @@
 }
 
 template <class _Tp, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 list<_Tp, _Alloc>::unique()
 {
@@ -2098,7 +2146,7 @@
 }
 
 template <class _Tp, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 list<_Tp, _Alloc>::merge(list& __c)
 {
@@ -2126,8 +2174,8 @@
                     ;
                 base::__sz() += __ds;
                 __c.__sz() -= __ds;
-                __node_pointer __f = __f2.__ptr_;
-                __node_pointer __l = __m2.__ptr_->__prev_;
+                __link_pointer __f = __f2.__ptr_;
+                __link_pointer __l = __m2.__ptr_->__prev_;
                 __f2 = __m2;
                 base::__unlink_nodes(__f, __l);
                 __m2 = _VSTD::next(__f1);
@@ -2146,8 +2194,7 @@
         {
             --__p;
             iterator* __i = static_cast<iterator*>((*__p)->__i_);
-            if (__i->__ptr_ != static_cast<__node_pointer>(
-                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))
+            if (__i->__ptr_ != __c.__end_as_link())
             {
                 __cn1->__add(*__p);
                 (*__p)->__c_ = __cn1;
@@ -2161,7 +2208,7 @@
 }
 
 template <class _Tp, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 list<_Tp, _Alloc>::sort()
 {
@@ -2170,7 +2217,7 @@
 
 template <class _Tp, class _Alloc>
 template <class _Comp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 list<_Tp, _Alloc>::sort(_Comp __comp)
 {
@@ -2190,7 +2237,7 @@
     case 2:
         if (__comp(*--__e2, *__f1))
         {
-            __node_pointer __f = __e2.__ptr_;
+            __link_pointer __f = __e2.__ptr_;
             base::__unlink_nodes(__f, __f);
             __link_nodes(__f1.__ptr_, __f, __f);
             return __e2;
@@ -2206,8 +2253,8 @@
         iterator __m2 = _VSTD::next(__f2);
         for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
             ;
-        __node_pointer __f = __f2.__ptr_;
-        __node_pointer __l = __m2.__ptr_->__prev_;
+        __link_pointer __f = __f2.__ptr_;
+        __link_pointer __l = __m2.__ptr_->__prev_;
         __r = __f2;
         __e1 = __f2 = __m2;
         base::__unlink_nodes(__f, __l);
@@ -2224,8 +2271,8 @@
             iterator __m2 = _VSTD::next(__f2);
             for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
                 ;
-            __node_pointer __f = __f2.__ptr_;
-            __node_pointer __l = __m2.__ptr_->__prev_;
+            __link_pointer __f = __f2.__ptr_;
+            __link_pointer __l = __m2.__ptr_->__prev_;
             if (__e1 == __f2)
                 __e1 = __m2;
             __f2 = __m2;
@@ -2269,8 +2316,7 @@
 bool
 list<_Tp, _Alloc>::__dereferenceable(const const_iterator* __i) const
 {
-    return __i->__ptr_ != static_cast<__node_pointer>(
-                       pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(this->__end_)));
+    return __i->__ptr_ != this->__end_as_link();
 }
 
 template <class _Tp, class _Alloc>
diff --git a/include/locale b/include/locale
index e683ba3..b1cac28 100644
--- a/include/locale
+++ b/include/locale
@@ -213,6 +213,12 @@
 #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 +234,6 @@
 
 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
@@ -1188,11 +1011,7 @@
     }
     // 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 +1375,9 @@
     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 +1403,7 @@
                           + ((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 +1429,7 @@
                           + ((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 +1455,7 @@
                           + ((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 +1482,17 @@
     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 +1533,17 @@
     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, __v);
-#endif
+            __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
         if (__nb == 0)
             __throw_bad_alloc();
         __nbh.reset(__nb);
@@ -1810,11 +1579,7 @@
     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
@@ -1888,6 +1653,9 @@
     virtual const string_type& __r() const;
     virtual const string_type& __x() const;
     virtual const string_type& __X() const;
+
+    _LIBCPP_ALWAYS_INLINE
+    ~__time_get_c_storage() {}
 };
 
 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
@@ -3523,11 +3291,7 @@
     // 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);
@@ -3773,11 +3537,14 @@
     wstring_convert(const wstring_convert& __wc);
     wstring_convert& operator=(const wstring_convert& __wc);
 public:
+    _LIBCPP_ALWAYS_INLINE
     _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
+    _LIBCPP_ALWAYS_INLINE
     wstring_convert(_Codecvt* __pcvt, state_type __state);
     _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
                     const wide_string& __wide_err = wide_string());
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_ALWAYS_INLINE
     wstring_convert(wstring_convert&& __wc);
 #endif
     ~wstring_convert();
@@ -3811,7 +3578,7 @@
 };
 
 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
-inline _LIBCPP_ALWAYS_INLINE
+inline
 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
     wstring_convert(_Codecvt* __pcvt)
         : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
@@ -3819,7 +3586,7 @@
 }
 
 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
-inline _LIBCPP_ALWAYS_INLINE
+inline
 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
     wstring_convert(_Codecvt* __pcvt, state_type __state)
         : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
@@ -3838,7 +3605,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
-inline _LIBCPP_ALWAYS_INLINE
+inline
 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
     wstring_convert(wstring_convert&& __wc)
         : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
@@ -4313,18 +4080,9 @@
     int __width = __cv_->encoding();
     if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
         return pos_type(off_type(-1));
-    // __width > 0 || __off == 0
-    switch (__way)
-    {
-    case ios_base::beg:
-        break;
-    case ios_base::cur:
-        break;
-    case ios_base::end:
-        break;
-    default:
+    // __width > 0 || __off == 0, now check __way
+    if (__way != ios_base::beg && __way != ios_base::cur && __way != ios_base::end)
         return pos_type(off_type(-1));
-    }
     pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
     __r.state(__st_);
     return __r;
diff --git a/include/map b/include/map
index eb6b8ed..8dc84e7 100644
--- a/include/map
+++ b/include/map
@@ -126,9 +126,11 @@
     template <class... Args>
         iterator emplace_hint(const_iterator position, Args&&... args);
     pair<iterator, bool> insert(const value_type& v);
+    pair<iterator, bool> insert(      value_type&& v);                                // C++17
     template <class P>
         pair<iterator, bool> insert(P&& p);
     iterator insert(const_iterator position, const value_type& v);
+    iterator insert(const_iterator position,       value_type&& v);                   // C++17
     template <class P>
         iterator insert(const_iterator position, P&& p);
     template <class InputIterator>
@@ -160,7 +162,7 @@
 
     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;
@@ -336,9 +338,11 @@
     template <class... Args>
         iterator emplace_hint(const_iterator position, Args&&... args);
     iterator insert(const value_type& v);
+    iterator insert(      value_type&& v);                                            // C++17
     template <class P>
         iterator insert(P&& p);
     iterator insert(const_iterator position, const value_type& v);
+    iterator insert(const_iterator position,       value_type&& v);                   // C++17
     template <class P>
         iterator insert(const_iterator position, P&& p);
     template <class InputIterator>
@@ -353,7 +357,7 @@
 
     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;
@@ -560,13 +564,11 @@
 {
     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&);
@@ -611,7 +613,7 @@
     class multimap;
 template <class _TreeIterator> class __map_const_iterator;
 
-#if __cplusplus >= 201103L
+#ifndef _LIBCPP_CXX03_LANG
 
 template <class _Key, class _Tp>
 union __value_type
@@ -624,33 +626,29 @@
     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
@@ -664,18 +662,11 @@
 
     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
@@ -693,24 +684,17 @@
 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 __pointer_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<value_type>
-#else
-            rebind<value_type>::other
-#endif
-                                                                 pointer;
+    typedef typename _NodeTypes::__map_value_type_pointer        pointer;
 
     _LIBCPP_INLINE_VISIBILITY
     __map_iterator() _NOEXCEPT {}
@@ -759,24 +743,17 @@
 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 __pointer_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<const value_type>
-#else
-            rebind<const value_type>::other
-#endif
-                                                                 pointer;
+    typedef typename _NodeTypes::__const_map_value_type_pointer  pointer;
 
     _LIBCPP_INLINE_VISIBILITY
     __map_const_iterator() _NOEXCEPT {}
@@ -840,6 +817,9 @@
     typedef value_type&                              reference;
     typedef const value_type&                        const_reference;
 
+    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
+                  "Allocator::value_type must be same type as value_type");
+
     class _LIBCPP_TYPE_VIS_ONLY value_compare
         : public binary_function<value_type, value_type, bool>
     {
@@ -1046,7 +1026,7 @@
     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
 
@@ -1060,18 +1040,18 @@
     _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>
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> emplace(_Args&& ...__args) {
+        return __tree_.__emplace_unique(_VSTD::forward<_Args>(__args)...);
+    }
 
     template <class ..._Args>
-        pair<iterator, bool>
-        emplace(_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>
@@ -1085,7 +1065,7 @@
         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>
@@ -1096,6 +1076,16 @@
         insert(const_iterator __p, const value_type& __v)
             {return __tree_.__insert_unique(__p.__i_, __v);}
 
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool>
+    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::move(__v));}
+#endif
+
     template <class _InputIterator>
         _LIBCPP_INLINE_VISIBILITY
         void insert(_InputIterator __f, _InputIterator __l)
@@ -1113,62 +1103,45 @@
 #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>
@@ -1183,7 +1156,7 @@
         }
         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)
@@ -1222,8 +1195,7 @@
         }
         return emplace_hint(__h, _VSTD::move(__k), _VSTD::forward<_Vp>(__v));
      }
-#endif
-#endif
+
 #endif
 
     _LIBCPP_INLINE_VISIBILITY
@@ -1324,38 +1296,36 @@
     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
+
+// 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_pointer&
+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 key_type& __k) const
 {
     __node_pointer __nd = __tree_.__root();
     if (__nd != nullptr)
@@ -1393,52 +1363,7 @@
     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,
-                                                       const key_type& __k) const
-{
-    __node_const_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 const_cast<const __node_base_const_pointer&>(__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 const_cast<const __node_base_const_pointer&>(__parent->__right_);
-                }
-            }
-            else
-            {
-                __parent = static_cast<__node_base_pointer>(__nd);
-                return __parent;
-            }
-        }
-    }
-    __parent = static_cast<__node_base_pointer>(__tree_.__end_node());
-    return const_cast<const __node_base_const_pointer&>(__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)
@@ -1449,69 +1374,14 @@
         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;
-}
+#endif  // !_LIBCPP_CXX03_LANG
 
-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
-
-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
@@ -1523,7 +1393,7 @@
     __h.get_deleter().__first_constructed = true;
     __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
     __h.get_deleter().__second_constructed = true;
-    return _VSTD::move(__h);  // explicitly moved for C++03
+    return _LIBCPP_EXPLICIT_MOVE(__h);  // explicitly moved for C++03
 }
 
 template <class _Key, class _Tp, class _Compare, class _Allocator>
@@ -1542,25 +1412,29 @@
     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&
@@ -1579,43 +1453,15 @@
 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;
+    return static_cast<__node_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;
-}
-
-#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
@@ -1696,6 +1542,9 @@
     typedef value_type&                              reference;
     typedef const value_type&                        const_reference;
 
+    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
+                  "Allocator::value_type must be same type as value_type");
+
     class _LIBCPP_TYPE_VIS_ONLY value_compare
         : public binary_function<value_type, value_type, bool>
     {
@@ -1910,18 +1759,19 @@
     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>
@@ -1935,7 +1785,15 @@
         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(value_type&& __v)
+        {return __tree_.__insert_multi(_VSTD::move(__v));}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __p, value_type&& __v)
+        {return __tree_.__insert_multi(__p.__i_, _VSTD::move(__v));}
+
+#endif  // _LIBCPP_CXX03_LANG
 
     _LIBCPP_INLINE_VISIBILITY
     iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);}
@@ -2057,24 +1915,12 @@
     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)
@@ -2084,82 +1930,10 @@
         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/math.h b/include/math.h
new file mode 100644
index 0000000..2020554
--- /dev/null
+++ b/include/math.h
@@ -0,0 +1,1419 @@
+// -*- C++ -*-
+//===---------------------------- math.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_MATH_H
+#define _LIBCPP_MATH_H
+
+/*
+    math.h synopsis
+
+Macros:
+
+    HUGE_VAL
+    HUGE_VALF               // C99
+    HUGE_VALL               // C99
+    INFINITY                // C99
+    NAN                     // C99
+    FP_INFINITE             // C99
+    FP_NAN                  // C99
+    FP_NORMAL               // C99
+    FP_SUBNORMAL            // C99
+    FP_ZERO                 // C99
+    FP_FAST_FMA             // C99
+    FP_FAST_FMAF            // C99
+    FP_FAST_FMAL            // C99
+    FP_ILOGB0               // C99
+    FP_ILOGBNAN             // C99
+    MATH_ERRNO              // C99
+    MATH_ERREXCEPT          // C99
+    math_errhandling        // C99
+
+Types:
+
+    float_t                 // C99
+    double_t                // C99
+
+// C90
+
+floating_point abs(floating_point x);
+
+floating_point acos (arithmetic x);
+float          acosf(float x);
+long double    acosl(long double x);
+
+floating_point asin (arithmetic x);
+float          asinf(float x);
+long double    asinl(long double x);
+
+floating_point atan (arithmetic x);
+float          atanf(float x);
+long double    atanl(long double x);
+
+floating_point atan2 (arithmetic y, arithmetic x);
+float          atan2f(float y, float x);
+long double    atan2l(long double y, long double x);
+
+floating_point ceil (arithmetic x);
+float          ceilf(float x);
+long double    ceill(long double x);
+
+floating_point cos (arithmetic x);
+float          cosf(float x);
+long double    cosl(long double x);
+
+floating_point cosh (arithmetic x);
+float          coshf(float x);
+long double    coshl(long double x);
+
+floating_point exp (arithmetic x);
+float          expf(float x);
+long double    expl(long double x);
+
+floating_point fabs (arithmetic x);
+float          fabsf(float x);
+long double    fabsl(long double x);
+
+floating_point floor (arithmetic x);
+float          floorf(float x);
+long double    floorl(long double x);
+
+floating_point fmod (arithmetic x, arithmetic y);
+float          fmodf(float x, float y);
+long double    fmodl(long double x, long double y);
+
+floating_point frexp (arithmetic value, int* exp);
+float          frexpf(float value, int* exp);
+long double    frexpl(long double value, int* exp);
+
+floating_point ldexp (arithmetic value, int exp);
+float          ldexpf(float value, int exp);
+long double    ldexpl(long double value, int exp);
+
+floating_point log (arithmetic x);
+float          logf(float x);
+long double    logl(long double x);
+
+floating_point log10 (arithmetic x);
+float          log10f(float x);
+long double    log10l(long double x);
+
+floating_point modf (floating_point value, floating_point* iptr);
+float          modff(float value, float* iptr);
+long double    modfl(long double value, long double* iptr);
+
+floating_point pow (arithmetic x, arithmetic y);
+float          powf(float x, float y);
+long double    powl(long double x, long double y);
+
+floating_point sin (arithmetic x);
+float          sinf(float x);
+long double    sinl(long double x);
+
+floating_point sinh (arithmetic x);
+float          sinhf(float x);
+long double    sinhl(long double x);
+
+floating_point sqrt (arithmetic x);
+float          sqrtf(float x);
+long double    sqrtl(long double x);
+
+floating_point tan (arithmetic x);
+float          tanf(float x);
+long double    tanl(long double x);
+
+floating_point tanh (arithmetic x);
+float          tanhf(float x);
+long double    tanhl(long double x);
+
+//  C99
+
+bool signbit(arithmetic x);
+
+int fpclassify(arithmetic x);
+
+bool isfinite(arithmetic x);
+bool isinf(arithmetic x);
+bool isnan(arithmetic x);
+bool isnormal(arithmetic x);
+
+bool isgreater(arithmetic x, arithmetic y);
+bool isgreaterequal(arithmetic x, arithmetic y);
+bool isless(arithmetic x, arithmetic y);
+bool islessequal(arithmetic x, arithmetic y);
+bool islessgreater(arithmetic x, arithmetic y);
+bool isunordered(arithmetic x, arithmetic y);
+
+floating_point acosh (arithmetic x);
+float          acoshf(float x);
+long double    acoshl(long double x);
+
+floating_point asinh (arithmetic x);
+float          asinhf(float x);
+long double    asinhl(long double x);
+
+floating_point atanh (arithmetic x);
+float          atanhf(float x);
+long double    atanhl(long double x);
+
+floating_point cbrt (arithmetic x);
+float          cbrtf(float x);
+long double    cbrtl(long double x);
+
+floating_point copysign (arithmetic x, arithmetic y);
+float          copysignf(float x, float y);
+long double    copysignl(long double x, long double y);
+
+floating_point erf (arithmetic x);
+float          erff(float x);
+long double    erfl(long double x);
+
+floating_point erfc (arithmetic x);
+float          erfcf(float x);
+long double    erfcl(long double x);
+
+floating_point exp2 (arithmetic x);
+float          exp2f(float x);
+long double    exp2l(long double x);
+
+floating_point expm1 (arithmetic x);
+float          expm1f(float x);
+long double    expm1l(long double x);
+
+floating_point fdim (arithmetic x, arithmetic y);
+float          fdimf(float x, float y);
+long double    fdiml(long double x, long double y);
+
+floating_point fma (arithmetic x, arithmetic y, arithmetic z);
+float          fmaf(float x, float y, float z);
+long double    fmal(long double x, long double y, long double z);
+
+floating_point fmax (arithmetic x, arithmetic y);
+float          fmaxf(float x, float y);
+long double    fmaxl(long double x, long double y);
+
+floating_point fmin (arithmetic x, arithmetic y);
+float          fminf(float x, float y);
+long double    fminl(long double x, long double y);
+
+floating_point hypot (arithmetic x, arithmetic y);
+float          hypotf(float x, float y);
+long double    hypotl(long double x, long double y);
+
+int ilogb (arithmetic x);
+int ilogbf(float x);
+int ilogbl(long double x);
+
+floating_point lgamma (arithmetic x);
+float          lgammaf(float x);
+long double    lgammal(long double x);
+
+long long llrint (arithmetic x);
+long long llrintf(float x);
+long long llrintl(long double x);
+
+long long llround (arithmetic x);
+long long llroundf(float x);
+long long llroundl(long double x);
+
+floating_point log1p (arithmetic x);
+float          log1pf(float x);
+long double    log1pl(long double x);
+
+floating_point log2 (arithmetic x);
+float          log2f(float x);
+long double    log2l(long double x);
+
+floating_point logb (arithmetic x);
+float          logbf(float x);
+long double    logbl(long double x);
+
+long lrint (arithmetic x);
+long lrintf(float x);
+long lrintl(long double x);
+
+long lround (arithmetic x);
+long lroundf(float x);
+long lroundl(long double x);
+
+double      nan (const char* str);
+float       nanf(const char* str);
+long double nanl(const char* str);
+
+floating_point nearbyint (arithmetic x);
+float          nearbyintf(float x);
+long double    nearbyintl(long double x);
+
+floating_point nextafter (arithmetic x, arithmetic y);
+float          nextafterf(float x, float y);
+long double    nextafterl(long double x, long double y);
+
+floating_point nexttoward (arithmetic x, long double y);
+float          nexttowardf(float x, long double y);
+long double    nexttowardl(long double x, long double y);
+
+floating_point remainder (arithmetic x, arithmetic y);
+float          remainderf(float x, float y);
+long double    remainderl(long double x, long double y);
+
+floating_point remquo (arithmetic x, arithmetic y, int* pquo);
+float          remquof(float x, float y, int* pquo);
+long double    remquol(long double x, long double y, int* pquo);
+
+floating_point rint (arithmetic x);
+float          rintf(float x);
+long double    rintl(long double x);
+
+floating_point round (arithmetic x);
+float          roundf(float x);
+long double    roundl(long double x);
+
+floating_point scalbln (arithmetic x, long ex);
+float          scalblnf(float x, long ex);
+long double    scalblnl(long double x, long ex);
+
+floating_point scalbn (arithmetic x, int ex);
+float          scalbnf(float x, int ex);
+long double    scalbnl(long double x, int ex);
+
+floating_point tgamma (arithmetic x);
+float          tgammaf(float x);
+long double    tgammal(long double x);
+
+floating_point trunc (arithmetic x);
+float          truncf(float x);
+long double    truncl(long double x);
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <math.h>
+
+#ifdef __cplusplus
+
+// We support including .h headers inside 'extern "C"' contexts, so switch
+// back to C++ linkage before including these C++ headers.
+extern "C++" {
+
+#include <type_traits>
+
+#ifdef _LIBCPP_MSVCRT
+#include "support/win32/math_win32.h"
+#endif
+
+// signbit
+
+#ifdef signbit
+
+template <class _A1>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_signbit(_A1 __lcpp_x) _NOEXCEPT
+{
+    return signbit(__lcpp_x);
+}
+
+#undef signbit
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
+signbit(_A1 __lcpp_x) _NOEXCEPT
+{
+    return __libcpp_signbit((typename std::__promote<_A1>::type)__lcpp_x);
+}
+
+#endif  // signbit
+
+// fpclassify
+
+#ifdef fpclassify
+
+template <class _A1>
+_LIBCPP_ALWAYS_INLINE
+int
+__libcpp_fpclassify(_A1 __lcpp_x) _NOEXCEPT
+{
+    return fpclassify(__lcpp_x);
+}
+
+#undef fpclassify
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_arithmetic<_A1>::value, int>::type
+fpclassify(_A1 __lcpp_x) _NOEXCEPT
+{
+    return __libcpp_fpclassify((typename std::__promote<_A1>::type)__lcpp_x);
+}
+
+#endif  // fpclassify
+
+// isfinite
+
+#ifdef isfinite
+
+template <class _A1>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isfinite(_A1 __lcpp_x) _NOEXCEPT
+{
+    return isfinite(__lcpp_x);
+}
+
+#undef isfinite
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
+isfinite(_A1 __lcpp_x) _NOEXCEPT
+{
+    return __libcpp_isfinite((typename std::__promote<_A1>::type)__lcpp_x);
+}
+
+#endif  // isfinite
+
+// isinf
+
+#ifdef isinf
+
+template <class _A1>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isinf(_A1 __lcpp_x) _NOEXCEPT
+{
+    return isinf(__lcpp_x);
+}
+
+#undef isinf
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
+isinf(_A1 __lcpp_x) _NOEXCEPT
+{
+    return __libcpp_isinf((typename std::__promote<_A1>::type)__lcpp_x);
+}
+
+#endif  // isinf
+
+// isnan
+
+#ifdef isnan
+
+template <class _A1>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isnan(_A1 __lcpp_x) _NOEXCEPT
+{
+    return isnan(__lcpp_x);
+}
+
+#undef isnan
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
+isnan(_A1 __lcpp_x) _NOEXCEPT
+{
+    return __libcpp_isnan((typename std::__promote<_A1>::type)__lcpp_x);
+}
+
+#endif  // isnan
+
+// isnormal
+
+#ifdef isnormal
+
+template <class _A1>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isnormal(_A1 __lcpp_x) _NOEXCEPT
+{
+    return isnormal(__lcpp_x);
+}
+
+#undef isnormal
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
+isnormal(_A1 __lcpp_x) _NOEXCEPT
+{
+    return __libcpp_isnormal((typename std::__promote<_A1>::type)__lcpp_x);
+}
+
+#endif  // isnormal
+
+// isgreater
+
+#ifdef isgreater
+
+template <class _A1, class _A2>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    return isgreater(__lcpp_x, __lcpp_y);
+}
+
+#undef isgreater
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    bool
+>::type
+isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type type;
+    return __libcpp_isgreater((type)__lcpp_x, (type)__lcpp_y);
+}
+
+#endif  // isgreater
+
+// isgreaterequal
+
+#ifdef isgreaterequal
+
+template <class _A1, class _A2>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    return isgreaterequal(__lcpp_x, __lcpp_y);
+}
+
+#undef isgreaterequal
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    bool
+>::type
+isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type type;
+    return __libcpp_isgreaterequal((type)__lcpp_x, (type)__lcpp_y);
+}
+
+#endif  // isgreaterequal
+
+// isless
+
+#ifdef isless
+
+template <class _A1, class _A2>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    return isless(__lcpp_x, __lcpp_y);
+}
+
+#undef isless
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    bool
+>::type
+isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type type;
+    return __libcpp_isless((type)__lcpp_x, (type)__lcpp_y);
+}
+
+#endif  // isless
+
+// islessequal
+
+#ifdef islessequal
+
+template <class _A1, class _A2>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    return islessequal(__lcpp_x, __lcpp_y);
+}
+
+#undef islessequal
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    bool
+>::type
+islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type type;
+    return __libcpp_islessequal((type)__lcpp_x, (type)__lcpp_y);
+}
+
+#endif  // islessequal
+
+// islessgreater
+
+#ifdef islessgreater
+
+template <class _A1, class _A2>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    return islessgreater(__lcpp_x, __lcpp_y);
+}
+
+#undef islessgreater
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    bool
+>::type
+islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type type;
+    return __libcpp_islessgreater((type)__lcpp_x, (type)__lcpp_y);
+}
+
+#endif  // islessgreater
+
+// isunordered
+
+#ifdef isunordered
+
+template <class _A1, class _A2>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    return isunordered(__lcpp_x, __lcpp_y);
+}
+
+#undef isunordered
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    bool
+>::type
+isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type type;
+    return __libcpp_isunordered((type)__lcpp_x, (type)__lcpp_y);
+}
+
+#endif  // isunordered
+
+#ifndef __sun__
+
+// abs
+
+#if !defined(_AIX)
+inline _LIBCPP_INLINE_VISIBILITY
+float
+abs(float __lcpp_x) _NOEXCEPT {return fabsf(__lcpp_x);}
+
+inline _LIBCPP_INLINE_VISIBILITY
+double
+abs(double __lcpp_x) _NOEXCEPT {return fabs(__lcpp_x);}
+
+inline _LIBCPP_INLINE_VISIBILITY
+long double
+abs(long double __lcpp_x) _NOEXCEPT {return fabsl(__lcpp_x);}
+#endif // !defined(_AIX)
+
+// acos
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       acos(float __lcpp_x) _NOEXCEPT       {return acosf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double acos(long double __lcpp_x) _NOEXCEPT {return acosl(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+acos(_A1 __lcpp_x) _NOEXCEPT {return acos((double)__lcpp_x);}
+
+// asin
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       asin(float __lcpp_x) _NOEXCEPT       {return asinf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double asin(long double __lcpp_x) _NOEXCEPT {return asinl(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+asin(_A1 __lcpp_x) _NOEXCEPT {return asin((double)__lcpp_x);}
+
+// atan
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       atan(float __lcpp_x) _NOEXCEPT       {return atanf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double atan(long double __lcpp_x) _NOEXCEPT {return atanl(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+atan(_A1 __lcpp_x) _NOEXCEPT {return atan((double)__lcpp_x);}
+
+// atan2
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       atan2(float __lcpp_y, float __lcpp_x) _NOEXCEPT             {return atan2f(__lcpp_y, __lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double atan2(long double __lcpp_y, long double __lcpp_x) _NOEXCEPT {return atan2l(__lcpp_y, __lcpp_x);}
+#endif
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::__lazy_enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    std::__promote<_A1, _A2>
+>::type
+atan2(_A1 __lcpp_y, _A2 __lcpp_x) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type __result_type;
+    static_assert((!(std::is_same<_A1, __result_type>::value &&
+                     std::is_same<_A2, __result_type>::value)), "");
+    return atan2((__result_type)__lcpp_y, (__result_type)__lcpp_x);
+}
+
+// ceil
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       ceil(float __lcpp_x) _NOEXCEPT       {return ceilf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double ceil(long double __lcpp_x) _NOEXCEPT {return ceill(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+ceil(_A1 __lcpp_x) _NOEXCEPT {return ceil((double)__lcpp_x);}
+
+// cos
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       cos(float __lcpp_x) _NOEXCEPT       {return cosf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double cos(long double __lcpp_x) _NOEXCEPT {return cosl(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+cos(_A1 __lcpp_x) _NOEXCEPT {return cos((double)__lcpp_x);}
+
+// cosh
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       cosh(float __lcpp_x) _NOEXCEPT       {return coshf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double cosh(long double __lcpp_x) _NOEXCEPT {return coshl(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+cosh(_A1 __lcpp_x) _NOEXCEPT {return cosh((double)__lcpp_x);}
+
+// exp
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       exp(float __lcpp_x) _NOEXCEPT       {return expf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double exp(long double __lcpp_x) _NOEXCEPT {return expl(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+exp(_A1 __lcpp_x) _NOEXCEPT {return exp((double)__lcpp_x);}
+
+// fabs
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       fabs(float __lcpp_x) _NOEXCEPT       {return fabsf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double fabs(long double __lcpp_x) _NOEXCEPT {return fabsl(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+fabs(_A1 __lcpp_x) _NOEXCEPT {return fabs((double)__lcpp_x);}
+
+// floor
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       floor(float __lcpp_x) _NOEXCEPT       {return floorf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double floor(long double __lcpp_x) _NOEXCEPT {return floorl(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+floor(_A1 __lcpp_x) _NOEXCEPT {return floor((double)__lcpp_x);}
+
+// fmod
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       fmod(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fmodf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double fmod(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fmodl(__lcpp_x, __lcpp_y);}
+#endif
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::__lazy_enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    std::__promote<_A1, _A2>
+>::type
+fmod(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type __result_type;
+    static_assert((!(std::is_same<_A1, __result_type>::value &&
+                     std::is_same<_A2, __result_type>::value)), "");
+    return fmod((__result_type)__lcpp_x, (__result_type)__lcpp_y);
+}
+
+// frexp
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       frexp(float __lcpp_x, int* __lcpp_e) _NOEXCEPT       {return frexpf(__lcpp_x, __lcpp_e);}
+inline _LIBCPP_INLINE_VISIBILITY long double frexp(long double __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexpl(__lcpp_x, __lcpp_e);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+frexp(_A1 __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexp((double)__lcpp_x, __lcpp_e);}
+
+// ldexp
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       ldexp(float __lcpp_x, int __lcpp_e) _NOEXCEPT       {return ldexpf(__lcpp_x, __lcpp_e);}
+inline _LIBCPP_INLINE_VISIBILITY long double ldexp(long double __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexpl(__lcpp_x, __lcpp_e);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+ldexp(_A1 __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexp((double)__lcpp_x, __lcpp_e);}
+
+// log
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       log(float __lcpp_x) _NOEXCEPT       {return logf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double log(long double __lcpp_x) _NOEXCEPT {return logl(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+log(_A1 __lcpp_x) _NOEXCEPT {return log((double)__lcpp_x);}
+
+// log10
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       log10(float __lcpp_x) _NOEXCEPT       {return log10f(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double log10(long double __lcpp_x) _NOEXCEPT {return log10l(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+log10(_A1 __lcpp_x) _NOEXCEPT {return log10((double)__lcpp_x);}
+
+// modf
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       modf(float __lcpp_x, float* __lcpp_y) _NOEXCEPT             {return modff(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double modf(long double __lcpp_x, long double* __lcpp_y) _NOEXCEPT {return modfl(__lcpp_x, __lcpp_y);}
+#endif
+
+// pow
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       pow(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return powf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double pow(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return powl(__lcpp_x, __lcpp_y);}
+#endif
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::__lazy_enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    std::__promote<_A1, _A2>
+>::type
+pow(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type __result_type;
+    static_assert((!(std::is_same<_A1, __result_type>::value &&
+                     std::is_same<_A2, __result_type>::value)), "");
+    return pow((__result_type)__lcpp_x, (__result_type)__lcpp_y);
+}
+
+// sin
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       sin(float __lcpp_x) _NOEXCEPT       {return sinf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double sin(long double __lcpp_x) _NOEXCEPT {return sinl(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+sin(_A1 __lcpp_x) _NOEXCEPT {return sin((double)__lcpp_x);}
+
+// sinh
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       sinh(float __lcpp_x) _NOEXCEPT       {return sinhf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double sinh(long double __lcpp_x) _NOEXCEPT {return sinhl(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+sinh(_A1 __lcpp_x) _NOEXCEPT {return sinh((double)__lcpp_x);}
+
+// sqrt
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       sqrt(float __lcpp_x) _NOEXCEPT       {return sqrtf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double sqrt(long double __lcpp_x) _NOEXCEPT {return sqrtl(__lcpp_x);}
+#endif
+
+#endif // __sun__
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+sqrt(_A1 __lcpp_x) _NOEXCEPT {return sqrt((double)__lcpp_x);}
+#ifndef __sun__
+
+// tan
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       tan(float __lcpp_x) _NOEXCEPT       {return tanf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double tan(long double __lcpp_x) _NOEXCEPT {return tanl(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+tan(_A1 __lcpp_x) _NOEXCEPT {return tan((double)__lcpp_x);}
+
+// tanh
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       tanh(float __lcpp_x) _NOEXCEPT       {return tanhf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double tanh(long double __lcpp_x) _NOEXCEPT {return tanhl(__lcpp_x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+tanh(_A1 __lcpp_x) _NOEXCEPT {return tanh((double)__lcpp_x);}
+
+// acosh
+
+#ifndef _LIBCPP_MSVCRT
+inline _LIBCPP_INLINE_VISIBILITY float       acosh(float __lcpp_x) _NOEXCEPT       {return acoshf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double acosh(long double __lcpp_x) _NOEXCEPT {return acoshl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+acosh(_A1 __lcpp_x) _NOEXCEPT {return acosh((double)__lcpp_x);}
+#endif
+
+// asinh
+
+#ifndef _LIBCPP_MSVCRT
+inline _LIBCPP_INLINE_VISIBILITY float       asinh(float __lcpp_x) _NOEXCEPT       {return asinhf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double asinh(long double __lcpp_x) _NOEXCEPT {return asinhl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+asinh(_A1 __lcpp_x) _NOEXCEPT {return asinh((double)__lcpp_x);}
+#endif
+
+// atanh
+
+#ifndef _LIBCPP_MSVCRT
+inline _LIBCPP_INLINE_VISIBILITY float       atanh(float __lcpp_x) _NOEXCEPT       {return atanhf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double atanh(long double __lcpp_x) _NOEXCEPT {return atanhl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+atanh(_A1 __lcpp_x) _NOEXCEPT {return atanh((double)__lcpp_x);}
+#endif
+
+// cbrt
+
+#ifndef _LIBCPP_MSVCRT
+inline _LIBCPP_INLINE_VISIBILITY float       cbrt(float __lcpp_x) _NOEXCEPT       {return cbrtf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double cbrt(long double __lcpp_x) _NOEXCEPT {return cbrtl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+cbrt(_A1 __lcpp_x) _NOEXCEPT {return cbrt((double)__lcpp_x);}
+#endif
+
+// copysign
+
+#if !defined(_VC_CRT_MAJOR_VERSION) || (_VC_CRT_MAJOR_VERSION < 12)
+inline _LIBCPP_INLINE_VISIBILITY float copysign(float __lcpp_x,
+                                                float __lcpp_y) _NOEXCEPT {
+  return copysignf(__lcpp_x, __lcpp_y);
+}
+inline _LIBCPP_INLINE_VISIBILITY long double
+copysign(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {
+  return copysignl(__lcpp_x, __lcpp_y);
+}
+#endif
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::__lazy_enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    std::__promote<_A1, _A2>
+>::type
+copysign(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type __result_type;
+    static_assert((!(std::is_same<_A1, __result_type>::value &&
+                     std::is_same<_A2, __result_type>::value)), "");
+    return copysign((__result_type)__lcpp_x, (__result_type)__lcpp_y);
+}
+
+#ifndef _LIBCPP_MSVCRT
+
+// erf
+
+inline _LIBCPP_INLINE_VISIBILITY float       erf(float __lcpp_x) _NOEXCEPT       {return erff(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double erf(long double __lcpp_x) _NOEXCEPT {return erfl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+erf(_A1 __lcpp_x) _NOEXCEPT {return erf((double)__lcpp_x);}
+
+// erfc
+
+inline _LIBCPP_INLINE_VISIBILITY float       erfc(float __lcpp_x) _NOEXCEPT       {return erfcf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double erfc(long double __lcpp_x) _NOEXCEPT {return erfcl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+erfc(_A1 __lcpp_x) _NOEXCEPT {return erfc((double)__lcpp_x);}
+
+// exp2
+
+inline _LIBCPP_INLINE_VISIBILITY float       exp2(float __lcpp_x) _NOEXCEPT       {return exp2f(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double exp2(long double __lcpp_x) _NOEXCEPT {return exp2l(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+exp2(_A1 __lcpp_x) _NOEXCEPT {return exp2((double)__lcpp_x);}
+
+// expm1
+
+inline _LIBCPP_INLINE_VISIBILITY float       expm1(float __lcpp_x) _NOEXCEPT       {return expm1f(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double expm1(long double __lcpp_x) _NOEXCEPT {return expm1l(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+expm1(_A1 __lcpp_x) _NOEXCEPT {return expm1((double)__lcpp_x);}
+
+// fdim
+
+inline _LIBCPP_INLINE_VISIBILITY float       fdim(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fdimf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double fdim(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fdiml(__lcpp_x, __lcpp_y);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::__lazy_enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    std::__promote<_A1, _A2>
+>::type
+fdim(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type __result_type;
+    static_assert((!(std::is_same<_A1, __result_type>::value &&
+                     std::is_same<_A2, __result_type>::value)), "");
+    return fdim((__result_type)__lcpp_x, (__result_type)__lcpp_y);
+}
+
+// fma
+
+inline _LIBCPP_INLINE_VISIBILITY float       fma(float __lcpp_x, float __lcpp_y, float __lcpp_z) _NOEXCEPT                   {return fmaf(__lcpp_x, __lcpp_y, __lcpp_z);}
+inline _LIBCPP_INLINE_VISIBILITY long double fma(long double __lcpp_x, long double __lcpp_y, long double __lcpp_z) _NOEXCEPT {return fmal(__lcpp_x, __lcpp_y, __lcpp_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
+fma(_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 fma((__result_type)__lcpp_x, (__result_type)__lcpp_y, (__result_type)__lcpp_z);
+}
+
+// fmax
+
+inline _LIBCPP_INLINE_VISIBILITY float       fmax(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fmaxf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double fmax(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fmaxl(__lcpp_x, __lcpp_y);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::__lazy_enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    std::__promote<_A1, _A2>
+>::type
+fmax(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type __result_type;
+    static_assert((!(std::is_same<_A1, __result_type>::value &&
+                     std::is_same<_A2, __result_type>::value)), "");
+    return fmax((__result_type)__lcpp_x, (__result_type)__lcpp_y);
+}
+
+// fmin
+
+inline _LIBCPP_INLINE_VISIBILITY float       fmin(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fminf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double fmin(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fminl(__lcpp_x, __lcpp_y);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::__lazy_enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    std::__promote<_A1, _A2>
+>::type
+fmin(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type __result_type;
+    static_assert((!(std::is_same<_A1, __result_type>::value &&
+                     std::is_same<_A2, __result_type>::value)), "");
+    return fmin((__result_type)__lcpp_x, (__result_type)__lcpp_y);
+}
+
+// hypot
+
+inline _LIBCPP_INLINE_VISIBILITY float       hypot(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return hypotf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double hypot(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return hypotl(__lcpp_x, __lcpp_y);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::__lazy_enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    std::__promote<_A1, _A2>
+>::type
+hypot(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type __result_type;
+    static_assert((!(std::is_same<_A1, __result_type>::value &&
+                     std::is_same<_A2, __result_type>::value)), "");
+    return hypot((__result_type)__lcpp_x, (__result_type)__lcpp_y);
+}
+
+// ilogb
+
+inline _LIBCPP_INLINE_VISIBILITY int ilogb(float __lcpp_x) _NOEXCEPT       {return ilogbf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY int ilogb(long double __lcpp_x) _NOEXCEPT {return ilogbl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, int>::type
+ilogb(_A1 __lcpp_x) _NOEXCEPT {return ilogb((double)__lcpp_x);}
+
+// lgamma
+
+inline _LIBCPP_INLINE_VISIBILITY float       lgamma(float __lcpp_x) _NOEXCEPT       {return lgammaf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double lgamma(long double __lcpp_x) _NOEXCEPT {return lgammal(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+lgamma(_A1 __lcpp_x) _NOEXCEPT {return lgamma((double)__lcpp_x);}
+
+// llrint
+
+inline _LIBCPP_INLINE_VISIBILITY long long llrint(float __lcpp_x) _NOEXCEPT       {return llrintf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long long llrint(long double __lcpp_x) _NOEXCEPT {return llrintl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, long long>::type
+llrint(_A1 __lcpp_x) _NOEXCEPT {return llrint((double)__lcpp_x);}
+
+// llround
+
+inline _LIBCPP_INLINE_VISIBILITY long long llround(float __lcpp_x) _NOEXCEPT       {return llroundf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long long llround(long double __lcpp_x) _NOEXCEPT {return llroundl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, long long>::type
+llround(_A1 __lcpp_x) _NOEXCEPT {return llround((double)__lcpp_x);}
+
+// log1p
+
+inline _LIBCPP_INLINE_VISIBILITY float       log1p(float __lcpp_x) _NOEXCEPT       {return log1pf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double log1p(long double __lcpp_x) _NOEXCEPT {return log1pl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+log1p(_A1 __lcpp_x) _NOEXCEPT {return log1p((double)__lcpp_x);}
+
+// log2
+
+inline _LIBCPP_INLINE_VISIBILITY float       log2(float __lcpp_x) _NOEXCEPT       {return log2f(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __lcpp_x) _NOEXCEPT {return log2l(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+log2(_A1 __lcpp_x) _NOEXCEPT {return log2((double)__lcpp_x);}
+
+// logb
+
+inline _LIBCPP_INLINE_VISIBILITY float       logb(float __lcpp_x) _NOEXCEPT       {return logbf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double logb(long double __lcpp_x) _NOEXCEPT {return logbl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+logb(_A1 __lcpp_x) _NOEXCEPT {return logb((double)__lcpp_x);}
+
+// lrint
+
+inline _LIBCPP_INLINE_VISIBILITY long lrint(float __lcpp_x) _NOEXCEPT       {return lrintf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long lrint(long double __lcpp_x) _NOEXCEPT {return lrintl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, long>::type
+lrint(_A1 __lcpp_x) _NOEXCEPT {return lrint((double)__lcpp_x);}
+
+// lround
+
+inline _LIBCPP_INLINE_VISIBILITY long lround(float __lcpp_x) _NOEXCEPT       {return lroundf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long lround(long double __lcpp_x) _NOEXCEPT {return lroundl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, long>::type
+lround(_A1 __lcpp_x) _NOEXCEPT {return lround((double)__lcpp_x);}
+
+// nan
+
+// nearbyint
+
+inline _LIBCPP_INLINE_VISIBILITY float       nearbyint(float __lcpp_x) _NOEXCEPT       {return nearbyintf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double nearbyint(long double __lcpp_x) _NOEXCEPT {return nearbyintl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+nearbyint(_A1 __lcpp_x) _NOEXCEPT {return nearbyint((double)__lcpp_x);}
+
+// nextafter
+
+inline _LIBCPP_INLINE_VISIBILITY float       nextafter(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return nextafterf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double nextafter(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nextafterl(__lcpp_x, __lcpp_y);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::__lazy_enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    std::__promote<_A1, _A2>
+>::type
+nextafter(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type __result_type;
+    static_assert((!(std::is_same<_A1, __result_type>::value &&
+                     std::is_same<_A2, __result_type>::value)), "");
+    return nextafter((__result_type)__lcpp_x, (__result_type)__lcpp_y);
+}
+
+// nexttoward
+
+inline _LIBCPP_INLINE_VISIBILITY float       nexttoward(float __lcpp_x, long double __lcpp_y) _NOEXCEPT       {return nexttowardf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double nexttoward(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nexttowardl(__lcpp_x, __lcpp_y);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+nexttoward(_A1 __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nexttoward((double)__lcpp_x, __lcpp_y);}
+
+// remainder
+
+inline _LIBCPP_INLINE_VISIBILITY float       remainder(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return remainderf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double remainder(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return remainderl(__lcpp_x, __lcpp_y);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::__lazy_enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    std::__promote<_A1, _A2>
+>::type
+remainder(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type __result_type;
+    static_assert((!(std::is_same<_A1, __result_type>::value &&
+                     std::is_same<_A2, __result_type>::value)), "");
+    return remainder((__result_type)__lcpp_x, (__result_type)__lcpp_y);
+}
+
+// remquo
+
+inline _LIBCPP_INLINE_VISIBILITY float       remquo(float __lcpp_x, float __lcpp_y, int* __lcpp_z) _NOEXCEPT             {return remquof(__lcpp_x, __lcpp_y, __lcpp_z);}
+inline _LIBCPP_INLINE_VISIBILITY long double remquo(long double __lcpp_x, long double __lcpp_y, int* __lcpp_z) _NOEXCEPT {return remquol(__lcpp_x, __lcpp_y, __lcpp_z);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::__lazy_enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    std::__promote<_A1, _A2>
+>::type
+remquo(_A1 __lcpp_x, _A2 __lcpp_y, int* __lcpp_z) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type __result_type;
+    static_assert((!(std::is_same<_A1, __result_type>::value &&
+                     std::is_same<_A2, __result_type>::value)), "");
+    return remquo((__result_type)__lcpp_x, (__result_type)__lcpp_y, __lcpp_z);
+}
+
+// rint
+
+inline _LIBCPP_INLINE_VISIBILITY float       rint(float __lcpp_x) _NOEXCEPT       {return rintf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double rint(long double __lcpp_x) _NOEXCEPT {return rintl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+rint(_A1 __lcpp_x) _NOEXCEPT {return rint((double)__lcpp_x);}
+
+// round
+
+inline _LIBCPP_INLINE_VISIBILITY float       round(float __lcpp_x) _NOEXCEPT       {return roundf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double round(long double __lcpp_x) _NOEXCEPT {return roundl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+round(_A1 __lcpp_x) _NOEXCEPT {return round((double)__lcpp_x);}
+
+// scalbln
+
+inline _LIBCPP_INLINE_VISIBILITY float       scalbln(float __lcpp_x, long __lcpp_y) _NOEXCEPT       {return scalblnf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double scalbln(long double __lcpp_x, long __lcpp_y) _NOEXCEPT {return scalblnl(__lcpp_x, __lcpp_y);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+scalbln(_A1 __lcpp_x, long __lcpp_y) _NOEXCEPT {return scalbln((double)__lcpp_x, __lcpp_y);}
+
+// scalbn
+
+inline _LIBCPP_INLINE_VISIBILITY float       scalbn(float __lcpp_x, int __lcpp_y) _NOEXCEPT       {return scalbnf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double scalbn(long double __lcpp_x, int __lcpp_y) _NOEXCEPT {return scalbnl(__lcpp_x, __lcpp_y);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+scalbn(_A1 __lcpp_x, int __lcpp_y) _NOEXCEPT {return scalbn((double)__lcpp_x, __lcpp_y);}
+
+// tgamma
+
+inline _LIBCPP_INLINE_VISIBILITY float       tgamma(float __lcpp_x) _NOEXCEPT       {return tgammaf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double tgamma(long double __lcpp_x) _NOEXCEPT {return tgammal(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+tgamma(_A1 __lcpp_x) _NOEXCEPT {return tgamma((double)__lcpp_x);}
+
+// trunc
+
+inline _LIBCPP_INLINE_VISIBILITY float       trunc(float __lcpp_x) _NOEXCEPT       {return truncf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double trunc(long double __lcpp_x) _NOEXCEPT {return truncl(__lcpp_x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_integral<_A1>::value, double>::type
+trunc(_A1 __lcpp_x) _NOEXCEPT {return trunc((double)__lcpp_x);}
+
+#endif // !_LIBCPP_MSVCRT
+#endif // __sun__
+
+} // extern "C++"
+
+#endif // __cplusplus
+
+#endif  // _LIBCPP_MATH_H
diff --git a/include/memory b/include/memory
index df35a07..7627248 100644
--- a/include/memory
+++ b/include/memory
@@ -607,12 +607,13 @@
 #include <__functional_base>
 #include <iosfwd>
 #include <tuple>
+#include <stdexcept>
 #include <cstring>
 #if defined(_LIBCPP_NO_EXCEPTIONS)
     #include <cassert>
 #endif
 
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
 #  include <atomic>
 #endif
 
@@ -932,6 +933,15 @@
         {return _VSTD::addressof(__r);}
 };
 
+template <class _From, class _To>
+struct __rebind_pointer {
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    typedef typename pointer_traits<_From>::template rebind<_To>        type;
+#else
+    typedef typename pointer_traits<_From>::template rebind<_To>::other type;
+#endif
+};
+
 // allocator_traits
 
 namespace __has_pointer_type_imp
@@ -1669,7 +1679,7 @@
             {return __a.max_size();}
     _LIBCPP_INLINE_VISIBILITY
     static size_type __max_size(false_type, const allocator_type&)
-            {return numeric_limits<size_type>::max();}
+            {return numeric_limits<size_type>::max() / sizeof(value_type);}
 
     _LIBCPP_INLINE_VISIBILITY
     static allocator_type
@@ -1717,7 +1727,12 @@
     _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
@@ -1808,7 +1823,12 @@
     _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
@@ -1900,6 +1920,10 @@
     _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;}
     _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element)
         {::new(&*__x_) _Tp(__element); return *this;}
+#if _LIBCPP_STD_VER >= 14
+    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(_Tp&& __element)
+        {::new(&*__x_) _Tp(_VSTD::move(__element)); return *this;}
+#endif
     _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;}
     _LIBCPP_INLINE_VISIBILITY raw_storage_iterator  operator++(int)
         {raw_storage_iterator __t(*this); ++__x_; return __t;}
@@ -2535,7 +2559,7 @@
                          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;
         }
 };
@@ -2659,10 +2683,17 @@
         : __ptr_(__u->release(), _VSTD::forward<deleter_type>(__u->get_deleter())) {}
 
     template <class _Up, class _Ep>
-    _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(unique_ptr<_Up, _Ep> __u)
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<
+        !is_array<_Up>::value &&
+        is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value &&
+        is_assignable<deleter_type&, _Ep&>::value,
+        unique_ptr&
+    >::type
+    operator=(unique_ptr<_Up, _Ep> __u)
     {
         reset(__u.release());
-        __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
+        __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
         return *this;
     }
 
@@ -2898,7 +2929,6 @@
         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
@@ -2909,29 +2939,13 @@
         if (__tmp)
             __ptr_.second()(__tmp);
     }
-    _LIBCPP_INLINE_VISIBILITY void reset(nullptr_t) _NOEXCEPT
+    _LIBCPP_INLINE_VISIBILITY void reset(nullptr_t = nullptr) _NOEXCEPT
     {
         pointer __tmp = __ptr_.first();
         __ptr_.first() = nullptr;
         if (__tmp)
             __ptr_.second()(__tmp);
     }
-    _LIBCPP_INLINE_VISIBILITY void reset() _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:
@@ -2955,7 +2969,10 @@
 
 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>
@@ -3147,8 +3164,6 @@
 
 #endif  // _LIBCPP_STD_VER > 11
 
-template <class _Tp> struct hash;
-
 template <class _Size>
 inline _LIBCPP_INLINE_VISIBILITY
 _Size
@@ -3174,7 +3189,7 @@
 // murmur2
 template <class _Size>
 _Size
-__murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len)
+__murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 
 {
     const _Size __m = 0x5bd1e995;
     const _Size __r = 24;
@@ -3324,7 +3339,7 @@
 // cityhash64
 template <class _Size>
 _Size
-__murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len)
+__murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 
 {
   const char* __s = static_cast<const char*>(__key);
   if (__len <= 32) {
@@ -3854,7 +3869,9 @@
 
     struct __nat {int __for_bool_;};
 public:
+    _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT;
     template<class _Yp>
         explicit shared_ptr(_Yp* __p,
@@ -3867,15 +3884,18 @@
                    typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
     template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);
     template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);
-    template<class _Yp> shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;
+    template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     shared_ptr(const shared_ptr& __r) _NOEXCEPT;
     template<class _Yp>
+        _LIBCPP_INLINE_VISIBILITY
         shared_ptr(const shared_ptr<_Yp>& __r,
                    typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type = __nat())
                        _NOEXCEPT;
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     shared_ptr(shared_ptr&& __r) _NOEXCEPT;
-    template<class _Yp> shared_ptr(shared_ptr<_Yp>&& __r,
+    template<class _Yp> _LIBCPP_INLINE_VISIBILITY  shared_ptr(shared_ptr<_Yp>&& __r,
                    typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type = __nat())
                        _NOEXCEPT;
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -3932,6 +3952,7 @@
 
     ~shared_ptr();
 
+    _LIBCPP_INLINE_VISIBILITY
     shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT;
     template<class _Yp>
         typename enable_if
@@ -3939,8 +3960,10 @@
             is_convertible<_Yp*, element_type*>::value,
             shared_ptr&
         >::type
+        _LIBCPP_INLINE_VISIBILITY
         operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT;
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT;
     template<class _Yp>
         typename enable_if
@@ -3948,8 +3971,10 @@
             is_convertible<_Yp*, element_type*>::value,
             shared_ptr<_Tp>&
         >::type
+        _LIBCPP_INLINE_VISIBILITY
         operator=(shared_ptr<_Yp>&& __r);
     template<class _Yp>
+        _LIBCPP_INLINE_VISIBILITY
         typename enable_if
         <
             !is_array<_Yp>::value &&
@@ -3959,6 +3984,7 @@
         operator=(auto_ptr<_Yp>&& __r);
 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     template<class _Yp>
+        _LIBCPP_INLINE_VISIBILITY
         typename enable_if
         <
             !is_array<_Yp>::value &&
@@ -3975,12 +4001,16 @@
             shared_ptr&
         >::type
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+        _LIBCPP_INLINE_VISIBILITY
         operator=(unique_ptr<_Yp, _Dp>&& __r);
 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+        _LIBCPP_INLINE_VISIBILITY
         operator=(unique_ptr<_Yp, _Dp> __r);
 #endif
 
+    _LIBCPP_INLINE_VISIBILITY
     void swap(shared_ptr& __r) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     void reset() _NOEXCEPT;
     template<class _Yp>
         typename enable_if
@@ -3988,6 +4018,7 @@
             is_convertible<_Yp*, element_type*>::value,
             void
         >::type
+        _LIBCPP_INLINE_VISIBILITY
         reset(_Yp* __p);
     template<class _Yp, class _Dp>
         typename enable_if
@@ -3995,6 +4026,7 @@
             is_convertible<_Yp*, element_type*>::value,
             void
         >::type
+        _LIBCPP_INLINE_VISIBILITY
         reset(_Yp* __p, _Dp __d);
     template<class _Yp, class _Dp, class _Alloc>
         typename enable_if
@@ -4002,6 +4034,7 @@
             is_convertible<_Yp*, element_type*>::value,
             void
         >::type
+        _LIBCPP_INLINE_VISIBILITY
         reset(_Yp* __p, _Dp __d, _Alloc __a);
 
     _LIBCPP_INLINE_VISIBILITY
@@ -4103,7 +4136,7 @@
 };
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _LIBCPP_CONSTEXPR
 shared_ptr<_Tp>::shared_ptr() _NOEXCEPT
     : __ptr_(0),
@@ -4112,7 +4145,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _LIBCPP_CONSTEXPR
 shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT
     : __ptr_(0),
@@ -4235,7 +4268,7 @@
 
 template<class _Tp>
 template<class _Yp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT
     : __ptr_(__p),
       __cntrl_(__r.__cntrl_)
@@ -4245,7 +4278,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 shared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT
     : __ptr_(__r.__ptr_),
       __cntrl_(__r.__cntrl_)
@@ -4256,7 +4289,7 @@
 
 template<class _Tp>
 template<class _Yp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,
                             typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type)
          _NOEXCEPT
@@ -4270,7 +4303,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 shared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT
     : __ptr_(__r.__ptr_),
       __cntrl_(__r.__cntrl_)
@@ -4281,7 +4314,7 @@
 
 template<class _Tp>
 template<class _Yp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,
                             typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type)
          _NOEXCEPT
@@ -4568,7 +4601,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 shared_ptr<_Tp>&
 shared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT
 {
@@ -4578,7 +4611,7 @@
 
 template<class _Tp>
 template<class _Yp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     is_convertible<_Yp*, _Tp*>::value,
@@ -4593,7 +4626,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 shared_ptr<_Tp>&
 shared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT
 {
@@ -4603,7 +4636,7 @@
 
 template<class _Tp>
 template<class _Yp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     is_convertible<_Yp*, _Tp*>::value,
@@ -4617,7 +4650,7 @@
 
 template<class _Tp>
 template<class _Yp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     !is_array<_Yp>::value &&
@@ -4632,7 +4665,7 @@
 
 template<class _Tp>
 template <class _Yp, class _Dp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     !is_array<_Yp>::value &&
@@ -4680,7 +4713,7 @@
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 shared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT
 {
@@ -4689,7 +4722,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 shared_ptr<_Tp>::reset() _NOEXCEPT
 {
@@ -4698,7 +4731,7 @@
 
 template<class _Tp>
 template<class _Yp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     is_convertible<_Yp*, _Tp*>::value,
@@ -4711,7 +4744,7 @@
 
 template<class _Tp>
 template<class _Yp, class _Dp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     is_convertible<_Yp*, _Tp*>::value,
@@ -4724,7 +4757,7 @@
 
 template<class _Tp>
 template<class _Yp, class _Dp, class _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     is_convertible<_Yp*, _Tp*>::value,
@@ -5041,23 +5074,27 @@
     __shared_weak_count* __cntrl_;
 
 public:
+    _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT;
-    template<class _Yp> weak_ptr(shared_ptr<_Yp> const& __r,
+    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(shared_ptr<_Yp> const& __r,
                    typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
                         _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     weak_ptr(weak_ptr const& __r) _NOEXCEPT;
-    template<class _Yp> weak_ptr(weak_ptr<_Yp> const& __r,
+    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r,
                    typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
                          _NOEXCEPT;
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     weak_ptr(weak_ptr&& __r) _NOEXCEPT;
-    template<class _Yp> weak_ptr(weak_ptr<_Yp>&& __r,
+    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r,
                    typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
                          _NOEXCEPT;
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     ~weak_ptr();
 
+    _LIBCPP_INLINE_VISIBILITY
     weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
     template<class _Yp>
         typename enable_if
@@ -5065,10 +5102,12 @@
             is_convertible<_Yp*, element_type*>::value,
             weak_ptr&
         >::type
+        _LIBCPP_INLINE_VISIBILITY
         operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
+    _LIBCPP_INLINE_VISIBILITY
     weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;
     template<class _Yp>
         typename enable_if
@@ -5076,6 +5115,7 @@
             is_convertible<_Yp*, element_type*>::value,
             weak_ptr&
         >::type
+        _LIBCPP_INLINE_VISIBILITY
         operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -5086,9 +5126,12 @@
             is_convertible<_Yp*, element_type*>::value,
             weak_ptr&
         >::type
+        _LIBCPP_INLINE_VISIBILITY
         operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;
 
+    _LIBCPP_INLINE_VISIBILITY
     void swap(weak_ptr& __r) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
     void reset() _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
@@ -5112,7 +5155,7 @@
 };
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _LIBCPP_CONSTEXPR
 weak_ptr<_Tp>::weak_ptr() _NOEXCEPT
     : __ptr_(0),
@@ -5121,7 +5164,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 weak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT
     : __ptr_(__r.__ptr_),
       __cntrl_(__r.__cntrl_)
@@ -5132,7 +5175,7 @@
 
 template<class _Tp>
 template<class _Yp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
                         typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
                          _NOEXCEPT
@@ -5145,7 +5188,7 @@
 
 template<class _Tp>
 template<class _Yp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
                         typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
          _NOEXCEPT
@@ -5159,7 +5202,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT
     : __ptr_(__r.__ptr_),
       __cntrl_(__r.__cntrl_)
@@ -5170,7 +5213,7 @@
 
 template<class _Tp>
 template<class _Yp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
                         typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
          _NOEXCEPT
@@ -5191,7 +5234,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 weak_ptr<_Tp>&
 weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT
 {
@@ -5201,7 +5244,7 @@
 
 template<class _Tp>
 template<class _Yp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     is_convertible<_Yp*, _Tp*>::value,
@@ -5216,7 +5259,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 weak_ptr<_Tp>&
 weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT
 {
@@ -5226,7 +5269,7 @@
 
 template<class _Tp>
 template<class _Yp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     is_convertible<_Yp*, _Tp*>::value,
@@ -5242,7 +5285,7 @@
 
 template<class _Tp>
 template<class _Yp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     is_convertible<_Yp*, _Tp*>::value,
@@ -5255,7 +5298,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT
 {
@@ -5272,7 +5315,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 weak_ptr<_Tp>::reset() _NOEXCEPT
 {
@@ -5305,7 +5348,11 @@
     return __r;
 }
 
+#if _LIBCPP_STD_VER > 14
+template <class _Tp = void> struct owner_less;
+#else
 template <class _Tp> struct owner_less;
+#endif
 
 template <class _Tp>
 struct _LIBCPP_TYPE_VIS_ONLY owner_less<shared_ptr<_Tp> >
@@ -5339,6 +5386,30 @@
         {return __x.owner_before(__y);}
 };
 
+#if _LIBCPP_STD_VER > 14
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY owner_less<void>
+{
+    template <class _Tp, class _Up>
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const
+        {return __x.owner_before(__y);}
+    template <class _Tp, class _Up>
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()( shared_ptr<_Tp> const& __x,  weak_ptr<_Up> const& __y) const
+        {return __x.owner_before(__y);}
+    template <class _Tp, class _Up>
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const
+        {return __x.owner_before(__y);}
+    template <class _Tp, class _Up>
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const
+        {return __x.owner_before(__y);}
+    typedef void is_transparent;
+};
+#endif
+
 template<class _Tp>
 class _LIBCPP_TYPE_VIS_ONLY enable_shared_from_this
 {
@@ -5381,7 +5452,9 @@
 basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
 
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+// 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)
 
 class _LIBCPP_TYPE_VIS __sp_mut
 {
@@ -5468,14 +5541,17 @@
 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;
@@ -5507,7 +5583,7 @@
     return atomic_compare_exchange_weak(__p, __v, __w);
 }
 
-#endif  // __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+#endif  // defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
 
 //enum class
 struct _LIBCPP_TYPE_VIS pointer_safety
@@ -5545,7 +5621,7 @@
 
 // --- 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
@@ -5571,9 +5647,18 @@
 }
 
 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> >
+struct __noexcept_move_assign_container : public integral_constant<bool, 
+    _Traits::propagate_on_container_move_assignment::value
+#if _LIBCPP_STD_VER > 14
+        || _Traits::is_always_equal::value
+#else
+        && is_nothrow_move_assignable<_Alloc>::value
+#endif
+    > {};
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/include/module.modulemap b/include/module.modulemap
index 3c0700e..3fb7428 100644
--- a/include/module.modulemap
+++ b/include/module.modulemap
@@ -455,9 +455,13 @@
     export *
   }
 
+  // FIXME: We don't have modules for the <foo.h> headers, because they might
+  // be included from the C library's headers, and that would create a #include
+  // cycle. For the same reason, we don't have a module for __config.
+  //module __config { header "__config" export * }
+
   // FIXME: These should be private.
   module __bit_reference { header "__bit_reference" export * }
-  module __config { header "__config" export * }
   module __debug { header "__debug" export * }
   module __functional_base { header "__functional_base" export * }
   module __hash_table { header "__hash_table" export * }
diff --git a/include/mutex b/include/mutex
index 373d75b..4d288ae 100644
--- a/include/mutex
+++ b/include/mutex
@@ -179,7 +179,7 @@
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 #include <tuple>
 #endif
-#include <sched.h>
+#include <__threading_support>
 
 #include <__undef_min_max>
 
@@ -193,7 +193,7 @@
 
 class _LIBCPP_TYPE_VIS recursive_mutex
 {
-    pthread_mutex_t __m_;
+    __libcpp_mutex_t __m_;
 
 public:
      recursive_mutex();
@@ -208,7 +208,7 @@
     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_;}
 };
@@ -260,7 +260,7 @@
     mutex              __m_;
     condition_variable __cv_;
     size_t             __count_;
-    pthread_t          __id_;
+    __libcpp_thread_id __id_;
 public:
      recursive_timed_mutex();
      ~recursive_timed_mutex();
@@ -286,9 +286,9 @@
 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;
@@ -360,7 +360,7 @@
                 break;
             }
         }
-        sched_yield();
+        __libcpp_thread_yield();
         {
             unique_lock<_L1> __u1(__l1);
             if (__l0.try_lock())
@@ -369,7 +369,7 @@
                 break;
             }
         }
-        sched_yield();
+        __libcpp_thread_yield();
     }
 }
 
@@ -394,7 +394,7 @@
                 }
             }
             ++__i;
-            sched_yield();
+            __libcpp_thread_yield();
             break;
         case 1:
             {
@@ -410,7 +410,7 @@
                 __i = 0;
             else
                 __i += 2;
-            sched_yield();
+            __libcpp_thread_yield();
             break;
         default:
             __lock_first(__i - 2, __l2, __l3..., __l0, __l1);
diff --git a/include/queue b/include/queue
index 6f49c87..c657b52 100644
--- a/include/queue
+++ b/include/queue
@@ -66,7 +66,7 @@
     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 @@
     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 @@
     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 @@
 
 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 @@
     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 @@
     _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 @@
     _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 @@
 #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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 #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 @@
 #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 @@
 
 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 @@
 #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 @@
 }
 
 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 @@
 
 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/random b/include/random
index c8341ef..794bf7b 100644
--- a/include/random
+++ b/include/random
@@ -3119,6 +3119,7 @@
                independent_bits_engine<_Eng, _Wp, _UI>& __x);
 
 private:
+    _LIBCPP_INLINE_VISIBILITY
     result_type __eval(false_type);
     result_type __eval(true_type);
 
@@ -3144,7 +3145,7 @@
 };
 
 template<class _Engine, size_t __w, class _UIntType>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _UIntType
 independent_bits_engine<_Engine, __w, _UIntType>::__eval(false_type)
 {
@@ -3735,7 +3736,7 @@
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG> _LIBCPP_INLINE_VISIBILITY result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
@@ -3765,7 +3766,7 @@
 
 template<class _RealType>
 template<class _URNG>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename uniform_real_distribution<_RealType>::result_type
 uniform_real_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
 {
@@ -3851,7 +3852,7 @@
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG> _LIBCPP_INLINE_VISIBILITY result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
@@ -3878,7 +3879,7 @@
 };
 
 template<class _URNG>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bernoulli_distribution::result_type
 bernoulli_distribution::operator()(_URNG& __g, const param_type& __p)
 {
@@ -5522,7 +5523,7 @@
         _LIBCPP_INLINE_VISIBILITY
         result_type operator()(_URNG& __g)
         {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+    template<class _URNG> _LIBCPP_INLINE_VISIBILITY result_type operator()(_URNG& __g, const param_type& __p);
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
@@ -5552,7 +5553,7 @@
 
 template <class _RealType>
 template<class _URNG>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _RealType
 cauchy_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
 {
diff --git a/include/ratio b/include/ratio
index f623a06..8f708ce 100644
--- a/include/ratio
+++ b/include/ratio
@@ -62,6 +62,19 @@
 typedef ratio<   1000000000000000000000, 1> zetta;  // not supported
 typedef ratio<1000000000000000000000000, 1> yotta;  // not supported
 
+  // 20.11.5, ratio comparison
+  template <class R1, class R2> constexpr bool ratio_equal_v
+    = ratio_equal<R1, R2>::value;                                       // C++17
+  template <class R1, class R2> constexpr bool ratio_not_equal_v
+    = ratio_not_equal<R1, R2>::value;                                   // C++17
+  template <class R1, class R2> constexpr bool ratio_less_v
+    = ratio_less<R1, R2>::value;                                        // C++17
+  template <class R1, class R2> constexpr bool ratio_less_equal_v
+    = ratio_less_equal<R1, R2>::value;                                  // C++17
+  template <class R1, class R2> constexpr bool ratio_greater_v
+    = ratio_greater<R1, R2>::value;                                     // C++17
+  template <class R1, class R2> constexpr bool ratio_greater_equal_v
+    = ratio_greater_equal<R1, R2>::value;                               // C++17
 }
 */
 
@@ -485,6 +498,26 @@
                   __static_lcm<_R1::den, _R2::den>::value> type;
 };
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_equal_v
+    = ratio_equal<_R1, _R2>::value;
+
+template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_not_equal_v
+    = ratio_not_equal<_R1, _R2>::value;
+
+template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_less_v
+    = ratio_less<_R1, _R2>::value;
+
+template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_less_equal_v
+    = ratio_less_equal<_R1, _R2>::value;
+
+template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_greater_v
+    = ratio_greater<_R1, _R2>::value;
+
+template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_greater_equal_v
+    = ratio_greater_equal<_R1, _R2>::value;
+#endif
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_RATIO
diff --git a/include/regex b/include/regex
index c270cab..3724204 100644
--- a/include/regex
+++ b/include/regex
@@ -762,6 +762,7 @@
 #include <memory>
 #include <vector>
 #include <deque>
+#include <cassert>
 
 #include <__undef_min_max>
 
@@ -960,7 +961,9 @@
 void __throw_regex_error()
 {
 #ifndef _LIBCPP_NO_EXCEPTIONS
-	throw regex_error(_Ev);
+    throw regex_error(_Ev);
+#else
+    assert(!"regex_error");
 #endif
 }
 
@@ -979,6 +982,8 @@
 
 #ifdef __ANDROID__
     static const char_class_type __regex_word = 0x8000;
+#elif defined(__mips__) && defined(__GLIBC__)
+    static const char_class_type __regex_word = static_cast<char_class_type>(_ISbit(15));
 #else
     static const char_class_type __regex_word = 0x80;
 #endif
@@ -1054,6 +1059,7 @@
     _LIBCPP_INLINE_VISIBILITY
     int __regex_traits_value(char __ch, int __radix) const
         {return __regex_traits_value(static_cast<unsigned char>(__ch), __radix);}
+    _LIBCPP_INLINE_VISIBILITY
     int __regex_traits_value(wchar_t __ch, int __radix) const;
 };
 
@@ -1276,7 +1282,7 @@
 }
 
 template <class _CharT>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 int
 regex_traits<_CharT>::__regex_traits_value(wchar_t __ch, int __radix) const
 {
@@ -1739,6 +1745,8 @@
 void
 __back_ref<_CharT>::__exec(__state& __s) const
 {
+    if (__mexp_ > __s.__sub_matches_.size())
+        __throw_regex_error<regex_constants::error_backref>();
     sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_-1];
     if (__sm.matched)
     {
@@ -4268,6 +4276,9 @@
     if (__first != __last && *__first == '\\')
     {
         _ForwardIterator __t1 = _VSTD::next(__first);
+        if (__t1 == __last)
+            __throw_regex_error<regex_constants::error_escape>();
+
         _ForwardIterator __t2 = __parse_decimal_escape(__t1, __last);
         if (__t2 != __t1)
             __first = __t2;
@@ -5387,8 +5398,8 @@
                 if ('0' <= *__fmt_first && *__fmt_first <= '9')
                 {
                     size_t __i = *__fmt_first - '0';
-                    __out = _VSTD::copy(__matches_[__i].first,
-                                       __matches_[__i].second, __out);
+                    __out = _VSTD::copy((*this)[__i].first,
+                                        (*this)[__i].second, __out);
                 }
                 else
                 {
@@ -5439,8 +5450,8 @@
                             ++__fmt_first;
                             __i = 10 * __i + *__fmt_first - '0';
                         }
-                        __out = _VSTD::copy(__matches_[__i].first,
-                                           __matches_[__i].second, __out);
+                        __out = _VSTD::copy((*this)[__i].first,
+                                            (*this)[__i].second, __out);
                     }
                     else
                     {
diff --git a/include/scoped_allocator b/include/scoped_allocator
index cd4987a..9436dac 100644
--- a/include/scoped_allocator
+++ b/include/scoped_allocator
@@ -58,6 +58,8 @@
     template <class OuterA2>
         scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
 
+    scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
+    scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
     ~scoped_allocator_adaptor();
 
     inner_allocator_type& inner_allocator() noexcept;
@@ -457,6 +459,8 @@
             scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
                 : base(_VSTD::move(__other)) {}
 
+    // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
+    // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
     // ~scoped_allocator_adaptor() = default;
 
     _LIBCPP_INLINE_VISIBILITY
diff --git a/include/set b/include/set
index 9d64a52..ac69e08 100644
--- a/include/set
+++ b/include/set
@@ -409,6 +409,9 @@
     typedef value_type&                              reference;
     typedef const value_type&                        const_reference;
 
+    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
+                  "Allocator::value_type must be same type as value_type");
+
 private:
     typedef __tree<value_type, value_compare, allocator_type> __base;
     typedef allocator_traits<allocator_type>                  __alloc_traits;
@@ -819,6 +822,9 @@
     typedef value_type&                              reference;
     typedef const value_type&                        const_reference;
 
+    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
+                  "Allocator::value_type must be same type as value_type");
+
 private:
     typedef __tree<value_type, value_compare, allocator_type> __base;
     typedef allocator_traits<allocator_type>                  __alloc_traits;
diff --git a/include/setjmp.h b/include/setjmp.h
new file mode 100644
index 0000000..464b4a5
--- /dev/null
+++ b/include/setjmp.h
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+//===--------------------------- setjmp.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_SETJMP_H
+#define _LIBCPP_SETJMP_H
+
+/*
+    setjmp.h synopsis
+
+Macros:
+
+    setjmp
+
+Types:
+
+    jmp_buf
+
+void longjmp(jmp_buf env, int val);
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <setjmp.h>
+
+#ifdef __cplusplus
+
+#ifndef setjmp
+#define setjmp(env) setjmp(env)
+#endif
+
+#endif // __cplusplus
+
+#endif  // _LIBCPP_SETJMP_H
diff --git a/include/shared_mutex b/include/shared_mutex
index dcb9394..923fe07 100644
--- a/include/shared_mutex
+++ b/include/shared_mutex
@@ -319,25 +319,25 @@
 
     _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 @@
         _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 @@
         _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 2992b09..48b3b0d 100644
--- a/include/stack
+++ b/include/stack
@@ -58,7 +58,7 @@
     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 @@
     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 @@
 
 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 0000000..86a127f
--- /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/stddef.h b/include/stddef.h
new file mode 100644
index 0000000..8841bbe
--- /dev/null
+++ b/include/stddef.h
@@ -0,0 +1,62 @@
+// -*- C++ -*-
+//===--------------------------- stddef.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.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__need_ptrdiff_t) || defined(__need_size_t) || \
+    defined(__need_wchar_t) || defined(__need_NULL) || defined(__need_wint_t)
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <stddef.h>
+
+#elif !defined(_LIBCPP_STDDEF_H)
+#define _LIBCPP_STDDEF_H
+
+/*
+    stddef.h synopsis
+
+Macros:
+
+    offsetof(type,member-designator)
+    NULL
+
+Types:
+
+    ptrdiff_t
+    size_t
+    max_align_t
+    nullptr_t
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <stddef.h>
+
+#ifdef __cplusplus
+
+extern "C++" {
+#include <__nullptr>
+using std::nullptr_t;
+}
+
+// Re-use the compiler's <stddef.h> max_align_t where possible.
+#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) && !defined(_GCC_MAX_ALIGN_T)
+typedef long double max_align_t;
+#endif
+
+#endif
+
+#endif  // _LIBCPP_STDDEF_H
diff --git a/include/stdexcept b/include/stdexcept
index f251806..4218b13 100644
--- a/include/stdexcept
+++ b/include/stdexcept
@@ -53,7 +53,11 @@
 #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/stdio.h b/include/stdio.h
new file mode 100644
index 0000000..56fb2d8
--- /dev/null
+++ b/include/stdio.h
@@ -0,0 +1,127 @@
+// -*- C++ -*-
+//===---------------------------- stdio.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.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__need_FILE) || defined(__need___FILE)
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <stdio.h>
+
+#elif !defined(_LIBCPP_STDIO_H)
+#define _LIBCPP_STDIO_H
+
+/*
+    stdio.h synopsis
+
+Macros:
+
+    BUFSIZ
+    EOF
+    FILENAME_MAX
+    FOPEN_MAX
+    L_tmpnam
+    NULL
+    SEEK_CUR
+    SEEK_END
+    SEEK_SET
+    TMP_MAX
+    _IOFBF
+    _IOLBF
+    _IONBF
+    stderr
+    stdin
+    stdout
+
+Types:
+
+FILE
+fpos_t
+size_t
+
+int remove(const char* filename);
+int rename(const char* old, const char* new);
+FILE* tmpfile(void);
+char* tmpnam(char* s);
+int fclose(FILE* stream);
+int fflush(FILE* stream);
+FILE* fopen(const char* restrict filename, const char* restrict mode);
+FILE* freopen(const char* restrict filename, const char * restrict mode,
+              FILE * restrict stream);
+void setbuf(FILE* restrict stream, char* restrict buf);
+int setvbuf(FILE* restrict stream, char* restrict buf, int mode, size_t size);
+int fprintf(FILE* restrict stream, const char* restrict format, ...);
+int fscanf(FILE* restrict stream, const char * restrict format, ...);
+int printf(const char* restrict format, ...);
+int scanf(const char* restrict format, ...);
+int snprintf(char* restrict s, size_t n, const char* restrict format, ...);    // C99
+int sprintf(char* restrict s, const char* restrict format, ...);
+int sscanf(const char* restrict s, const char* restrict format, ...);
+int vfprintf(FILE* restrict stream, const char* restrict format, va_list arg);
+int vfscanf(FILE* restrict stream, const char* restrict format, va_list arg);  // C99
+int vprintf(const char* restrict format, va_list arg);
+int vscanf(const char* restrict format, va_list arg);                          // C99
+int vsnprintf(char* restrict s, size_t n, const char* restrict format,         // C99
+              va_list arg);
+int vsprintf(char* restrict s, const char* restrict format, va_list arg);
+int vsscanf(const char* restrict s, const char* restrict format, va_list arg); // C99
+int fgetc(FILE* stream);
+char* fgets(char* restrict s, int n, FILE* restrict stream);
+int fputc(int c, FILE* stream);
+int fputs(const char* restrict s, FILE* restrict stream);
+int getc(FILE* stream);
+int getchar(void);
+char* gets(char* s);  // removed in C++14
+int putc(int c, FILE* stream);
+int putchar(int c);
+int puts(const char* s);
+int ungetc(int c, FILE* stream);
+size_t fread(void* restrict ptr, size_t size, size_t nmemb,
+             FILE* restrict stream);
+size_t fwrite(const void* restrict ptr, size_t size, size_t nmemb,
+              FILE* restrict stream);
+int fgetpos(FILE* restrict stream, fpos_t* restrict pos);
+int fseek(FILE* stream, long offset, int whence);
+int fsetpos(FILE*stream, const fpos_t* pos);
+long ftell(FILE* stream);
+void rewind(FILE* stream);
+void clearerr(FILE* stream);
+int feof(FILE* stream);
+int ferror(FILE* stream);
+void perror(const char* s);
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <stdio.h>
+
+#ifdef __cplusplus
+
+// snprintf
+#if defined(_LIBCPP_MSVCRT)
+extern "C++" {
+#include "support/win32/support.h"
+}
+#endif
+
+#undef getc
+#undef putc
+#undef clearerr
+#undef feof
+#undef ferror
+
+#endif
+
+#endif  // _LIBCPP_STDIO_H
diff --git a/include/stdlib.h b/include/stdlib.h
new file mode 100644
index 0000000..12fd676
--- /dev/null
+++ b/include/stdlib.h
@@ -0,0 +1,130 @@
+// -*- C++ -*-
+//===--------------------------- stdlib.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.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__need_malloc_and_calloc)
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <stdlib.h>
+
+#elif !defined(_LIBCPP_STDLIB_H)
+#define _LIBCPP_STDLIB_H
+
+/*
+    stdlib.h synopsis
+
+Macros:
+
+    EXIT_FAILURE
+    EXIT_SUCCESS
+    MB_CUR_MAX
+    NULL
+    RAND_MAX
+
+Types:
+
+    size_t
+    div_t
+    ldiv_t
+    lldiv_t                                                               // C99
+
+double    atof (const char* nptr);
+int       atoi (const char* nptr);
+long      atol (const char* nptr);
+long long atoll(const char* nptr);                                        // C99
+double             strtod  (const char* restrict nptr, char** restrict endptr);
+float              strtof  (const char* restrict nptr, char** restrict endptr); // C99
+long double        strtold (const char* restrict nptr, char** restrict endptr); // C99
+long               strtol  (const char* restrict nptr, char** restrict endptr, int base);
+long long          strtoll (const char* restrict nptr, char** restrict endptr, int base); // C99
+unsigned long      strtoul (const char* restrict nptr, char** restrict endptr, int base);
+unsigned long long strtoull(const char* restrict nptr, char** restrict endptr, int base); // C99
+int rand(void);
+void srand(unsigned int seed);
+void* calloc(size_t nmemb, size_t size);
+void free(void* ptr);
+void* malloc(size_t size);
+void* realloc(void* ptr, size_t size);
+void abort(void);
+int atexit(void (*func)(void));
+void exit(int status);
+void _Exit(int status);
+char* getenv(const char* name);
+int system(const char* string);
+void* bsearch(const void* key, const void* base, size_t nmemb, size_t size,
+              int (*compar)(const void *, const void *));
+void qsort(void* base, size_t nmemb, size_t size,
+           int (*compar)(const void *, const void *));
+int         abs(      int j);
+long        abs(     long j);
+long long   abs(long long j);                                             // C++0X
+long       labs(     long j);
+long long llabs(long long j);                                             // C99
+div_t     div(      int numer,       int denom);
+ldiv_t    div(     long numer,      long denom);
+lldiv_t   div(long long numer, long long denom);                          // C++0X
+ldiv_t   ldiv(     long numer,      long denom);
+lldiv_t lldiv(long long numer, long long denom);                          // C99
+int mblen(const char* s, size_t n);
+int mbtowc(wchar_t* restrict pwc, const char* restrict s, size_t n);
+int wctomb(char* s, wchar_t wchar);
+size_t mbstowcs(wchar_t* restrict pwcs, const char* restrict s, size_t n);
+size_t wcstombs(char* restrict s, const wchar_t* restrict pwcs, size_t n);
+int at_quick_exit(void (*func)(void))                                     // C++11
+void quick_exit(int status);                                              // C++11
+void *aligned_alloc(size_t alignment, size_t size);                       // C11
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <stdlib.h>
+
+#ifdef __cplusplus
+
+extern "C++" {
+
+#ifdef _LIBCPP_MSVCRT
+#include "support/win32/locale_win32.h"
+#endif // _LIBCPP_MSVCRT
+
+#undef abs
+#undef div
+#undef labs
+#undef ldiv
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+#undef llabs
+#undef lldiv
+#endif
+
+// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
+#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
+inline _LIBCPP_INLINE_VISIBILITY long      abs(     long __x) _NOEXCEPT {return  labs(__x);}
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {return llabs(__x);}
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+
+inline _LIBCPP_INLINE_VISIBILITY  ldiv_t div(     long __x,      long __y) _NOEXCEPT {return  ldiv(__x, __y);}
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x, long long __y) _NOEXCEPT {return lldiv(__x, __y);}
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+#endif // _LIBCPP_MSVCRT / __sun__ / _AIX
+
+}  // extern "C++"
+
+#endif  // __cplusplus
+
+#endif  // _LIBCPP_STDLIB_H
diff --git a/include/string b/include/string
index 2c677ce..786735f 100644
--- a/include/string
+++ b/include/string
@@ -98,8 +98,10 @@
     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());
@@ -115,8 +117,8 @@
     basic_string& operator=(const basic_string& str);
     basic_string& operator=(basic_string&& str)
         noexcept(
-             allocator_type::propagate_on_container_move_assignment::value &&
-             is_nothrow_move_assignable<allocator_type>::value);
+             allocator_type::propagate_on_container_move_assignment::value ||
+             allocator_type::is_always_equal::value ); // C++17
     basic_string& operator=(const value_type* s);
     basic_string& operator=(value_type c);
     basic_string& operator=(initializer_list<value_type>);
@@ -225,6 +227,7 @@
 
     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;
 
@@ -517,10 +520,14 @@
         {return __c1 < __c2;}
 
     static int              compare(const char_type* __s1, const char_type* __s2, size_t __n);
+    _LIBCPP_INLINE_VISIBILITY
     static size_t           length(const char_type* __s);
+    _LIBCPP_INLINE_VISIBILITY
     static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
     static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n);
+    _LIBCPP_INLINE_VISIBILITY
     static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);
+    _LIBCPP_INLINE_VISIBILITY
     static char_type*       assign(char_type* __s, size_t __n, char_type __a);
 
     static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
@@ -550,7 +557,7 @@
 }
 
 template <class _CharT>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 size_t
 char_traits<_CharT>::length(const char_type* __s)
 {
@@ -561,7 +568,7 @@
 }
 
 template <class _CharT>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 const _CharT*
 char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
 {
@@ -595,7 +602,7 @@
 }
 
 template <class _CharT>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _CharT*
 char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
 {
@@ -607,7 +614,7 @@
 }
 
 template <class _CharT>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _CharT*
 char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
 {
@@ -726,11 +733,17 @@
     static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 < __c2;}
 
+    _LIBCPP_INLINE_VISIBILITY
     static int              compare(const char_type* __s1, const char_type* __s2, size_t __n);
+    _LIBCPP_INLINE_VISIBILITY
     static size_t           length(const char_type* __s);
+    _LIBCPP_INLINE_VISIBILITY
     static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
+    _LIBCPP_INLINE_VISIBILITY
     static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n);
+    _LIBCPP_INLINE_VISIBILITY
     static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);
+    _LIBCPP_INLINE_VISIBILITY
     static char_type*       assign(char_type* __s, size_t __n, char_type __a);
 
     static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
@@ -745,7 +758,7 @@
         {return int_type(0xFFFF);}
 };
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 int
 char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
 {
@@ -759,7 +772,7 @@
     return 0;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 size_t
 char_traits<char16_t>::length(const char_type* __s)
 {
@@ -769,7 +782,7 @@
     return __len;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 const char16_t*
 char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a)
 {
@@ -782,7 +795,7 @@
     return 0;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 char16_t*
 char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n)
 {
@@ -802,7 +815,7 @@
     return __r;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 char16_t*
 char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)
 {
@@ -813,7 +826,7 @@
     return __r;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 char16_t*
 char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a)
 {
@@ -839,11 +852,17 @@
     static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 < __c2;}
 
+    _LIBCPP_INLINE_VISIBILITY
     static int              compare(const char_type* __s1, const char_type* __s2, size_t __n);
+    _LIBCPP_INLINE_VISIBILITY
     static size_t           length(const char_type* __s);
+    _LIBCPP_INLINE_VISIBILITY
     static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
+    _LIBCPP_INLINE_VISIBILITY
     static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n);
+    _LIBCPP_INLINE_VISIBILITY
     static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);
+    _LIBCPP_INLINE_VISIBILITY
     static char_type*       assign(char_type* __s, size_t __n, char_type __a);
 
     static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
@@ -858,7 +877,7 @@
         {return int_type(0xFFFFFFFF);}
 };
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 int
 char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
 {
@@ -872,7 +891,7 @@
     return 0;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 size_t
 char_traits<char32_t>::length(const char_type* __s)
 {
@@ -882,7 +901,7 @@
     return __len;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 const char32_t*
 char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a)
 {
@@ -895,7 +914,7 @@
     return 0;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 char32_t*
 char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n)
 {
@@ -915,7 +934,7 @@
     return __r;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 char32_t*
 char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)
 {
@@ -926,7 +945,7 @@
     return __r;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 char32_t*
 char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a)
 {
@@ -942,7 +961,7 @@
 
 // __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
 {
@@ -955,7 +974,7 @@
 }
 
 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
 {
@@ -966,7 +985,7 @@
     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);
@@ -976,7 +995,7 @@
 // __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
 {
@@ -995,7 +1014,7 @@
 }
 
 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
 {
@@ -1014,7 +1033,7 @@
 
 // __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
 {
@@ -1030,7 +1049,7 @@
 
 // __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
     {
@@ -1053,7 +1072,7 @@
 
 // __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
 {
@@ -1069,7 +1088,7 @@
 
 
 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
 {
@@ -1086,7 +1105,7 @@
 
 // __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
 {
@@ -1102,7 +1121,7 @@
 
 
 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
 {
@@ -1185,7 +1204,31 @@
 #pragma warning( pop )
 #endif // _LIBCPP_MSVC
 
-#ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT
+#ifdef _LIBCPP_NO_EXCEPTIONS
+template <class _Iter>
+struct __libcpp_string_gets_noexcept_iterator_impl : public true_type {};
+#elif defined(_LIBCPP_HAS_NO_NOEXCEPT)
+template <class _Iter>
+struct __libcpp_string_gets_noexcept_iterator_impl : public false_type {};
+#else
+template <class _Iter, bool = __is_forward_iterator<_Iter>::value>
+struct __libcpp_string_gets_noexcept_iterator_impl : public _LIBCPP_BOOL_CONSTANT((
+    noexcept(++(declval<_Iter&>())) && 
+    is_nothrow_assignable<_Iter&, _Iter>::value && 
+    noexcept(declval<_Iter>() == declval<_Iter>()) && 
+    noexcept(*declval<_Iter>())
+)) {};
+
+template <class _Iter> 
+struct __libcpp_string_gets_noexcept_iterator_impl<_Iter, false> : public false_type {};
+#endif
+
+
+template <class _Iter>
+struct __libcpp_string_gets_noexcept_iterator
+    : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value || __libcpp_string_gets_noexcept_iterator_impl<_Iter>::value) {};
+
+#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
 
 template <class _CharT, size_t = sizeof(_CharT)>
 struct __padding
@@ -1198,7 +1241,7 @@
 {
 };
 
-#endif  // _LIBCPP_ALTERNATE_STRING_LAYOUT
+#endif  // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
 
 template<class _CharT, class _Traits, class _Allocator>
 class _LIBCPP_TYPE_VIS_ONLY basic_string
@@ -1234,7 +1277,7 @@
 
 private:
 
-#ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT
+#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
 
     struct __long
     {
@@ -1294,7 +1337,7 @@
         value_type __data_[__min_cap];
     };
 
-#endif  // _LIBCPP_ALTERNATE_STRING_LAYOUT
+#endif  // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
 
     union __ulx{__long __lx; __short __lxx;};
 
@@ -1356,7 +1399,10 @@
     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
@@ -1377,8 +1423,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     _LIBCPP_INLINE_VISIBILITY
     basic_string& operator=(basic_string&& __str)
-        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
-                   is_nothrow_move_assignable<allocator_type>::value);
+        _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
 #endif
     _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}
     basic_string& operator=(value_type __c);
@@ -1445,7 +1490,8 @@
     _LIBCPP_INLINE_VISIBILITY size_type length() const _NOEXCEPT {return size();}
     _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT
-        {return (__is_long() ? __get_long_cap() : __min_cap) - 1;}
+        {return (__is_long() ? __get_long_cap()
+                             : static_cast<size_type>(__min_cap)) - 1;}
 
     void resize(size_type __n, value_type __c);
     _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());}
@@ -1479,15 +1525,16 @@
     template<class _InputIterator>
         typename enable_if
         <
-             __is_input_iterator  <_InputIterator>::value &&
-            !__is_forward_iterator<_InputIterator>::value,
+            __is_exactly_input_iterator<_InputIterator>::value
+                || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
             basic_string&
         >::type
         append(_InputIterator __first, _InputIterator __last);
     template<class _ForwardIterator>
         typename enable_if
         <
-            __is_forward_iterator<_ForwardIterator>::value,
+            __is_forward_iterator<_ForwardIterator>::value
+                && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
             basic_string&
         >::type
         append(_ForwardIterator __first, _ForwardIterator __last);
@@ -1505,10 +1552,11 @@
     _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)
+        _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
         {*this = _VSTD::move(str); return *this;}
 #endif
     basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
@@ -1518,15 +1566,16 @@
     template<class _InputIterator>
         typename enable_if
         <
-             __is_input_iterator  <_InputIterator>::value &&
-            !__is_forward_iterator<_InputIterator>::value,
+           __is_exactly_input_iterator<_InputIterator>::value
+                || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
             basic_string&
         >::type
         assign(_InputIterator __first, _InputIterator __last);
     template<class _ForwardIterator>
         typename enable_if
         <
-            __is_forward_iterator<_ForwardIterator>::value,
+            __is_forward_iterator<_ForwardIterator>::value
+                 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
             basic_string&
         >::type
         assign(_ForwardIterator __first, _ForwardIterator __last);
@@ -1547,15 +1596,16 @@
     template<class _InputIterator>
         typename enable_if
         <
-             __is_input_iterator  <_InputIterator>::value &&
-            !__is_forward_iterator<_InputIterator>::value,
+           __is_exactly_input_iterator<_InputIterator>::value
+                || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
             iterator
         >::type
         insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
     template<class _ForwardIterator>
         typename enable_if
         <
-            __is_forward_iterator<_ForwardIterator>::value,
+            __is_forward_iterator<_ForwardIterator>::value
+                 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
             iterator
         >::type
         insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
@@ -1615,6 +1665,10 @@
     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();}
@@ -1697,7 +1751,7 @@
     const allocator_type& __alloc() const _NOEXCEPT
         {return __r_.second();}
 
-#ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT
+#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
 
     _LIBCPP_INLINE_VISIBILITY
     void __set_short_size(size_type __s) _NOEXCEPT
@@ -1715,7 +1769,7 @@
         {return __r_.first().__s.__size_;}
 #   endif
 
-#else  // _LIBCPP_ALTERNATE_STRING_LAYOUT
+#else  // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
 
     _LIBCPP_INLINE_VISIBILITY
     void __set_short_size(size_type __s) _NOEXCEPT
@@ -1733,7 +1787,7 @@
         {return __r_.first().__s.__size_ >> 1;}
 #   endif
 
-#endif  // _LIBCPP_ALTERNATE_STRING_LAYOUT
+#endif  // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
 
     _LIBCPP_INLINE_VISIBILITY
     void __set_long_size(size_type __s) _NOEXCEPT
@@ -1785,11 +1839,11 @@
     template <size_type __a> static
         _LIBCPP_INLINE_VISIBILITY
         size_type __align_it(size_type __s) _NOEXCEPT
-            {return __s + (__a-1) & ~(__a-1);}
+            {return (__s + (__a-1)) & ~(__a-1);}
     enum {__alignment = 16};
     static _LIBCPP_INLINE_VISIBILITY
     size_type __recommend(size_type __s) _NOEXCEPT
-        {return (__s < __min_cap ? __min_cap :
+        {return (__s < __min_cap ? static_cast<size_type>(__min_cap) :
                  __align_it<sizeof(value_type) < __alignment ?
                             __alignment/sizeof(value_type) : 1 > (__s+1)) - 1;}
 
@@ -1800,8 +1854,7 @@
     template <class _InputIterator>
     typename enable_if
     <
-         __is_input_iterator  <_InputIterator>::value &&
-        !__is_forward_iterator<_InputIterator>::value,
+        __is_exactly_input_iterator<_InputIterator>::value,
         void
     >::type
     __init(_InputIterator __first, _InputIterator __last);
@@ -1845,11 +1898,16 @@
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     _LIBCPP_INLINE_VISIBILITY
-    void __move_assign(basic_string& __str, false_type);
+    void __move_assign(basic_string& __str, false_type)
+        _NOEXCEPT_(__alloc_traits::is_always_equal::value);
     _LIBCPP_INLINE_VISIBILITY
     void __move_assign(basic_string& __str, true_type)
+#if _LIBCPP_STD_VER > 14
+        _NOEXCEPT;
+#else
         _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
 #endif
+#endif
 
     _LIBCPP_INLINE_VISIBILITY
     void
@@ -2170,11 +2228,25 @@
 }
 
 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
 <
-     __is_input_iterator  <_InputIterator>::value &&
-    !__is_forward_iterator<_InputIterator>::value,
+    __is_exactly_input_iterator<_InputIterator>::value,
     void
 >::type
 basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
@@ -2419,7 +2491,7 @@
     if (this != &__str)
     {
         __copy_assign_alloc(__str);
-        assign(__str);
+        assign(__str.data(), __str.size());
     }
     return *this;
 }
@@ -2430,6 +2502,7 @@
 inline _LIBCPP_INLINE_VISIBILITY
 void
 basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
+    _NOEXCEPT_(__alloc_traits::is_always_equal::value)
 {
     if (__alloc() != __str.__alloc())
         assign(__str);
@@ -2441,7 +2514,11 @@
 inline _LIBCPP_INLINE_VISIBILITY
 void
 basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
+#if _LIBCPP_STD_VER > 14
+    _NOEXCEPT
+#else
     _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+#endif
 {
     clear();
     shrink_to_fit();
@@ -2454,8 +2531,7 @@
 inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
-    _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
-               is_nothrow_move_assignable<allocator_type>::value)
+    _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
 {
     __move_assign(__str, integral_constant<bool,
           __alloc_traits::propagate_on_container_move_assignment::value>());
@@ -2468,15 +2544,14 @@
 template<class _InputIterator>
 typename enable_if
 <
-     __is_input_iterator  <_InputIterator>::value &&
-    !__is_forward_iterator<_InputIterator>::value,
+     __is_exactly_input_iterator <_InputIterator>::value
+          || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
     basic_string<_CharT, _Traits, _Allocator>&
 >::type
 basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
 {
-    clear();
-    for (; __first != __last; ++__first)
-        push_back(*__first);
+    basic_string __temp(__first, __last, __alloc());
+    assign(__temp.data(), __temp.size());
     return *this;
 }
 
@@ -2484,7 +2559,8 @@
 template<class _ForwardIterator>
 typename enable_if
 <
-    __is_forward_iterator<_ForwardIterator>::value,
+    __is_forward_iterator<_ForwardIterator>::value
+         && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
     basic_string<_CharT, _Traits, _Allocator>&
 >::type
 basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
@@ -2507,14 +2583,6 @@
 }
 
 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)
 {
@@ -2617,14 +2685,14 @@
 template<class _InputIterator>
 typename enable_if
 <
-     __is_input_iterator  <_InputIterator>::value &&
-    !__is_forward_iterator<_InputIterator>::value,
+    __is_exactly_input_iterator<_InputIterator>::value
+             || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
     basic_string<_CharT, _Traits, _Allocator>&
 >::type
 basic_string<_CharT, _Traits, _Allocator>::append(_InputIterator __first, _InputIterator __last)
 {
-    for (; __first != __last; ++__first)
-        push_back(*__first);
+	basic_string __temp (__first, __last, __alloc());
+	append(__temp.data(), __temp.size());
     return *this;
 }
 
@@ -2632,7 +2700,8 @@
 template<class _ForwardIterator>
 typename enable_if
 <
-    __is_forward_iterator<_ForwardIterator>::value,
+    __is_forward_iterator<_ForwardIterator>::value
+          && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
     basic_string<_CharT, _Traits, _Allocator>&
 >::type
 basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last)
@@ -2748,9 +2817,9 @@
 template<class _InputIterator>
 typename enable_if
 <
-     __is_input_iterator  <_InputIterator>::value &&
-    !__is_forward_iterator<_InputIterator>::value,
-    typename basic_string<_CharT, _Traits, _Allocator>::iterator
+   __is_exactly_input_iterator<_InputIterator>::value
+        || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
+   typename basic_string<_CharT, _Traits, _Allocator>::iterator
 >::type
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
 {
@@ -2759,24 +2828,16 @@
         "string::insert(iterator, range) called with an iterator not"
         " referring to this string");
 #endif
-    size_type __old_sz = size();
-    difference_type __ip = __pos - begin();
-    for (; __first != __last; ++__first)
-        push_back(*__first);
-    pointer __p = __get_pointer();
-    _VSTD::rotate(__p + __ip, __p + __old_sz, __p + size());
-#if _LIBCPP_DEBUG_LEVEL >= 2
-    return iterator(this, __p + __ip);
-#else
-    return iterator(__p + __ip);
-#endif
+    basic_string __temp(__first, __last, __alloc());
+    return insert(__pos, __temp.data(), __temp.data() + __temp.size());
 }
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _ForwardIterator>
 typename enable_if
 <
-    __is_forward_iterator<_ForwardIterator>::value,
+    __is_forward_iterator<_ForwardIterator>::value
+        && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
     typename basic_string<_CharT, _Traits, _Allocator>::iterator
 >::type
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
@@ -2979,22 +3040,8 @@
 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
                                                    _InputIterator __j1, _InputIterator __j2)
 {
-    for (; true; ++__i1, ++__j1)
-    {
-        if (__i1 == __i2)
-        {
-            if (__j1 != __j2)
-                insert(__i1, __j1, __j2);
-            break;
-        }
-        if (__j1 == __j2)
-        {
-            erase(__i1, __i2);
-            break;
-        }
-        traits_type::assign(const_cast<value_type&>(*__i1), *__j1);
-    }
-    return *this;
+    basic_string __temp(__j1, __j2, __alloc());
+    return this->replace(__i1, __i2, __temp);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -3787,7 +3834,11 @@
 operator==(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
 {
-    return __rhs.compare(__lhs) == 0;
+    typedef basic_string<_CharT, _Traits, _Allocator> _String;
+    _LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr");
+    size_t __lhs_len = _Traits::length(__lhs);
+    if (__lhs_len != __rhs.size()) return false;
+    return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0;
 }
 
 template<class _CharT, class _Traits, class _Allocator>
@@ -3796,7 +3847,11 @@
 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
 {
-    return __lhs.compare(__rhs) == 0;
+    typedef basic_string<_CharT, _Traits, _Allocator> _String;
+    _LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
+    size_t __rhs_len = _Traits::length(__rhs);
+    if (__rhs_len != __lhs.size()) return false;
+    return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0;
 }
 
 // operator!=
diff --git a/include/string.h b/include/string.h
new file mode 100644
index 0000000..a1ce56c
--- /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 3a020da..1365563 100644
--- a/include/support/android/locale_bionic.h
+++ b/include/support/android/locale_bionic.h
@@ -24,8 +24,8 @@
 }
 #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 0000000..e3b7a78
--- /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 8d99a5c..f39c0ba 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 @@
 #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/musl/xlocale.h b/include/support/musl/xlocale.h
new file mode 100644
index 0000000..3e31c99
--- /dev/null
+++ b/include/support/musl/xlocale.h
@@ -0,0 +1,58 @@
+// -*- C++ -*-
+//===------------------- support/musl/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 adds support for the extended locale functions that are currently
+// missing from the Musl C library.
+//
+// This 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 Musl.
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_MUSL_XLOCALE_H
+#define _LIBCPP_SUPPORT_MUSL_XLOCALE_H
+
+#include <cstdlib>
+#include <cwchar>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+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_MUSL_XLOCALE_H
diff --git a/include/support/newlib/xlocale.h b/include/support/newlib/xlocale.h
index d067cf8..4e4b23b 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/win32/locale_mgmt_win32.h b/include/support/win32/locale_mgmt_win32.h
new file mode 100644
index 0000000..b3316d6
--- /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 f728d23..7f3710e 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 0000000..0d3f23a
--- /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 0000000..8bf9567
--- /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 0000000..b060f75
--- /dev/null
+++ b/include/support/xlocale/__strtonum_fallback.h
@@ -0,0 +1,56 @@
+// -*- 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 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 99f710e..e69de29 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/system_error b/include/system_error
index 66bf6d6..134bb32 100644
--- a/include/system_error
+++ b/include/system_error
@@ -371,7 +371,7 @@
     error_category() _NOEXCEPT;
 #else
     _LIBCPP_ALWAYS_INLINE
-    _LIBCPP_CONSTEXPR_AFTER_CXX11 error_category() _NOEXCEPT _LIBCPP_DEFAULT;
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 error_category() _NOEXCEPT _LIBCPP_DEFAULT
 #endif
 private:
     error_category(const error_category&);// = delete;
diff --git a/include/thread b/include/thread
index 8a30102..3ce32fc 100644
--- a/include/thread
+++ b/include/thread
@@ -98,8 +98,7 @@
 #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
@@ -113,10 +112,37 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+template <class _Tp> class __thread_specific_ptr;
+class _LIBCPP_TYPE_VIS __thread_struct;
+class _LIBCPP_HIDDEN __thread_struct_imp;
+class __assoc_sub_state;
+
+_LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
+
+class _LIBCPP_TYPE_VIS __thread_struct
+{
+    __thread_struct_imp* __p_;
+
+    __thread_struct(const __thread_struct&);
+    __thread_struct& operator=(const __thread_struct&);
+public:
+    __thread_struct();
+    ~__thread_struct();
+
+    void notify_all_at_thread_exit(condition_variable*, mutex*);
+    void __make_ready_at_thread_exit(__assoc_sub_state*);
+};
+
 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.
+    static_assert((is_same<_Tp, __thread_struct>::value), "");
+    __thread_specific_ptr();
+    friend _LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
 
     __thread_specific_ptr(const __thread_specific_ptr&);
     __thread_specific_ptr& operator=(const __thread_specific_ptr&);
@@ -125,11 +151,10 @@
 public:
     typedef _Tp* pointer;
 
-    __thread_specific_ptr();
     ~__thread_specific_ptr();
 
     _LIBCPP_INLINE_VISIBILITY
-    pointer get() const {return static_cast<_Tp*>(pthread_getspecific(__key_));}
+    pointer get() const {return static_cast<_Tp*>(__libcpp_tl_get(__key_));}
     _LIBCPP_INLINE_VISIBILITY
     pointer operator*() const {return *get();}
     _LIBCPP_INLINE_VISIBILITY
@@ -148,7 +173,9 @@
 template <class _Tp>
 __thread_specific_ptr<_Tp>::__thread_specific_ptr()
 {
-    int __ec = pthread_key_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
+    int __ec = __libcpp_tl_create(
+        &__key_,
+        &__thread_specific_ptr::__at_thread_exit);
 #ifndef _LIBCPP_NO_EXCEPTIONS
     if (__ec)
         throw system_error(error_code(__ec, system_category()),
@@ -159,7 +186,10 @@
 template <class _Tp>
 __thread_specific_ptr<_Tp>::~__thread_specific_ptr()
 {
-    pthread_key_delete(__key_);
+    // __thread_specific_ptr is only created with a static storage duration
+    // so this destructor is only invoked during program termination. Invoking
+    // pthread_key_delete(__key_) may prevent other threads from deleting their
+    // thread local data. For this reason we leak the key.
 }
 
 template <class _Tp>
@@ -167,7 +197,7 @@
 __thread_specific_ptr<_Tp>::release()
 {
     pointer __p = get();
-    pthread_setspecific(__key_, 0);
+    __libcpp_tl_set(__key_, nullptr);
     return __p;
 }
 
@@ -176,7 +206,7 @@
 __thread_specific_ptr<_Tp>::reset(pointer __p)
 {
     pointer __p_old = get();
-    pthread_setspecific(__key_, __p);
+    __libcpp_tl_set(__key_, __p);
     delete __p_old;
 }
 
@@ -190,14 +220,14 @@
 
 }  // 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
@@ -205,13 +235,13 @@
 
     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);}
@@ -231,7 +261,7 @@
 
 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;
@@ -245,7 +275,7 @@
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(__thread_id __v) const
     {
-        return hash<pthread_t>()(__v.__id_);
+        return hash<__libcpp_thread_id>()(__v.__id_);
     }
 };
 
@@ -256,20 +286,20 @@
 __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) {}
@@ -289,6 +319,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     _LIBCPP_INLINE_VISIBILITY
     thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {__t.__t_ = 0;}
+    _LIBCPP_INLINE_VISIBILITY
     thread& operator=(thread&& __t) _NOEXCEPT;
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
@@ -300,50 +331,30 @@
     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_;}
 
     static unsigned hardware_concurrency() _NOEXCEPT;
 };
 
-class __assoc_sub_state;
-
-class _LIBCPP_HIDDEN __thread_struct_imp;
-
-class _LIBCPP_TYPE_VIS __thread_struct
-{
-    __thread_struct_imp* __p_;
-
-    __thread_struct(const __thread_struct&);
-    __thread_struct& operator=(const __thread_struct&);
-public:
-    __thread_struct();
-    ~__thread_struct();
-
-    void notify_all_at_thread_exit(condition_variable*, mutex*);
-    void __make_ready_at_thread_exit(__assoc_sub_state*);
-};
-
-_LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
-
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 
-template <class _Fp, class ..._Args, size_t ..._Indices>
+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;
 }
@@ -353,10 +364,14 @@
          >
 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
@@ -366,22 +381,34 @@
 #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");
 }
@@ -390,7 +417,7 @@
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 thread&
 thread::operator=(thread&& __t) _NOEXCEPT
 {
@@ -454,7 +481,7 @@
 }
 
 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 3a22aa5..73f42a0 100644
--- a/include/tuple
+++ b/include/tuple
@@ -80,28 +80,33 @@
 // 20.4.1.4, tuple helper classes:
 template <class T> class tuple_size; // undefined
 template <class... T> class tuple_size<tuple<T...>>;
-template <intsize_t I, class T> class tuple_element; // undefined
-template <intsize_t I, class... T> class tuple_element<I, tuple<T...>>;
-template <size_t _Ip, class ..._Tp>
-  using tuple_element_t = typename tuple_element <_Ip, _Tp...>::type; // C++14
+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>
+  using tuple_element_t = typename tuple_element <I, T>::type; // C++14
 
 // 20.4.1.5, element access:
-template <intsize_t I, class... T>
+template <size_t I, class... T>
     typename tuple_element<I, tuple<T...>>::type&
     get(tuple<T...>&) noexcept; // constexpr in C++14
-template <intsize_t I, class... T>
-    typename const tuple_element<I, tuple<T...>>::type &
+template <size_t I, class... T>
+    const typename tuple_element<I, tuple<T...>>::type&
     get(const tuple<T...>&) noexcept; // constexpr in C++14
-template <intsize_t I, class... T>
+template <size_t I, class... T>
     typename tuple_element<I, tuple<T...>>::type&&
     get(tuple<T...>&&) noexcept; // constexpr in C++14
+template <size_t I, class... T>
+    const typename tuple_element<I, tuple<T...>>::type&&
+    get(const tuple<T...>&&) noexcept; // constexpr in C++14
 
 template <class T1, class... T>
     constexpr T1& get(tuple<T...>&) noexcept;  // C++14
 template <class T1, class... T>
-    constexpr T1 const& get(const tuple<T...>&) noexcept;   // C++14
+    constexpr const T1& get(const tuple<T...>&) noexcept;   // C++14
 template <class T1, class... T>
     constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
+template <class T1, class... T>
+    constexpr const T1&& get(const tuple<T...>&&) noexcept;   // C++14
 
 // 20.4.1.6, relational operators:
 template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
@@ -379,6 +384,9 @@
     : is_same<__all<_Pred...>, __all<(_Pred, true)...>>
 { };
 
+template <class ..._Tp>
+struct __lazy_all : __all<_Tp::value...> {};
+
 template <class _Tp>
 struct __all_default_constructible;
 
@@ -441,7 +449,7 @@
     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
@@ -494,6 +502,28 @@
     }
 };
 
+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
 {
@@ -501,12 +531,126 @@
 
     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
         const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
     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
+        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
 public:
 
     template <bool _Dummy = true, class = typename enable_if<
@@ -516,8 +660,30 @@
     _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_base_of<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(),
@@ -525,7 +691,33 @@
                 __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,
@@ -536,24 +728,33 @@
                 __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(),
+                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
+                typename __make_tuple_indices<0>::type(),
+                typename __make_tuple_types<tuple, 0>::type(),
+                __t...
+               ) {}
+
     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
              >
@@ -577,31 +778,12 @@
     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
@@ -622,24 +804,14 @@
                     _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)
@@ -650,10 +822,33 @@
                     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(),
+                    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 _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
              >
@@ -664,8 +859,10 @@
     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
              >
@@ -675,15 +872,32 @@
             : 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)) {}
+
     template <class _Tuple,
               class = typename enable_if
                       <
@@ -766,6 +980,16 @@
              static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get());
 }
 
+template <size_t _Ip, class ..._Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const typename tuple_element<_Ip, tuple<_Tp...> >::type&&
+get(const tuple<_Tp...>&& __t) _NOEXCEPT
+{
+    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
+    return static_cast<const type&&>(
+             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.base_).get());
+}
+
 #if _LIBCPP_STD_VER > 11
 // get by type
 template <typename _T1, size_t _Idx, typename... _Args>
@@ -822,6 +1046,13 @@
     return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
 }
 
+template <class _T1, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
+{
+    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
+}
+
 #endif
 
 // tie
diff --git a/include/type_traits b/include/type_traits
index f0defaf..a8b0bd0 100644
--- a/include/type_traits
+++ b/include/type_traits
@@ -105,6 +105,8 @@
     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 @@
     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 @@
     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>
@@ -203,8 +215,172 @@
       using result_of_t       = typename result_of<F(ArgTypes...)>::type;  // C++14
 
     template <class...>
-      using void_t = void;
-}  // C++17
+      using void_t = void;   // C++17
+      
+      // See C++14 20.10.4.1, primary type categories
+      template <class T> constexpr bool is_void_v
+        = is_void<T>::value;                                             // C++17
+      template <class T> constexpr bool is_null_pointer_v
+        = is_null_pointer<T>::value;                                     // C++17
+      template <class T> constexpr bool is_integral_v
+        = is_integral<T>::value;                                         // C++17
+      template <class T> constexpr bool is_floating_point_v
+        = is_floating_point<T>::value;                                   // C++17
+      template <class T> constexpr bool is_array_v
+        = is_array<T>::value;                                            // C++17
+      template <class T> constexpr bool is_pointer_v
+        = is_pointer<T>::value;                                          // C++17
+      template <class T> constexpr bool is_lvalue_reference_v
+        = is_lvalue_reference<T>::value;                                 // C++17
+      template <class T> constexpr bool is_rvalue_reference_v
+        = is_rvalue_reference<T>::value;                                 // C++17
+      template <class T> constexpr bool is_member_object_pointer_v
+        = is_member_object_pointer<T>::value;                            // C++17
+      template <class T> constexpr bool is_member_function_pointer_v
+        = is_member_function_pointer<T>::value;                          // C++17
+      template <class T> constexpr bool is_enum_v
+        = is_enum<T>::value;                                             // C++17
+      template <class T> constexpr bool is_union_v
+        = is_union<T>::value;                                            // C++17
+      template <class T> constexpr bool is_class_v
+        = is_class<T>::value;                                            // C++17
+      template <class T> constexpr bool is_function_v
+        = is_function<T>::value;                                         // C++17
+
+      // See C++14 20.10.4.2, composite type categories
+      template <class T> constexpr bool is_reference_v
+        = is_reference<T>::value;                                        // C++17
+      template <class T> constexpr bool is_arithmetic_v
+        = is_arithmetic<T>::value;                                       // C++17
+      template <class T> constexpr bool is_fundamental_v
+        = is_fundamental<T>::value;                                      // C++17
+      template <class T> constexpr bool is_object_v
+        = is_object<T>::value;                                           // C++17
+      template <class T> constexpr bool is_scalar_v
+        = is_scalar<T>::value;                                           // C++17
+      template <class T> constexpr bool is_compound_v
+        = is_compound<T>::value;                                         // C++17
+      template <class T> constexpr bool is_member_pointer_v
+        = is_member_pointer<T>::value;                                   // C++17
+
+      // See C++14 20.10.4.3, type properties
+      template <class T> constexpr bool is_const_v
+        = is_const<T>::value;                                            // C++17
+      template <class T> constexpr bool is_volatile_v
+        = is_volatile<T>::value;                                         // C++17
+      template <class T> constexpr bool is_trivial_v
+        = is_trivial<T>::value;                                          // C++17
+      template <class T> constexpr bool is_trivially_copyable_v
+        = is_trivially_copyable<T>::value;                               // C++17
+      template <class T> constexpr bool is_standard_layout_v
+        = is_standard_layout<T>::value;                                  // C++17
+      template <class T> constexpr bool is_pod_v
+        = is_pod<T>::value;                                              // C++17
+      template <class T> constexpr bool is_literal_type_v
+        = is_literal_type<T>::value;                                     // C++17
+      template <class T> constexpr bool is_empty_v
+        = is_empty<T>::value;                                            // C++17
+      template <class T> constexpr bool is_polymorphic_v
+        = is_polymorphic<T>::value;                                      // C++17
+      template <class T> constexpr bool is_abstract_v
+        = is_abstract<T>::value;                                         // C++17
+      template <class T> constexpr bool is_final_v
+        = is_final<T>::value;                                            // C++17
+      template <class T> constexpr bool is_signed_v
+        = is_signed<T>::value;                                           // C++17
+      template <class T> constexpr bool is_unsigned_v
+        = is_unsigned<T>::value;                                         // C++17
+      template <class T, class... Args> constexpr bool is_constructible_v
+        = is_constructible<T, Args...>::value;                           // C++17
+      template <class T> constexpr bool is_default_constructible_v
+        = is_default_constructible<T>::value;                            // C++17
+      template <class T> constexpr bool is_copy_constructible_v
+        = is_copy_constructible<T>::value;                               // C++17
+      template <class T> constexpr bool is_move_constructible_v
+        = is_move_constructible<T>::value;                               // C++17
+      template <class T, class U> constexpr bool is_assignable_v
+        = is_assignable<T, U>::value;                                    // C++17
+      template <class T> constexpr bool is_copy_assignable_v
+        = 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
+        = is_trivially_constructible<T, Args...>::value;                 // C++17
+      template <class T> constexpr bool is_trivially_default_constructible_v
+        = is_trivially_default_constructible<T>::value;                  // C++17
+      template <class T> constexpr bool is_trivially_copy_constructible_v
+        = is_trivially_copy_constructible<T>::value;                     // C++17
+      template <class T> constexpr bool is_trivially_move_constructible_v
+        = is_trivially_move_constructible<T>::value;                     // C++17
+      template <class T, class U> constexpr bool is_trivially_assignable_v
+        = is_trivially_assignable<T, U>::value;                          // C++17
+      template <class T> constexpr bool is_trivially_copy_assignable_v
+        = is_trivially_copy_assignable<T>::value;                        // C++17
+      template <class T> constexpr bool is_trivially_move_assignable_v
+        = is_trivially_move_assignable<T>::value;                        // C++17
+      template <class T> constexpr bool is_trivially_destructible_v
+        = is_trivially_destructible<T>::value;                           // C++17
+      template <class T, class... Args> constexpr bool is_nothrow_constructible_v
+        = is_nothrow_constructible<T, Args...>::value;                   // C++17
+      template <class T> constexpr bool is_nothrow_default_constructible_v
+        = is_nothrow_default_constructible<T>::value;                    // C++17
+      template <class T> constexpr bool is_nothrow_copy_constructible_v
+        = is_nothrow_copy_constructible<T>::value;                       // C++17
+      template <class T> constexpr bool is_nothrow_move_constructible_v
+        = is_nothrow_move_constructible<T>::value;                       // C++17
+      template <class T, class U> constexpr bool is_nothrow_assignable_v
+        = is_nothrow_assignable<T, U>::value;                            // C++17
+      template <class T> constexpr bool is_nothrow_copy_assignable_v
+        = 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
+        = has_virtual_destructor<T>::value;                              // C++17
+
+      // See C++14 20.10.5, type property queries
+      template <class T> constexpr size_t alignment_of_v
+        = alignment_of<T>::value;                                        // C++17
+      template <class T> constexpr size_t rank_v
+        = rank<T>::value;                                                // C++17
+      template <class T, unsigned I = 0> constexpr size_t extent_v
+        = extent<T, I>::value;                                           // C++17
+
+      // See C++14 20.10.6, type relations
+      template <class T, class U> constexpr bool is_same_v
+        = is_same<T, U>::value;                                          // C++17
+      template <class Base, class Derived> constexpr bool is_base_of_v
+        = 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
+      template<class... B> 
+        constexpr bool conjunction_v = conjunction<B...>::value;         // C++17
+      template<class... B> struct disjunction;                           // C++17
+      template<class... B>
+        constexpr bool disjunction_v = disjunction<B...>::value;         // C++17
+      template<class B> struct negation;                                 // C++17
+      template<class B> 
+        constexpr bool negation_v = negation<B>::value;                  // C++17
+
+}
 
 */
 #include <__config>
@@ -216,6 +392,10 @@
 
 _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; };
 
@@ -244,6 +424,69 @@
 template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
 #endif
 
+// addressof
+#if __has_builtin(__builtin_addressof)
+
+template <class _Tp>
+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
+// _LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF is defined, the compiler
+// itself is providing these definitions. Otherwise, we provide them.
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__strong _Tp*
+addressof(__strong _Tp& __x) _NOEXCEPT
+{
+  return &__x;
+}
+
+#ifdef _LIBCPP_HAS_OBJC_ARC_WEAK
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__weak _Tp*
+addressof(__weak _Tp& __x) _NOEXCEPT
+{
+  return &__x;
+}
+#endif
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__autoreleasing _Tp*
+addressof(__autoreleasing _Tp& __x) _NOEXCEPT
+{
+  return &__x;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__unsafe_unretained _Tp*
+addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT
+{
+  return &__x;
+}
+#endif
 
 struct __two {char __lx[2];};
 
@@ -269,24 +512,111 @@
 #if _LIBCPP_STD_VER > 14
 template <bool __b>
 using bool_constant = integral_constant<bool, __b>;
-#define	_LIBCPP_BOOL_CONSTANT(__b) bool_constant<(__b)>
+#define _LIBCPP_BOOL_CONSTANT(__b) bool_constant<(__b)>
 #else
-#define	_LIBCPP_BOOL_CONSTANT(__b) integral_constant<bool,(__b)>
+#define _LIBCPP_BOOL_CONSTANT(__b) integral_constant<bool,(__b)>
 #endif
 
 typedef _LIBCPP_BOOL_CONSTANT(true)  true_type;
 typedef _LIBCPP_BOOL_CONSTANT(false) false_type;
 
+#if !defined(_LIBCPP_HAS_NO_VARIADICS)
+
+// __lazy_and
+
+template <bool _Last, class ..._Preds>
+struct __lazy_and_impl;
+
+template <class ..._Preds>
+struct __lazy_and_impl<false, _Preds...> : false_type {};
+
+template <>
+struct __lazy_and_impl<true> : true_type {};
+
+template <class _Pred>
+struct __lazy_and_impl<true, _Pred> : integral_constant<bool, _Pred::type::value> {};
+
+template <class _Hp, class ..._Tp>
+struct __lazy_and_impl<true, _Hp, _Tp...> : __lazy_and_impl<_Hp::type::value, _Tp...> {};
+
+template <class _P1, class ..._Pr>
+struct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {};
+
+// __lazy_or
+
+template <bool _List, class ..._Preds>
+struct __lazy_or_impl;
+
+template <class ..._Preds>
+struct __lazy_or_impl<true, _Preds...> : true_type {};
+
+template <>
+struct __lazy_or_impl<false> : false_type {};
+
+template <class _Hp, class ..._Tp>
+struct __lazy_or_impl<false, _Hp, _Tp...>
+        : __lazy_or_impl<_Hp::type::value, _Tp...> {};
+
+template <class _P1, class ..._Pr>
+struct __lazy_or : __lazy_or_impl<_P1::type::value, _Pr...> {};
+
+// __lazy_not
+
+template <class _Pred>
+struct __lazy_not : integral_constant<bool, !_Pred::type::value> {};
+
+// __and_
+template<class...> struct __and_;
+template<> struct __and_<> : true_type {};
+
+template<class _B0> struct __and_<_B0> : _B0 {};
+
+template<class _B0, class _B1>
+struct __and_<_B0, _B1> : conditional<_B0::value, _B1, _B0>::type {};
+
+template<class _B0, class _B1, class _B2, class... _Bn>
+struct __and_<_B0, _B1, _B2, _Bn...> 
+        : conditional<_B0::value, __and_<_B1, _B2, _Bn...>, _B0>::type {};
+
+// __or_
+template<class...> struct __or_;
+template<> struct __or_<> : false_type {};
+
+template<class _B0> struct __or_<_B0> : _B0 {};
+
+template<class _B0, class _B1>
+struct __or_<_B0, _B1> : conditional<_B0::value, _B0, _B1>::type {};
+
+template<class _B0, class _B1, class _B2, class... _Bn>
+struct __or_<_B0, _B1, _B2, _Bn...> 
+        : conditional<_B0::value, _B0, __or_<_B1, _B2, _Bn...> >::type {};
+
+// __not_
+template<class _Tp> 
+struct __not_ : conditional<_Tp::value, false_type, true_type>::type {};
+
+#endif // !defined(_LIBCPP_HAS_NO_VARIADICS)
+
 // is_const
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_const            : public false_type {};
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_const<_Tp const> : public true_type {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_const_v
+    = is_const<_Tp>::value;
+#endif
+
 // is_volatile
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_volatile               : public false_type {};
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_volatile<_Tp volatile> : public true_type {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_volatile_v
+    = is_volatile<_Tp>::value;
+#endif
+
 // remove_const
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_const            {typedef _Tp type;};
@@ -319,6 +649,11 @@
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_void
     : public __libcpp_is_void<typename remove_cv<_Tp>::type> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_void_v
+    = is_void<_Tp>::value;
+#endif
+
 // __is_nullptr_t
 
 template <class _Tp> struct __is_nullptr_t_impl       : public false_type {};
@@ -330,6 +665,11 @@
 #if _LIBCPP_STD_VER > 11
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_null_pointer
     : public __is_nullptr_t_impl<typename remove_cv<_Tp>::type> {};
+
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_null_pointer_v
+    = is_null_pointer<_Tp>::value;
+#endif
 #endif
 
 // is_integral
@@ -360,6 +700,11 @@
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_integral
     : public __libcpp_is_integral<typename remove_cv<_Tp>::type> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_integral_v
+    = is_integral<_Tp>::value;
+#endif
+
 // is_floating_point
 
 template <class _Tp> struct __libcpp_is_floating_point              : public false_type {};
@@ -370,6 +715,11 @@
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_floating_point
     : public __libcpp_is_floating_point<typename remove_cv<_Tp>::type> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_floating_point_v
+    = is_floating_point<_Tp>::value;
+#endif
+
 // is_array
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_array
@@ -379,6 +729,11 @@
 template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY is_array<_Tp[_Np]>
     : public true_type {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_array_v
+    = is_array<_Tp>::value;
+#endif
+
 // is_pointer
 
 template <class _Tp> struct __libcpp_is_pointer       : public false_type {};
@@ -387,6 +742,11 @@
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_pointer
     : public __libcpp_is_pointer<typename remove_cv<_Tp>::type> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_pointer_v
+    = is_pointer<_Tp>::value;
+#endif
+
 // is_reference
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_lvalue_reference       : public false_type {};
@@ -403,6 +763,16 @@
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_reference<_Tp&&> : public true_type {};
 #endif
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_reference_v
+    = is_reference<_Tp>::value;
+
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_lvalue_reference_v
+    = is_lvalue_reference<_Tp>::value;
+
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_rvalue_reference_v
+    = is_rvalue_reference<_Tp>::value;
+#endif
 // is_union
 
 #if __has_feature(is_union) || (_GNUC_VER >= 403)
@@ -418,6 +788,11 @@
 
 #endif
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_union_v
+    = is_union<_Tp>::value;
+#endif
+
 // is_class
 
 #if __has_feature(is_class) || (_GNUC_VER >= 403)
@@ -438,11 +813,21 @@
 
 #endif
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_class_v
+    = is_class<_Tp>::value;
+#endif
+
 // is_same
 
 template <class _Tp, class _Up> struct _LIBCPP_TYPE_VIS_ONLY is_same           : public false_type {};
 template <class _Tp>            struct _LIBCPP_TYPE_VIS_ONLY is_same<_Tp, _Tp> : public true_type {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_same_v
+    = is_same<_Tp, _Up>::value;
+#endif
+
 // is_function
 
 namespace __libcpp_is_function_imp
@@ -468,6 +853,11 @@
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_function
     : public __libcpp_is_function<_Tp> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_function_v
+    = is_function<_Tp>::value;
+#endif
+
 // is_member_function_pointer
 
 // template <class _Tp> struct            __libcpp_is_member_function_pointer             : public false_type {};
@@ -490,6 +880,11 @@
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_function_pointer
     : public __libcpp_is_member_function_pointer<typename remove_cv<_Tp>::type>::type {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_member_function_pointer_v
+    = is_member_function_pointer<_Tp>::value;
+#endif
+
 // is_member_pointer
 
 template <class _Tp>            struct __libcpp_is_member_pointer             : public false_type {};
@@ -498,12 +893,22 @@
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_pointer
     : public __libcpp_is_member_pointer<typename remove_cv<_Tp>::type> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_member_pointer_v
+    = is_member_pointer<_Tp>::value;
+#endif
+
 // is_member_object_pointer
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_object_pointer
     : public integral_constant<bool, is_member_pointer<_Tp>::value &&
                                     !is_member_function_pointer<_Tp>::value> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_member_object_pointer_v
+    = is_member_object_pointer<_Tp>::value;
+#endif
+
 // is_enum
 
 #if __has_feature(is_enum) || (_GNUC_VER >= 403)
@@ -527,12 +932,22 @@
 
 #endif
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_enum_v
+    = is_enum<_Tp>::value;
+#endif
+
 // is_arithmetic
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_arithmetic
     : public integral_constant<bool, is_integral<_Tp>::value      ||
                                      is_floating_point<_Tp>::value> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_arithmetic_v
+    = is_arithmetic<_Tp>::value;
+#endif
+
 // is_fundamental
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_fundamental
@@ -540,6 +955,11 @@
                                      __is_nullptr_t<_Tp>::value ||
                                      is_arithmetic<_Tp>::value> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_fundamental_v
+    = is_fundamental<_Tp>::value;
+#endif
+
 // is_scalar
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_scalar
@@ -551,6 +971,11 @@
 
 template <> struct _LIBCPP_TYPE_VIS_ONLY is_scalar<nullptr_t> : public true_type {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_scalar_v
+    = is_scalar<_Tp>::value;
+#endif
+
 // is_object
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_object
@@ -559,11 +984,34 @@
                                      is_union<_Tp>::value  ||
                                      is_class<_Tp>::value  > {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_object_v
+    = is_object<_Tp>::value;
+#endif
+
 // is_compound
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_compound
     : public integral_constant<bool, !is_fundamental<_Tp>::value> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+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 ||
@@ -621,12 +1069,11 @@
 
 // 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;
@@ -634,11 +1081,11 @@
 
 #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;
@@ -648,8 +1095,11 @@
 
 #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
@@ -660,6 +1110,24 @@
 
 #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(...);
@@ -679,8 +1147,16 @@
 
 // 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;
@@ -701,6 +1177,11 @@
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_signed : public __libcpp_is_signed<_Tp> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_signed_v
+    = is_signed<_Tp>::value;
+#endif
+
 // is_unsigned
 
 template <class _Tp, bool = is_integral<_Tp>::value>
@@ -716,6 +1197,11 @@
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_unsigned : public __libcpp_is_unsigned<_Tp> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_unsigned_v
+    = is_unsigned<_Tp>::value;
+#endif
+
 // rank
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY rank
@@ -725,6 +1211,11 @@
 template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY rank<_Tp[_Np]>
     : public integral_constant<size_t, rank<_Tp>::value + 1> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR size_t rank_v
+    = rank<_Tp>::value;
+#endif
+
 // extent
 
 template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TYPE_VIS_ONLY extent
@@ -738,6 +1229,11 @@
 template <class _Tp, size_t _Np, unsigned _Ip> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[_Np], _Ip>
     : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp, unsigned _Ip = 0> _LIBCPP_CONSTEXPR size_t extent_v
+    = extent<_Tp, _Ip>::value;
+#endif
+
 // remove_extent
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_extent
@@ -804,6 +1300,11 @@
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_abstract : public __libcpp_abstract<_Tp> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_abstract_v
+    = is_abstract<_Tp>::value;
+#endif
+
 // is_final
 
 #if defined(_LIBCPP_HAS_IS_FINAL)
@@ -819,6 +1320,11 @@
 is_final : public integral_constant<bool, __is_final(_Tp)> {};
 #endif
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_final_v
+    = is_final<_Tp>::value;
+#endif
+
 // is_base_of
 
 #ifdef _LIBCPP_HAS_IS_BASE_OF
@@ -854,6 +1360,11 @@
 
 #endif  // _LIBCPP_HAS_IS_BASE_OF
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Bp, class _Dp> _LIBCPP_CONSTEXPR bool is_base_of_v
+    = is_base_of<_Bp, _Dp>::value;
+#endif
+
 // is_convertible
 
 #if __has_feature(is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
@@ -873,16 +1384,9 @@
 
 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>
@@ -922,41 +1426,6 @@
     >
 {};
 
-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 {};
@@ -981,6 +1450,11 @@
 
 #endif  // __has_feature(is_convertible_to)
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _From, class _To> _LIBCPP_CONSTEXPR bool is_convertible_v
+    = is_convertible<_From, _To>::value;
+#endif
+
 // is_empty
 
 #if __has_feature(is_empty) || (_GNUC_VER >= 407)
@@ -1012,6 +1486,11 @@
 
 #endif  // __has_feature(is_empty)
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_empty_v
+    = is_empty<_Tp>::value;
+#endif
+
 // is_polymorphic
 
 #if __has_feature(is_polymorphic) || defined(_LIBCPP_MSVC)
@@ -1032,6 +1511,11 @@
 
 #endif // __has_feature(is_polymorphic)
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_polymorphic_v
+    = is_polymorphic<_Tp>::value;
+#endif
+
 // has_virtual_destructor
 
 #if __has_feature(has_virtual_destructor) || (_GNUC_VER >= 403)
@@ -1046,11 +1530,21 @@
 
 #endif
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool has_virtual_destructor_v
+    = has_virtual_destructor<_Tp>::value;
+#endif
+
 // alignment_of
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY alignment_of
     : public integral_constant<size_t, __alignof__(_Tp)> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR size_t alignment_of_v
+    = alignment_of<_Tp>::value;
+#endif
+
 // aligned_storage
 
 template <class _Hp, class _Tp>
@@ -1143,7 +1637,7 @@
     union type
     {
         _Aligner __align;
-        unsigned char __data[_Len];
+        unsigned char __data[(_Len + _Align - 1)/_Align * _Align];
     };
 };
 
@@ -1158,7 +1652,7 @@
 {\
     struct _ALIGNAS(n) type\
     {\
-        unsigned char __lx[_Len];\
+        unsigned char __lx[(_Len + n - 1)/n * n];\
     };\
 }
 
@@ -1290,18 +1784,6 @@
 template <class _A1, class _A2 = void, class _A3 = void>
 class __promote : public __promote_imp<_A1, _A2, _A3> {};
 
-#ifdef _LIBCPP_STORE_AS_OPTIMIZATION
-
-// __transform
-
-template <class _Tp, size_t = sizeof(_Tp), bool = is_scalar<_Tp>::value> struct __transform {typedef _Tp type;};
-template <class _Tp> struct __transform<_Tp, 1, true> {typedef unsigned char      type;};
-template <class _Tp> struct __transform<_Tp, 2, true> {typedef unsigned short     type;};
-template <class _Tp> struct __transform<_Tp, 4, true> {typedef unsigned int       type;};
-template <class _Tp> struct __transform<_Tp, 8, true> {typedef unsigned long long type;};
-
-#endif  // _LIBCPP_STORE_AS_OPTIMIZATION
-
 // make_signed / make_unsigned
 
 typedef
@@ -1482,21 +1964,19 @@
 template <class _Tp, class _Up>
 struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up, void>
 {
-private:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    static _Tp&& __t();
-    static _Up&& __u();
-#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    static _Tp __t();
-    static _Up __u();
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-public:
-    typedef typename remove_reference<decltype(true ? __t() : __u())>::type type;
+    typedef typename decay<decltype(
+        true ? _VSTD::declval<_Tp>() : _VSTD::declval<_Up>()
+      )>::type type;
 };
 
 #else  // _LIBCPP_HAS_NO_VARIADICS
 
-template <class ..._Tp> struct common_type;
+// bullet 1 - sizeof...(Tp) == 0
+
+template <class ..._Tp>
+struct _LIBCPP_TYPE_VIS_ONLY common_type {};
+
+// bullet 2 - sizeof...(Tp) == 1
 
 template <class _Tp>
 struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp>
@@ -1504,22 +1984,45 @@
     typedef typename decay<_Tp>::type type;
 };
 
+// bullet 3 - sizeof...(Tp) == 2
+
+template <class _Tp, class _Up, class = void>
+struct __common_type2 {};
+
+template <class _Tp, class _Up>
+struct __common_type2<_Tp, _Up,
+    typename __void_t<decltype(
+        true ? _VSTD::declval<_Tp>() : _VSTD::declval<_Up>()
+    )>::type>
+{
+    typedef typename decay<decltype(
+        true ? _VSTD::declval<_Tp>() : _VSTD::declval<_Up>()
+    )>::type type;
+};
+
 template <class _Tp, class _Up>
 struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up>
+    : __common_type2<_Tp, _Up> {};
+
+// bullet 4 - sizeof...(Tp) > 2
+
+template <class ...Tp> struct __common_types;
+
+template <class, class = void>
+struct __common_type_impl {};
+
+template <class _Tp, class _Up, class ..._Vp>
+struct __common_type_impl<__common_types<_Tp, _Up, _Vp...>,
+    typename __void_t<typename common_type<_Tp, _Up>::type>::type>
 {
-private:
-    static _Tp&& __t();
-    static _Up&& __u();
-    static bool __f();
-public:
-    typedef typename decay<decltype(__f() ? __t() : __u())>::type type;
+    typedef typename common_type<
+        typename common_type<_Tp, _Up>::type, _Vp...
+    >::type type;
 };
 
 template <class _Tp, class _Up, class ..._Vp>
 struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up, _Vp...>
-{
-    typedef typename common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
-};
+    : __common_type_impl<__common_types<_Tp, _Up, _Vp...> > {};
 
 #if _LIBCPP_STD_VER > 11
 template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type;
@@ -1564,12 +2067,22 @@
 struct is_assignable
     : public __is_assignable_imp<_Tp, _Arg> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp, class _Arg> _LIBCPP_CONSTEXPR bool is_assignable_v
+    = is_assignable<_Tp, _Arg>::value;
+#endif
+
 // is_copy_assignable
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_copy_assignable
     : public is_assignable<typename add_lvalue_reference<_Tp>::type,
                   typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_copy_assignable_v
+    = is_copy_assignable<_Tp>::value;
+#endif
+
 // is_move_assignable
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_move_assignable
@@ -1580,6 +2093,11 @@
     : public is_copy_assignable<_Tp> {};
 #endif
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_move_assignable_v
+    = is_move_assignable<_Tp>::value;
+#endif
+
 // is_destructible
 
 //  if it's a reference, return true
@@ -1638,6 +2156,11 @@
 struct is_destructible<void>
     : public _VSTD::false_type {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_destructible_v
+    = is_destructible<_Tp>::value;
+#endif
+
 // move
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1654,7 +2177,7 @@
 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);
 }
@@ -1662,9 +2185,9 @@
 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);
 }
@@ -1690,7 +2213,7 @@
 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;
 }
@@ -2209,6 +2732,15 @@
 //     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;
@@ -2672,6 +3204,11 @@
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 #endif  // __has_feature(is_constructible)
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+template <class _Tp, class ..._Args> _LIBCPP_CONSTEXPR bool is_constructible_v
+    = is_constructible<_Tp, _Args...>::value;
+#endif
+
 // is_default_constructible
 
 template <class _Tp>
@@ -2679,6 +3216,11 @@
     : public is_constructible<_Tp>
     {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_default_constructible_v
+    = is_default_constructible<_Tp>::value;
+#endif
+
 // is_copy_constructible
 
 template <class _Tp>
@@ -2686,6 +3228,11 @@
     : public is_constructible<_Tp, 
                   typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_copy_constructible_v
+    = is_copy_constructible<_Tp>::value;
+#endif
+
 // is_move_constructible
 
 template <class _Tp>
@@ -2697,6 +3244,11 @@
 #endif
     {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_move_constructible_v
+    = is_move_constructible<_Tp>::value;
+#endif
+
 // is_trivially_constructible
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
@@ -2824,18 +3376,33 @@
 
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+template <class _Tp, class... _Args> _LIBCPP_CONSTEXPR bool is_trivially_constructible_v
+    = is_trivially_constructible<_Tp, _Args...>::value;
+#endif
+
 // is_trivially_default_constructible
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_default_constructible
     : public is_trivially_constructible<_Tp>
     {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_default_constructible_v
+    = is_trivially_default_constructible<_Tp>::value;
+#endif
+
 // is_trivially_copy_constructible
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copy_constructible
     : public is_trivially_constructible<_Tp, typename add_lvalue_reference<const _Tp>::type>
     {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_copy_constructible_v
+    = is_trivially_copy_constructible<_Tp>::value;
+#endif
+
 // is_trivially_move_constructible
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_move_constructible
@@ -2846,6 +3413,11 @@
 #endif
     {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_move_constructible_v
+    = is_trivially_move_constructible<_Tp>::value;
+#endif
+
 // is_trivially_assignable
 
 #if __has_feature(is_trivially_assignable) || _GNUC_VER >= 501
@@ -2884,12 +3456,22 @@
 
 #endif  // !__has_feature(is_trivially_assignable)
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp, class _Arg> _LIBCPP_CONSTEXPR bool is_trivially_assignable_v
+    = is_trivially_assignable<_Tp, _Arg>::value;
+#endif
+
 // is_trivially_copy_assignable
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copy_assignable
     : public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type,
                   typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_copy_assignable_v
+    = is_trivially_copy_assignable<_Tp>::value;
+#endif
+
 // is_trivially_move_assignable
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_move_assignable
@@ -2901,6 +3483,11 @@
 #endif
     {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_move_assignable_v
+    = is_trivially_move_assignable<_Tp>::value;
+#endif
+
 // is_trivially_destructible
 
 #if __has_feature(has_trivial_destructor) || (_GNUC_VER >= 403)
@@ -2922,6 +3509,11 @@
 
 #endif
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_destructible_v
+    = is_trivially_destructible<_Tp>::value;
+#endif
+
 // is_nothrow_constructible
 
 #if 0
@@ -3082,18 +3674,33 @@
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 #endif  // __has_feature(is_nothrow_constructible)
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+template <class _Tp, class ..._Args> _LIBCPP_CONSTEXPR bool is_nothrow_constructible_v
+    = is_nothrow_constructible<_Tp, _Args...>::value;
+#endif
+
 // is_nothrow_default_constructible
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_default_constructible
     : public is_nothrow_constructible<_Tp>
     {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_default_constructible_v
+    = is_nothrow_default_constructible<_Tp>::value;
+#endif
+
 // is_nothrow_copy_constructible
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_copy_constructible
     : public is_nothrow_constructible<_Tp,
                   typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_copy_constructible_v
+    = is_nothrow_copy_constructible<_Tp>::value;
+#endif
+
 // is_nothrow_move_constructible
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_move_constructible
@@ -3104,6 +3711,11 @@
 #endif
     {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_move_constructible_v
+    = is_nothrow_move_constructible<_Tp>::value;
+#endif
+
 // is_nothrow_assignable
 
 #if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)
@@ -3172,12 +3784,22 @@
 
 #endif  // __has_feature(cxx_noexcept)
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp, class _Arg> _LIBCPP_CONSTEXPR bool is_nothrow_assignable_v
+    = is_nothrow_assignable<_Tp, _Arg>::value;
+#endif
+
 // is_nothrow_copy_assignable
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_copy_assignable
     : public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type,
                   typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_copy_assignable_v
+    = is_nothrow_copy_assignable<_Tp>::value;
+#endif
+
 // is_nothrow_move_assignable
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_move_assignable
@@ -3189,6 +3811,11 @@
 #endif
     {};
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_move_assignable_v
+    = is_nothrow_move_assignable<_Tp>::value;
+#endif
+
 // is_nothrow_destructible
 
 #if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)
@@ -3250,6 +3877,11 @@
 
 #endif
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_destructible_v
+    = is_nothrow_destructible<_Tp>::value;
+#endif
+
 // is_pod
 
 #if __has_feature(is_pod) || (_GNUC_VER >= 403)
@@ -3267,6 +3899,11 @@
 
 #endif
 
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_pod_v
+    = is_pod<_Tp>::value;
+#endif
+
 // is_literal_type;
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_literal_type
@@ -3278,6 +3915,11 @@
 #endif
     {};
     
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_literal_type_v
+    = is_literal_type<_Tp>::value;
+#endif
+
 // is_standard_layout;
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_standard_layout
@@ -3288,6 +3930,11 @@
 #endif
     {};
     
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_standard_layout_v
+    = is_standard_layout<_Tp>::value;
+#endif
+
 // is_trivially_copyable;
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copyable
@@ -3300,6 +3947,11 @@
 #endif
     {};
     
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_copyable_v
+    = is_trivially_copyable<_Tp>::value;
+#endif
+
 // is_trivial;
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivial
@@ -3311,7 +3963,17 @@
 #endif
     {};
 
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivial_v
+    = is_trivial<_Tp>::value;
+#endif
+
+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
 
@@ -3399,8 +4061,6 @@
 {
 };
 
-#if __has_feature(cxx_reference_qualified_functions)
-
 template <class _Rp, class _Class, class ..._Param>
 struct __check_complete<_Rp (_Class::*)(_Param...) &>
     : private __check_complete<_Class>
@@ -3449,125 +4109,257 @@
 {
 };
 
-#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;
+auto __invoke(__any, _Args&& ...__args) -> __nat;
 
-// bullets 1 and 2
+template <class ..._Args>
+auto __invoke_constexpr(__any, _Args&& ...__args) -> __nat;
+
+// bullets 1, 2 and 3
 
 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_bullet1<_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 = 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_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 = __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)...))
 
-// bullets 3 and 4
+template <class _Fp, class _A0, class ..._Args,
+          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)
+_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 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 = 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
+_LIBCPP_CONSTEXPR auto
+__invoke_constexpr(_Fp&& __f, _A0&& __a0)
+_LIBCPP_INVOKE_RETURN(_VSTD::forward<_A0>(__a0).*__f)
+
+template <class _Fp, class _A0,
+          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...>;
+
+template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class ..._Args>
+struct __nothrow_invokable_r_imp {
+  static const bool value = false;
 };
 
-// __invoke_of
-
-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...>
@@ -3578,7 +4370,39 @@
 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
@@ -3599,6 +4423,13 @@
     __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
@@ -3614,55 +4445,103 @@
 
 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;
+    typedef decltype(swap(_VSTD::declval<_Tp>(), _VSTD::declval<_Up>())) __swap1;
+    typedef decltype(swap(_VSTD::declval<_Up>(), _VSTD::declval<_Tp>())) __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>
-{
-};
-
-#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)
-
-template <bool, class _Tp>
-struct __is_nothrow_swappable_imp
-    : public integral_constant<bool, noexcept(swap(_VSTD::declval<_Tp&>(),
-                                                   _VSTD::declval<_Tp&>()))>
-{
-};
-
-template <class _Tp>
-struct __is_nothrow_swappable_imp<false, _Tp>
-    : public false_type
+    : public integral_constant<bool, __detail::__swappable_with<_Tp&>::value>
 {
 };
 
 template <class _Tp>
 struct __is_nothrow_swappable
-    : public __is_nothrow_swappable_imp<__is_swappable<_Tp>::value, _Tp>
+    : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp&>::value>
 {
 };
 
-#else  // __has_feature(cxx_noexcept)
+#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 false_type
+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
 {
 };
 
-#endif  // __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 _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
+{
+};
+
+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
 
@@ -3689,7 +4568,7 @@
 #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;
@@ -3699,34 +4578,34 @@
 template <class _Tp>
 struct __sfinae_underlying_type<_Tp, false> {};
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
+inline _LIBCPP_INLINE_VISIBILITY
 int __convert_to_integral(int __val) { return __val; }
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
+inline _LIBCPP_INLINE_VISIBILITY
 unsigned __convert_to_integral(unsigned __val) { return __val; }
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
+inline _LIBCPP_INLINE_VISIBILITY
 long __convert_to_integral(long __val) { return __val; }
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
+inline _LIBCPP_INLINE_VISIBILITY
 unsigned long __convert_to_integral(unsigned long __val) { return __val; }
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
+inline _LIBCPP_INLINE_VISIBILITY
 long long __convert_to_integral(long long __val) { return __val; }
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
+inline _LIBCPP_INLINE_VISIBILITY
 unsigned long long __convert_to_integral(unsigned long long __val) {return __val; }
 
 #ifndef _LIBCPP_HAS_NO_INT128
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
+inline _LIBCPP_INLINE_VISIBILITY
 __int128_t __convert_to_integral(__int128_t __val) { return __val; }
 
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
+inline _LIBCPP_INLINE_VISIBILITY
 __uint128_t __convert_to_integral(__uint128_t __val) { return __val; }
 #endif
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
+inline _LIBCPP_INLINE_VISIBILITY
 typename __sfinae_underlying_type<_Tp>::__promoted_type
 __convert_to_integral(_Tp __val) { return __val; }
 
@@ -3766,6 +4645,53 @@
 
 #if _LIBCPP_STD_VER > 14
 template <class...> using void_t = void;
+
+# ifndef _LIBCPP_HAS_NO_VARIADICS
+template <class... _Args>
+struct conjunction : __and_<_Args...> {};
+template<class... _Args> constexpr bool conjunction_v = conjunction<_Args...>::value;
+
+template <class... _Args>
+struct disjunction : __or_<_Args...> {};
+template<class... _Args> constexpr bool disjunction_v = disjunction<_Args...>::value;
+
+template <class _Tp>
+struct negation : __not_<_Tp> {};
+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
diff --git a/include/unordered_map b/include/unordered_map
index cf70ab6..319c71e 100644
--- a/include/unordered_map
+++ b/include/unordered_map
@@ -369,6 +369,7 @@
 #include <__hash_table>
 #include <functional>
 #include <stdexcept>
+#include <tuple>
 
 #include <__debug>
 
@@ -413,7 +414,6 @@
 class __unordered_map_hasher<_Key, _Cp, _Hash, false>
 {
     _Hash __hash_;
-
 public:
     _LIBCPP_INLINE_VISIBILITY
     __unordered_map_hasher()
@@ -487,7 +487,6 @@
 class __unordered_map_equal<_Key, _Cp, _Pred, false>
 {
     _Pred __pred_;
-
 public:
     _LIBCPP_INLINE_VISIBILITY
     __unordered_map_equal()
@@ -531,12 +530,11 @@
 {
     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 @@
     }
 };
 
-#if __cplusplus >= 201103L
-
+#ifndef _LIBCPP_CXX03_LANG
 template <class _Key, class _Tp>
 union __hash_value_type
 {
@@ -599,19 +596,6 @@
     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 @@
     __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 @@
 
     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,21 +645,14 @@
 {
     _HashIterator __i_;
 
-    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;
-    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 __pointer_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<value_type>
-#else
-            rebind<value_type>::other
-#endif
-                                                                 pointer;
+    typedef typename _NodeTypes::__map_value_type_pointer       pointer;
 
     _LIBCPP_INLINE_VISIBILITY
     __hash_map_iterator() _NOEXCEPT {}
@@ -712,21 +694,14 @@
 {
     _HashIterator __i_;
 
-    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;
-    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 __pointer_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<const value_type>
-#else
-            rebind<const value_type>::other
-#endif
-                                                                 pointer;
+    typedef typename _NodeTypes::__const_map_value_type_pointer  pointer;
 
     _LIBCPP_INLINE_VISIBILITY
     __hash_map_const_iterator() _NOEXCEPT {}
@@ -797,6 +772,7 @@
 
     __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;
@@ -805,11 +781,14 @@
     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;
@@ -840,10 +819,12 @@
                       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);
@@ -899,10 +880,12 @@
         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
 
@@ -930,189 +913,162 @@
     _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>
-        pair<iterator, bool> emplace(_Args&&... __args);
-
-    template <class... _Args>
-        _LIBCPP_INLINE_VISIBILITY
-#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;}
-#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
-    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
+
+    iterator insert(const_iterator __p, const value_type& __x) {
 #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;}
+        _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
-#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)
-        {
-            _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");
-            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
+        return insert(__x).first;
+    }
+
     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
+        _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 __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));}
+
+    template <class _Pp,
+              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY
+        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;
+        }
+
+    template <class... _Args>
+    _LIBCPP_INLINE_VISIBILITY
+    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_);}
@@ -1152,7 +1108,7 @@
         {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
 
@@ -1208,18 +1164,10 @@
 #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>
@@ -1246,7 +1194,7 @@
 }
 
 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)
@@ -1322,7 +1270,7 @@
 #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)
@@ -1345,10 +1293,10 @@
     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
@@ -1401,7 +1349,7 @@
 #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)
@@ -1415,7 +1363,7 @@
 #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)
@@ -1426,81 +1374,7 @@
 
 #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)
@@ -1511,12 +1385,13 @@
     __h.get_deleter().__first_constructed = true;
     __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
     __h.get_deleter().__second_constructed = true;
-    return _VSTD::move(__h);  // explicitly moved for C++03
+    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)
@@ -1525,6 +1400,7 @@
         __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)
@@ -1537,23 +1413,27 @@
     __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&
@@ -1647,17 +1527,21 @@
 
     __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;
@@ -1688,10 +1572,12 @@
                       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);
@@ -1748,10 +1634,12 @@
         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
 
@@ -1779,43 +1667,55 @@
     _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
@@ -1902,17 +1802,7 @@
 
 #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>
@@ -1978,7 +1868,7 @@
 }
 
 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)
@@ -2015,7 +1905,7 @@
 #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)
@@ -2041,7 +1931,7 @@
         while (__u.size() != 0)
         {
             __table_.__insert_multi(
-                _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_)
+                      _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_.__nc)
                                    );
         }
     }
@@ -2096,7 +1986,7 @@
 #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)
@@ -2110,7 +2000,7 @@
 #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)
@@ -2121,81 +2011,11 @@
 
 #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 f6ccdc3..fb38b64 100644
--- a/include/unordered_set
+++ b/include/unordered_set
@@ -404,10 +404,12 @@
                       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 @@
         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 @@
 #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 @@
 }
 
 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 @@
 #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 @@
 #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 @@
 #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 @@
 
 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 @@
                        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 @@
         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 @@
         {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 @@
 }
 
 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 @@
 #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 @@
 #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 @@
 
 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 54cfc8b..27b81a0 100644
--- a/include/utility
+++ b/include/utility
@@ -52,6 +52,9 @@
     >::type
     move_if_noexcept(T& x) noexcept; // constexpr in C++14
 
+template <class T> constexpr add_const<T>_t& as_const(T& t) noexcept;      // C++17
+template <class T>                      void as_const(const T&&) = delete; // C++17
+
 template <class T> typename add_rvalue_reference<T>::type declval() noexcept;
 
 template <class T1, class T2>
@@ -79,8 +82,8 @@
                                        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
@@ -110,22 +113,41 @@
     get(pair<T1, T2>&) noexcept; // constexpr in C++14
 
 template<size_t I, class T1, class T2>
-    const typename const tuple_element<I, pair<T1, T2> >::type&
+    const typename tuple_element<I, pair<T1, T2> >::type&
     get(const pair<T1, T2>&) noexcept; // constexpr in C++14
 
 template<size_t I, class T1, class T2>
     typename tuple_element<I, pair<T1, T2> >::type&&
     get(pair<T1, T2>&&) noexcept; // constexpr in C++14
 
+template<size_t I, class T1, class T2>
+    const typename tuple_element<I, pair<T1, T2> >::type&&
+    get(const pair<T1, T2>&&) noexcept; // constexpr in C++14
+
 template<class T1, class T2>
     constexpr T1& get(pair<T1, T2>&) noexcept; // C++14
 
-template<size_t I, class T1, class T2>
-    constexpr T1 const& get(pair<T1, T2> const &) noexcept; // C++14
+template<class T1, class T2>
+    constexpr const T1& get(const pair<T1, T2>&) noexcept; // C++14
 
-template<size_t I, class T1, class T2>
+template<class T1, class T2>
     constexpr T1&& get(pair<T1, T2>&&) noexcept; // C++14
 
+template<class T1, class T2>
+    constexpr const T1&& get(const pair<T1, T2>&&) noexcept; // C++14
+
+template<class T1, class T2>
+    constexpr T1& get(pair<T2, T1>&) noexcept; // C++14
+
+template<class T1, class T2>
+    constexpr const T1& get(const pair<T2, T1>&) noexcept; // C++14
+
+template<class T1, class T2>
+    constexpr T1&& get(pair<T2, T1>&&) noexcept; // C++14
+
+template<class T1, class T2>
+    constexpr const T1&& get(const pair<T2, T1>&&) noexcept; // C++14
+
 // C++14
 
 template<class T, T... I>
@@ -156,6 +178,7 @@
 #include <__config>
 #include <__tuple>
 #include <type_traits>
+#include <initializer_list>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -202,10 +225,6 @@
 
 // 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
@@ -217,9 +236,12 @@
     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);
@@ -242,6 +264,11 @@
     return _VSTD::move(__x);
 }
 
+#if _LIBCPP_STD_VER > 14
+template <class _Tp> constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; }
+template <class _Tp>                        void as_const(const _Tp&&) = delete;
+#endif
+
 struct _LIBCPP_TYPE_VIS_ONLY piecewise_construct_t { };
 #if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_UTILITY)
 extern const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
@@ -261,6 +288,12 @@
     // 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 &&
+        __dependent_type<is_default_constructible<_T2>, _Dummy>::value
+      >::type>
+#endif
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR pair() : first(), second() {}
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
@@ -388,8 +421,9 @@
     swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&
                                __is_nothrow_swappable<second_type>::value)
     {
-        _VSTD::iter_swap(&first, &__p.first);
-        _VSTD::iter_swap(&second, &__p.second);
+        using _VSTD::swap;
+        swap(first,  __p.first);
+        swap(second, __p.second);
     }
 private:
 
@@ -467,7 +501,6 @@
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY reference_wrapper;
 
 template <class _Tp>
 struct __make_pair_return_impl
@@ -551,6 +584,12 @@
     _T1&&
     get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);}
 
+    template <class _T1, class _T2>
+    static
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    const _T1&&
+    get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T1>(__p.first);}
+
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 };
 
@@ -577,6 +616,12 @@
     _T2&&
     get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);}
 
+    template <class _T1, class _T2>
+    static
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    const _T2&&
+    get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T2>(__p.second);}
+
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 };
 
@@ -606,6 +651,14 @@
     return __get_pair<_Ip>::get(_VSTD::move(__p));
 }
 
+template <size_t _Ip, class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
+get(const pair<_T1, _T2>&& __p) _NOEXCEPT
+{
+    return __get_pair<_Ip>::get(_VSTD::move(__p));
+}
+
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 #if _LIBCPP_STD_VER > 11
@@ -632,6 +685,13 @@
 
 template <class _T1, class _T2>
 inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT
+{
+    return __get_pair<0>::get(_VSTD::move(__p));
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
 constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT
 {
     return __get_pair<1>::get(__p);
@@ -651,6 +711,13 @@
     return __get_pair<1>::get(_VSTD::move(__p));
 }
 
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT
+{
+    return __get_pair<1>::get(_VSTD::move(__p));
+}
+
 #endif
 
 #if _LIBCPP_STD_VER > 11
@@ -671,6 +738,16 @@
 template<size_t... _Ip>
     using index_sequence = integer_sequence<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;
+};
+
+#else
+
 namespace __detail {
 
 template<typename _Tp, size_t ..._Extra> struct __repeat;
@@ -724,10 +801,14 @@
 {
     static_assert(is_integral<_Tp>::value,
                   "std::make_integer_sequence can only be instantiated with an integral type" );
-    static_assert(0 <= _Ep, "std::make_integer_sequence input shall not be negative");
-    typedef __make_integer_sequence_unchecked<_Tp, _Ep> type;
+    static_assert(0 <= _Ep, "std::make_integer_sequence must have a non-negative sequence length");
+    // Workaround GCC bug by preventing bad installations when 0 <= _Ep
+    // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68929
+    typedef __make_integer_sequence_unchecked<_Tp, 0 <= _Ep ? _Ep : 0> type;
 };
 
+#endif
+
 template<class _Tp, _Tp _Np>
     using make_integer_sequence = typename __make_integer_sequence<_Tp, _Np>::type;
 
diff --git a/include/valarray b/include/valarray
index bdaa588..bde644e 100644
--- a/include/valarray
+++ b/include/valarray
@@ -802,11 +802,14 @@
     // construct/destroy:
     _LIBCPP_INLINE_VISIBILITY
     valarray() : __begin_(0), __end_(0) {}
-    explicit valarray(size_t __n);
+    _LIBCPP_INLINE_VISIBILITY
+    inline explicit valarray(size_t __n);
+    _LIBCPP_INLINE_VISIBILITY
     valarray(const value_type& __x, size_t __n);
     valarray(const value_type* __p, size_t __n);
     valarray(const valarray& __v);
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     valarray(valarray&& __v) _NOEXCEPT;
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -816,22 +819,31 @@
     valarray(const gslice_array<value_type>& __ga);
     valarray(const mask_array<value_type>& __ma);
     valarray(const indirect_array<value_type>& __ia);
+    inline _LIBCPP_INLINE_VISIBILITY
     ~valarray();
 
     // assignment:
     valarray& operator=(const valarray& __v);
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator=(valarray&& __v) _NOEXCEPT;
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator=(initializer_list<value_type>);
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator=(const value_type& __x);
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator=(const slice_array<value_type>& __sa);
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator=(const gslice_array<value_type>& __ga);
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator=(const mask_array<value_type>& __ma);
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator=(const indirect_array<value_type>& __ia);
     template <class _ValExpr>
+        _LIBCPP_INLINE_VISIBILITY
         valarray& operator=(const __val_expr<_ValExpr>& __v);
 
     // element access:
@@ -842,24 +854,38 @@
     value_type&       operator[](size_t __i)       {return __begin_[__i];}
 
     // subset operations:
+    _LIBCPP_INLINE_VISIBILITY
     __val_expr<__slice_expr<const valarray&> >    operator[](slice __s) const;
+    _LIBCPP_INLINE_VISIBILITY
     slice_array<value_type>                       operator[](slice __s);
+    _LIBCPP_INLINE_VISIBILITY
     __val_expr<__indirect_expr<const valarray&> > operator[](const gslice& __gs) const;
+    _LIBCPP_INLINE_VISIBILITY
     gslice_array<value_type>   operator[](const gslice& __gs);
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     __val_expr<__indirect_expr<const valarray&> > operator[](gslice&& __gs) const;
+    _LIBCPP_INLINE_VISIBILITY
     gslice_array<value_type>                      operator[](gslice&& __gs);
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     __val_expr<__mask_expr<const valarray&> >     operator[](const valarray<bool>& __vb) const;
+    _LIBCPP_INLINE_VISIBILITY
     mask_array<value_type>                        operator[](const valarray<bool>& __vb);
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     __val_expr<__mask_expr<const valarray&> >     operator[](valarray<bool>&& __vb) const;
+    _LIBCPP_INLINE_VISIBILITY
     mask_array<value_type>                        operator[](valarray<bool>&& __vb);
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     __val_expr<__indirect_expr<const valarray&> > operator[](const valarray<size_t>& __vs) const;
+    _LIBCPP_INLINE_VISIBILITY
     indirect_array<value_type>                    operator[](const valarray<size_t>& __vs);
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     __val_expr<__indirect_expr<const valarray&> > operator[](valarray<size_t>&& __vs) const;
+    _LIBCPP_INLINE_VISIBILITY
     indirect_array<value_type>                    operator[](valarray<size_t>&& __vs);
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
@@ -870,15 +896,25 @@
     valarray<bool> operator!() const;
 
     // computed assignment:
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator*= (const value_type& __x);
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator/= (const value_type& __x);
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator%= (const value_type& __x);
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator+= (const value_type& __x);
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator-= (const value_type& __x);
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator^= (const value_type& __x);
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator&= (const value_type& __x);
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator|= (const value_type& __x);
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator<<=(const value_type& __x);
+    _LIBCPP_INLINE_VISIBILITY
     valarray& operator>>=(const value_type& __x);
 
     template <class _Expr>
@@ -887,6 +923,7 @@
         __is_val_expr<_Expr>::value,
         valarray&
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator*= (const _Expr& __v);
 
     template <class _Expr>
@@ -895,6 +932,7 @@
         __is_val_expr<_Expr>::value,
         valarray&
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator/= (const _Expr& __v);
 
     template <class _Expr>
@@ -903,6 +941,7 @@
         __is_val_expr<_Expr>::value,
         valarray&
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator%= (const _Expr& __v);
 
     template <class _Expr>
@@ -911,6 +950,7 @@
         __is_val_expr<_Expr>::value,
         valarray&
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator+= (const _Expr& __v);
 
     template <class _Expr>
@@ -919,6 +959,7 @@
         __is_val_expr<_Expr>::value,
         valarray&
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator-= (const _Expr& __v);
 
     template <class _Expr>
@@ -927,6 +968,7 @@
         __is_val_expr<_Expr>::value,
         valarray&
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator^= (const _Expr& __v);
 
     template <class _Expr>
@@ -935,6 +977,7 @@
         __is_val_expr<_Expr>::value,
         valarray&
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator|= (const _Expr& __v);
 
     template <class _Expr>
@@ -943,6 +986,7 @@
         __is_val_expr<_Expr>::value,
         valarray&
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator&= (const _Expr& __v);
 
     template <class _Expr>
@@ -951,6 +995,7 @@
         __is_val_expr<_Expr>::value,
         valarray&
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator<<= (const _Expr& __v);
 
     template <class _Expr>
@@ -959,16 +1004,21 @@
         __is_val_expr<_Expr>::value,
         valarray&
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator>>= (const _Expr& __v);
 
     // member functions:
+    _LIBCPP_INLINE_VISIBILITY
     void swap(valarray& __v) _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
     size_t size() const {return static_cast<size_t>(__end_ - __begin_);}
 
+    _LIBCPP_INLINE_VISIBILITY
     value_type sum() const;
+    _LIBCPP_INLINE_VISIBILITY
     value_type min() const;
+    _LIBCPP_INLINE_VISIBILITY
     value_type max() const;
 
     valarray shift (int __i) const;
@@ -1114,6 +1164,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1122,6 +1173,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator*=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1130,6 +1182,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator/=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1138,6 +1191,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator%=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1146,6 +1200,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator+=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1154,6 +1209,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator-=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1162,6 +1218,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator^=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1170,6 +1227,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator&=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1178,6 +1236,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator|=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1186,6 +1245,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator<<=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1194,10 +1254,13 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator>>=(const _Expr& __v) const;
 
+    _LIBCPP_INLINE_VISIBILITY
     const slice_array& operator=(const slice_array& __sa) const;
 
+    _LIBCPP_INLINE_VISIBILITY
     void operator=(const value_type& __x) const;
 
 private:
@@ -1213,7 +1276,7 @@
 };
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 const slice_array<_Tp>&
 slice_array<_Tp>::operator=(const slice_array& __sa) const
 {
@@ -1226,7 +1289,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1241,7 +1304,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1256,7 +1319,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1271,7 +1334,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1286,7 +1349,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1301,7 +1364,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1316,7 +1379,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1331,7 +1394,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1346,7 +1409,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1361,7 +1424,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1376,7 +1439,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1390,7 +1453,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 slice_array<_Tp>::operator=(const value_type& __x) const
 {
@@ -1484,6 +1547,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1492,6 +1556,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator*=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1500,6 +1565,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator/=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1508,6 +1574,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator%=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1516,6 +1583,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator+=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1524,6 +1592,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator-=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1532,6 +1601,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator^=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1540,6 +1610,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator&=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1548,6 +1619,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator|=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1556,6 +1628,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator<<=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1564,10 +1637,13 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator>>=(const _Expr& __v) const;
 
+    _LIBCPP_INLINE_VISIBILITY
     const gslice_array& operator=(const gslice_array& __ga) const;
 
+    _LIBCPP_INLINE_VISIBILITY
     void operator=(const value_type& __x) const;
 
 //  gslice_array(const gslice_array&)            = default;
@@ -1576,20 +1652,16 @@
 //  gslice_array& operator=(gslice_array&&)      = default;
 
 private:
-    _LIBCPP_INLINE_VISIBILITY
     gslice_array(const gslice& __gs, const valarray<value_type>& __v)
         : __vp_(const_cast<value_type*>(__v.__begin_)),
           __1d_(__gs.__1d_)
         {}
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-    _LIBCPP_INLINE_VISIBILITY
     gslice_array(gslice&& __gs, const valarray<value_type>& __v)
         : __vp_(const_cast<value_type*>(__v.__begin_)),
           __1d_(move(__gs.__1d_))
         {}
-
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
     template <class> friend class valarray;
@@ -1597,7 +1669,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1613,7 +1685,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1629,7 +1701,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1645,7 +1717,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1661,7 +1733,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1677,7 +1749,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1693,7 +1765,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1709,7 +1781,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1725,7 +1797,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1741,7 +1813,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1757,7 +1829,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1772,7 +1844,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 const gslice_array<_Tp>&
 gslice_array<_Tp>::operator=(const gslice_array& __ga) const
 {
@@ -1785,7 +1857,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 gslice_array<_Tp>::operator=(const value_type& __x) const
 {
@@ -1813,6 +1885,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1821,6 +1894,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator*=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1829,6 +1903,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator/=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1837,6 +1912,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator%=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1845,6 +1921,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator+=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1853,6 +1930,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator-=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1861,6 +1939,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator^=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1869,6 +1948,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator&=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1877,6 +1957,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator|=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1885,6 +1966,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator<<=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -1893,10 +1975,13 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator>>=(const _Expr& __v) const;
 
+    _LIBCPP_INLINE_VISIBILITY
     const mask_array& operator=(const mask_array& __ma) const;
 
+    _LIBCPP_INLINE_VISIBILITY
     void operator=(const value_type& __x) const;
 
 //  mask_array(const mask_array&)            = default;
@@ -1921,7 +2006,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1936,7 +2021,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1951,7 +2036,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1966,7 +2051,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1981,7 +2066,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -1996,7 +2081,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2011,7 +2096,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2026,7 +2111,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2041,7 +2126,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2056,7 +2141,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2071,7 +2156,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2085,7 +2170,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 const mask_array<_Tp>&
 mask_array<_Tp>::operator=(const mask_array& __ma) const
 {
@@ -2096,7 +2181,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 mask_array<_Tp>::operator=(const value_type& __x) const
 {
@@ -2158,6 +2243,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -2166,6 +2252,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator*=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -2174,6 +2261,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator/=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -2182,6 +2270,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator%=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -2190,6 +2279,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator+=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -2198,6 +2288,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator-=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -2206,6 +2297,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator^=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -2214,6 +2306,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator&=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -2222,6 +2315,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator|=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -2230,6 +2324,7 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator<<=(const _Expr& __v) const;
 
     template <class _Expr>
@@ -2238,10 +2333,13 @@
         __is_val_expr<_Expr>::value,
         void
     >::type
+    _LIBCPP_INLINE_VISIBILITY
     operator>>=(const _Expr& __v) const;
 
+    _LIBCPP_INLINE_VISIBILITY
     const indirect_array& operator=(const indirect_array& __ia) const;
 
+    _LIBCPP_INLINE_VISIBILITY
     void operator=(const value_type& __x) const;
 
 //  indirect_array(const indirect_array&)            = default;
@@ -2271,7 +2369,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2286,7 +2384,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2301,7 +2399,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2316,7 +2414,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2331,7 +2429,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2346,7 +2444,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2361,7 +2459,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2376,7 +2474,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2391,7 +2489,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2406,7 +2504,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2421,7 +2519,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -2435,7 +2533,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 const indirect_array<_Tp>&
 indirect_array<_Tp>::operator=(const indirect_array& __ia) const
 {
@@ -2448,7 +2546,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 indirect_array<_Tp>::operator=(const value_type& __x) const
 {
@@ -2650,7 +2748,7 @@
 // valarray
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>::valarray(size_t __n)
     : __begin_(0),
       __end_(0)
@@ -2659,7 +2757,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>::valarray(const value_type& __x, size_t __n)
     : __begin_(0),
       __end_(0)
@@ -2720,7 +2818,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>::valarray(valarray&& __v) _NOEXCEPT
     : __begin_(__v.__begin_),
       __end_(__v.__end_)
@@ -2874,7 +2972,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>::~valarray()
 {
     resize(0);
@@ -2896,7 +2994,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator=(valarray&& __v) _NOEXCEPT
 {
@@ -2913,7 +3011,7 @@
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator=(initializer_list<value_type> __il)
 {
@@ -2926,7 +3024,7 @@
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator=(const value_type& __x)
 {
@@ -2935,7 +3033,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator=(const slice_array<value_type>& __sa)
 {
@@ -2947,7 +3045,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator=(const gslice_array<value_type>& __ga)
 {
@@ -2961,7 +3059,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator=(const mask_array<value_type>& __ma)
 {
@@ -2975,7 +3073,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator=(const indirect_array<value_type>& __ia)
 {
@@ -2990,7 +3088,7 @@
 
 template <class _Tp>
 template <class _ValExpr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator=(const __val_expr<_ValExpr>& __v)
 {
@@ -3004,7 +3102,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __val_expr<__slice_expr<const valarray<_Tp>&> >
 valarray<_Tp>::operator[](slice __s) const
 {
@@ -3012,7 +3110,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 slice_array<_Tp>
 valarray<_Tp>::operator[](slice __s)
 {
@@ -3020,7 +3118,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __val_expr<__indirect_expr<const valarray<_Tp>&> >
 valarray<_Tp>::operator[](const gslice& __gs) const
 {
@@ -3028,7 +3126,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 gslice_array<_Tp>
 valarray<_Tp>::operator[](const gslice& __gs)
 {
@@ -3038,7 +3136,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __val_expr<__indirect_expr<const valarray<_Tp>&> >
 valarray<_Tp>::operator[](gslice&& __gs) const
 {
@@ -3046,7 +3144,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 gslice_array<_Tp>
 valarray<_Tp>::operator[](gslice&& __gs)
 {
@@ -3056,7 +3154,7 @@
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __val_expr<__mask_expr<const valarray<_Tp>&> >
 valarray<_Tp>::operator[](const valarray<bool>& __vb) const
 {
@@ -3064,7 +3162,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 mask_array<_Tp>
 valarray<_Tp>::operator[](const valarray<bool>& __vb)
 {
@@ -3074,7 +3172,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __val_expr<__mask_expr<const valarray<_Tp>&> >
 valarray<_Tp>::operator[](valarray<bool>&& __vb) const
 {
@@ -3082,7 +3180,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 mask_array<_Tp>
 valarray<_Tp>::operator[](valarray<bool>&& __vb)
 {
@@ -3092,7 +3190,7 @@
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __val_expr<__indirect_expr<const valarray<_Tp>&> >
 valarray<_Tp>::operator[](const valarray<size_t>& __vs) const
 {
@@ -3100,7 +3198,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 indirect_array<_Tp>
 valarray<_Tp>::operator[](const valarray<size_t>& __vs)
 {
@@ -3110,7 +3208,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 __val_expr<__indirect_expr<const valarray<_Tp>&> >
 valarray<_Tp>::operator[](valarray<size_t>&& __vs) const
 {
@@ -3118,7 +3216,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 indirect_array<_Tp>
 valarray<_Tp>::operator[](valarray<size_t>&& __vs)
 {
@@ -3196,7 +3294,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator*=(const value_type& __x)
 {
@@ -3206,7 +3304,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator/=(const value_type& __x)
 {
@@ -3216,7 +3314,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator%=(const value_type& __x)
 {
@@ -3226,7 +3324,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator+=(const value_type& __x)
 {
@@ -3236,7 +3334,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator-=(const value_type& __x)
 {
@@ -3246,7 +3344,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator^=(const value_type& __x)
 {
@@ -3256,7 +3354,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator&=(const value_type& __x)
 {
@@ -3266,7 +3364,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator|=(const value_type& __x)
 {
@@ -3276,7 +3374,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator<<=(const value_type& __x)
 {
@@ -3286,7 +3384,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 valarray<_Tp>&
 valarray<_Tp>::operator>>=(const value_type& __x)
 {
@@ -3297,7 +3395,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -3313,7 +3411,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -3329,7 +3427,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -3345,7 +3443,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -3361,7 +3459,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -3377,7 +3475,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -3393,7 +3491,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -3409,7 +3507,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -3425,7 +3523,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -3441,7 +3539,7 @@
 
 template <class _Tp>
 template <class _Expr>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 typename enable_if
 <
     __is_val_expr<_Expr>::value,
@@ -3456,7 +3554,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 valarray<_Tp>::swap(valarray& __v) _NOEXCEPT
 {
@@ -3465,7 +3563,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _Tp
 valarray<_Tp>::sum() const
 {
@@ -3479,7 +3577,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _Tp
 valarray<_Tp>::min() const
 {
@@ -3489,7 +3587,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 _Tp
 valarray<_Tp>::max() const
 {
diff --git a/include/vector b/include/vector
index 049d3c8..81c514e 100644
--- a/include/vector
+++ b/include/vector
@@ -51,8 +51,8 @@
     vector& operator=(const vector& x);
     vector& operator=(vector&& x)
         noexcept(
-             allocator_type::propagate_on_container_move_assignment::value &&
-             is_nothrow_move_assignable<allocator_type>::value);
+             allocator_type::propagate_on_container_move_assignment::value ||
+             allocator_type::is_always_equal::value); // C++17
     vector& operator=(initializer_list<value_type> il);
     template <class InputIterator>
         void assign(InputIterator first, InputIterator last);
@@ -175,8 +175,8 @@
     vector& operator=(const vector& x);
     vector& operator=(vector&& x)
         noexcept(
-             allocator_type::propagate_on_container_move_assignment::value &&
-             is_nothrow_move_assignable<allocator_type>::value);
+             allocator_type::propagate_on_container_move_assignment::value ||
+             allocator_type::is_always_equal::value); // C++17
     vector& operator=(initializer_list<value_type> il);
     template <class InputIterator>
         void assign(InputIterator first, InputIterator last);
@@ -262,6 +262,7 @@
 */
 
 #include <__config>
+#include <iosfwd> // for forward declaration of vector
 #include <__bit_reference>
 #include <type_traits>
 #include <climits>
@@ -453,7 +454,7 @@
     }
 }
 
-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>
 {
@@ -562,9 +563,7 @@
     vector(vector&& __x, const allocator_type& __a);
     _LIBCPP_INLINE_VISIBILITY
     vector& operator=(vector&& __x)
-        _NOEXCEPT_(
-             __alloc_traits::propagate_on_container_move_assignment::value &&
-             is_nothrow_move_assignable<allocator_type>::value);
+        _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
     _LIBCPP_INLINE_VISIBILITY
@@ -687,9 +686,11 @@
     _LIBCPP_INLINE_VISIBILITY void push_back(value_type&& __x);
 #ifndef _LIBCPP_HAS_NO_VARIADICS
     template <class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
         void emplace_back(_Args&&... __args);
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     void pop_back();
 
     iterator insert(const_iterator __position, const_reference __x);
@@ -768,6 +769,7 @@
     void deallocate() _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const;
     void __construct_at_end(size_type __n);
+    _LIBCPP_INLINE_VISIBILITY
     void __construct_at_end(size_type __n, const_reference __x);
     template <class _ForwardIterator>
         typename enable_if
@@ -787,7 +789,8 @@
     void __move_range(pointer __from_s, pointer __from_e, pointer __to);
     void __move_assign(vector& __c, true_type)
         _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
-    void __move_assign(vector& __c, false_type);
+    void __move_assign(vector& __c, false_type)
+        _NOEXCEPT_(__alloc_traits::is_always_equal::value);
     _LIBCPP_INLINE_VISIBILITY
     void __destruct_at_end(pointer __new_last) _NOEXCEPT
     {
@@ -991,7 +994,7 @@
 //  Postcondition:  size() == old size() + __n
 //  Postcondition:  [i] == __x for all i in [size() - __n, __n)
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
 {
@@ -1303,9 +1306,7 @@
 inline _LIBCPP_INLINE_VISIBILITY
 vector<_Tp, _Allocator>&
 vector<_Tp, _Allocator>::operator=(vector&& __x)
-        _NOEXCEPT_(
-             __alloc_traits::propagate_on_container_move_assignment::value &&
-             is_nothrow_move_assignable<allocator_type>::value)
+    _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
 {
     __move_assign(__x, integral_constant<bool,
           __alloc_traits::propagate_on_container_move_assignment::value>());
@@ -1315,6 +1316,7 @@
 template <class _Tp, class _Allocator>
 void
 vector<_Tp, _Allocator>::__move_assign(vector& __c, false_type)
+    _NOEXCEPT_(__alloc_traits::is_always_equal::value)
 {
     if (__base::__alloc() != __c.__alloc())
     {
@@ -1629,7 +1631,7 @@
 
 template <class _Tp, class _Allocator>
 template <class... _Args>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 vector<_Tp, _Allocator>::emplace_back(_Args&&... __args)
 {
@@ -1650,7 +1652,7 @@
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 vector<_Tp, _Allocator>::pop_back()
 {
@@ -2213,9 +2215,7 @@
     vector(vector&& __v, const allocator_type& __a);
     _LIBCPP_INLINE_VISIBILITY
     vector& operator=(vector&& __v)
-        _NOEXCEPT_(
-             __alloc_traits::propagate_on_container_move_assignment::value &&
-             is_nothrow_move_assignable<allocator_type>::value);
+        _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
     _LIBCPP_INLINE_VISIBILITY
@@ -2363,6 +2363,7 @@
         _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;
@@ -2838,9 +2839,7 @@
 inline _LIBCPP_INLINE_VISIBILITY
 vector<bool, _Allocator>&
 vector<bool, _Allocator>::operator=(vector&& __v)
-        _NOEXCEPT_(
-             __alloc_traits::propagate_on_container_move_assignment::value &&
-             is_nothrow_move_assignable<allocator_type>::value)
+    _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
 {
     __move_assign(__v, integral_constant<bool,
           __storage_traits::propagate_on_container_move_assignment::value>());
diff --git a/include/wchar.h b/include/wchar.h
new file mode 100644
index 0000000..c0c6ef7
--- /dev/null
+++ b/include/wchar.h
@@ -0,0 +1,175 @@
+// -*- C++ -*-
+//===--------------------------- wchar.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.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__need_wint_t) || defined(__need_mbstate_t)
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <wchar.h>
+
+#elif !defined(_LIBCPP_WCHAR_H)
+#define _LIBCPP_WCHAR_H
+
+/*
+    wchar.h synopsis
+
+Macros:
+
+    NULL
+    WCHAR_MAX
+    WCHAR_MIN
+    WEOF
+
+Types:
+
+    mbstate_t
+    size_t
+    tm
+    wint_t
+
+int fwprintf(FILE* restrict stream, const wchar_t* restrict format, ...);
+int fwscanf(FILE* restrict stream, const wchar_t* restrict format, ...);
+int swprintf(wchar_t* restrict s, size_t n, const wchar_t* restrict format, ...);
+int swscanf(const wchar_t* restrict s, const wchar_t* restrict format, ...);
+int vfwprintf(FILE* restrict stream, const wchar_t* restrict format, va_list arg);
+int vfwscanf(FILE* restrict stream, const wchar_t* restrict format, va_list arg);  // C99
+int vswprintf(wchar_t* restrict s, size_t n, const wchar_t* restrict format, va_list arg);
+int vswscanf(const wchar_t* restrict s, const wchar_t* restrict format, va_list arg);  // C99
+int vwprintf(const wchar_t* restrict format, va_list arg);
+int vwscanf(const wchar_t* restrict format, va_list arg);  // C99
+int wprintf(const wchar_t* restrict format, ...);
+int wscanf(const wchar_t* restrict format, ...);
+wint_t fgetwc(FILE* stream);
+wchar_t* fgetws(wchar_t* restrict s, int n, FILE* restrict stream);
+wint_t fputwc(wchar_t c, FILE* stream);
+int fputws(const wchar_t* restrict s, FILE* restrict stream);
+int fwide(FILE* stream, int mode);
+wint_t getwc(FILE* stream);
+wint_t getwchar();
+wint_t putwc(wchar_t c, FILE* stream);
+wint_t putwchar(wchar_t c);
+wint_t ungetwc(wint_t c, FILE* stream);
+double wcstod(const wchar_t* restrict nptr, wchar_t** restrict endptr);
+float wcstof(const wchar_t* restrict nptr, wchar_t** restrict endptr);         // C99
+long double wcstold(const wchar_t* restrict nptr, wchar_t** restrict endptr);  // C99
+long wcstol(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);
+long long wcstoll(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);  // C99
+unsigned long wcstoul(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);
+unsigned long long wcstoull(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);  // C99
+wchar_t* wcscpy(wchar_t* restrict s1, const wchar_t* restrict s2);
+wchar_t* wcsncpy(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+wchar_t* wcscat(wchar_t* restrict s1, const wchar_t* restrict s2);
+wchar_t* wcsncat(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+int wcscmp(const wchar_t* s1, const wchar_t* s2);
+int wcscoll(const wchar_t* s1, const wchar_t* s2);
+int wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n);
+size_t wcsxfrm(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+const wchar_t* wcschr(const wchar_t* s, wchar_t c);
+      wchar_t* wcschr(      wchar_t* s, wchar_t c);
+size_t wcscspn(const wchar_t* s1, const wchar_t* s2);
+size_t wcslen(const wchar_t* s);
+const wchar_t* wcspbrk(const wchar_t* s1, const wchar_t* s2);
+      wchar_t* wcspbrk(      wchar_t* s1, const wchar_t* s2);
+const wchar_t* wcsrchr(const wchar_t* s, wchar_t c);
+      wchar_t* wcsrchr(      wchar_t* s, wchar_t c);
+size_t wcsspn(const wchar_t* s1, const wchar_t* s2);
+const wchar_t* wcsstr(const wchar_t* s1, const wchar_t* s2);
+      wchar_t* wcsstr(      wchar_t* s1, const wchar_t* s2);
+wchar_t* wcstok(wchar_t* restrict s1, const wchar_t* restrict s2, wchar_t** restrict ptr);
+const wchar_t* wmemchr(const wchar_t* s, wchar_t c, size_t n);
+      wchar_t* wmemchr(      wchar_t* s, wchar_t c, size_t n);
+int wmemcmp(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+wchar_t* wmemcpy(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+wchar_t* wmemmove(wchar_t* s1, const wchar_t* s2, size_t n);
+wchar_t* wmemset(wchar_t* s, wchar_t c, size_t n);
+size_t wcsftime(wchar_t* restrict s, size_t maxsize, const wchar_t* restrict format,
+                const tm* restrict timeptr);
+wint_t btowc(int c);
+int wctob(wint_t c);
+int mbsinit(const mbstate_t* ps);
+size_t mbrlen(const char* restrict s, size_t n, mbstate_t* restrict ps);
+size_t mbrtowc(wchar_t* restrict pwc, const char* restrict s, size_t n, mbstate_t* restrict ps);
+size_t wcrtomb(char* restrict s, wchar_t wc, mbstate_t* restrict ps);
+size_t mbsrtowcs(wchar_t* restrict dst, const char** restrict src, size_t len,
+                 mbstate_t* restrict ps);
+size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
+                 mbstate_t* restrict ps);
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+#define __CORRECT_ISO_CPP_WCHAR_H_PROTO
+#endif
+
+#include_next <wchar.h>
+
+// 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)
+#  if __GLIBC_PREREQ(2, 10)
+#    define _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS 1
+#  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
+}  // extern "C++"
+#endif  // __cplusplus && _LIBCPP_MSVCRT
+
+#endif  // _LIBCPP_WCHAR_H
diff --git a/include/wctype.h b/include/wctype.h
new file mode 100644
index 0000000..f9c5a47
--- /dev/null
+++ b/include/wctype.h
@@ -0,0 +1,79 @@
+// -*- C++ -*-
+//===--------------------------- wctype.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_WCTYPE_H
+#define _LIBCPP_WCTYPE_H
+
+/*
+    wctype.h synopsis
+
+Macros:
+
+    WEOF
+
+Types:
+
+    wint_t
+    wctrans_t
+    wctype_t
+
+int iswalnum(wint_t wc);
+int iswalpha(wint_t wc);
+int iswblank(wint_t wc);  // C99
+int iswcntrl(wint_t wc);
+int iswdigit(wint_t wc);
+int iswgraph(wint_t wc);
+int iswlower(wint_t wc);
+int iswprint(wint_t wc);
+int iswpunct(wint_t wc);
+int iswspace(wint_t wc);
+int iswupper(wint_t wc);
+int iswxdigit(wint_t wc);
+int iswctype(wint_t wc, wctype_t desc);
+wctype_t wctype(const char* property);
+wint_t towlower(wint_t wc);
+wint_t towupper(wint_t wc);
+wint_t towctrans(wint_t wc, wctrans_t desc);
+wctrans_t wctrans(const char* property);
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <wctype.h>
+
+#ifdef __cplusplus
+
+#undef iswalnum
+#undef iswalpha
+#undef iswblank
+#undef iswcntrl
+#undef iswdigit
+#undef iswgraph
+#undef iswlower
+#undef iswprint
+#undef iswpunct
+#undef iswspace
+#undef iswupper
+#undef iswxdigit
+#undef iswctype
+#undef wctype
+#undef towlower
+#undef towupper
+#undef towctrans
+#undef wctrans
+
+#endif  // __cplusplus
+
+#endif  // _LIBCPP_WCTYPE_H
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 26dee67..05127bd 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -11,7 +11,7 @@
 endif()
 
 # Add all the headers to the project for IDEs.
-if (MSVC_IDE OR XCODE)
+if (LIBCXX_CONFIGURE_IDE)
   file(GLOB_RECURSE LIBCXX_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/*)
   if(WIN32)
     file( GLOB LIBCXX_WIN32_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/support/win32/*.h)
@@ -24,10 +24,14 @@
   endif()
 endif()
 
+if(NOT LIBCXX_INSTALL_LIBRARY)
+  set(exclude_from_all EXCLUDE_FROM_ALL)
+endif()
+
 if (LIBCXX_ENABLE_SHARED)
-  add_library(cxx SHARED ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
+  add_library(cxx SHARED ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
 else()
-  add_library(cxx STATIC ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
+  add_library(cxx STATIC ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
 endif()
 
 if (DEFINED LIBCXX_CXX_ABI_DEPS)
@@ -75,6 +79,7 @@
 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_HAS_ATOMIC_LIB atomic)
 
 # Setup flags.
 add_flags_if_supported(-fPIC)
@@ -107,7 +112,7 @@
           "-Wl,-reexport_library,${CMAKE_OSX_SYSROOT}/usr/lib/libc++abi.dylib")
       endif()
     else()
-      set (OSX_RE_EXPORT_LINE "/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++abi${LIBCXX_LIBCPPABI_VERSION}.exp")
+      set(OSX_RE_EXPORT_LINE "/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++abi${LIBCXX_LIBCPPABI_VERSION}.exp")
     endif()
 
     add_link_flags(
@@ -129,11 +134,83 @@
     COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
     LINK_FLAGS    "${LIBCXX_LINK_FLAGS}"
     OUTPUT_NAME   "c++"
-    VERSION       "1.0"
-    SOVERSION     "1"
+    VERSION       "${LIBCXX_ABI_VERSION}.0"
+    SOVERSION     "${LIBCXX_ABI_VERSION}"
   )
 
-install(TARGETS cxx
-  LIBRARY DESTINATION lib${LIBCXX_LIBDIR_SUFFIX}
-  ARCHIVE DESTINATION lib${LIBCXX_LIBDIR_SUFFIX}
+if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
+  file(GLOB LIBCXX_EXPERIMENTAL_SOURCES ../src/experimental/*.cpp)
+  add_library(cxx_experimental STATIC ${LIBCXX_EXPERIMENTAL_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)
+  # Get the name of the ABI library and handle the case where CXXABI_LIBNAME
+  # is a target name and not a library. Ex cxxabi_shared.
+  set(SCRIPT_ABI_LIBNAME "${LIBCXX_CXX_ABI_LIBRARY}")
+  if (SCRIPT_ABI_LIBNAME STREQUAL "cxxabi_shared")
+    set(SCRIPT_ABI_LIBNAME "c++abi")
+  endif()
+  # Generate a linker script inplace of a libc++.so symlink. Rerun this command
+  # after cxx builds.
+  add_custom_command(TARGET cxx POST_BUILD
+    COMMAND
+      ${PYTHON_EXECUTABLE} ${LIBCXX_SOURCE_DIR}/utils/gen_link_script/gen_link_script.py
+    ARGS
+      "$<TARGET_LINKER_FILE:cxx>"
+      "${SCRIPT_ABI_LIBNAME}"
+    WORKING_DIRECTORY ${LIBCXX_BUILD_DIR}
+  )
+endif()
+
+if (LIBCXX_INSTALL_LIBRARY)
+  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
+    )
+  # NOTE: This install command must go after the cxx install command otherwise
+  # it will not be executed after the library symlinks are installed.
+  if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
+    # Replace the libc++ filename with $<TARGET_LINKER_FILE:cxx>
+    # after we required CMake 3.0.
+    install(FILES "${LIBCXX_LIBRARY_DIR}/libc++${CMAKE_SHARED_LIBRARY_SUFFIX}"
+      DESTINATION lib${LIBCXX_LIBDIR_SUFFIX}
+      COMPONENT libcxx)
+  endif()
+endif()
+
+if (NOT CMAKE_CONFIGURATION_TYPES AND (LIBCXX_INSTALL_LIBRARY OR
+                                       LIBCXX_INSTALL_HEADERS))
+    if(LIBCXX_INSTALL_LIBRARY)
+      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
+                      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")
+endif()
diff --git a/lib/buildit b/lib/buildit
index 7e3bc2e..6451a9b 100755
--- a/lib/buildit
+++ b/lib/buildit
@@ -41,7 +41,7 @@
 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/lib/libc++abi2.exp b/lib/libc++abi2.exp
index bdfe99c..47dcbbb 100644
--- a/lib/libc++abi2.exp
+++ b/lib/libc++abi2.exp
@@ -290,6 +290,16 @@
 __ZTSSt16invalid_argument
 __ZTVSt16invalid_argument
 
+__ZNKSt16bad_array_length4whatEv
+__ZNSt16bad_array_lengthC1Ev
+__ZNSt16bad_array_lengthC2Ev
+__ZNSt16bad_array_lengthD0Ev
+__ZNSt16bad_array_lengthD1Ev
+__ZNSt16bad_array_lengthD2Ev
+__ZTISt16bad_array_length
+__ZTSSt16bad_array_length
+__ZTVSt16bad_array_length
+
 __ZTSDi
 __ZTSDn
 __ZTSDs
diff --git a/src/algorithm.cpp b/src/algorithm.cpp
index de185c2..0840323 100644
--- a/src/algorithm.cpp
+++ b/src/algorithm.cpp
@@ -50,14 +50,14 @@
 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;
 }
@@ -71,7 +71,7 @@
 {
 #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/any.cpp b/src/any.cpp
index 8c3e977..f776845 100644
--- a/src/any.cpp
+++ b/src/any.cpp
@@ -11,10 +11,6 @@
 
 _LIBCPP_BEGIN_NAMESPACE_LFTS
 
-// TODO(EricWF) Enable or delete these
-//bad_any_cast::bad_any_cast() _NOEXCEPT {}
-//bad_any_cast::~bad_any_cast() _NOEXCEPT {}
-
 const char* bad_any_cast::what() const _NOEXCEPT {
     return "bad any cast";
 }
diff --git a/src/condition_variable.cpp b/src/condition_variable.cpp
index 5fd5fc8..bfb4bf3 100644
--- a/src/condition_variable.cpp
+++ b/src/condition_variable.cpp
@@ -20,19 +20,19 @@
 
 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 @@
     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 @@
         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/exception.cpp b/src/exception.cpp
index 2c16060..e172f64 100644
--- a/src/exception.cpp
+++ b/src/exception.cpp
@@ -12,10 +12,6 @@
 #include "exception"
 #include "new"
 
-#ifndef __has_include
-#define __has_include(inc) 0
-#endif
-
 #if defined(__APPLE__) && !defined(LIBCXXRT)
   #include <cxxabi.h>
 
@@ -29,16 +25,16 @@
     #define __terminate_handler  __cxxabiapple::__cxa_terminate_handler
     #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
   #endif  // _LIBCPPABI_VERSION
-#elif defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI) || __has_include(<cxxabi.h>)
+#elif defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI)
   #include <cxxabi.h>
   using namespace __cxxabiv1;
   #if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION)
     #define HAVE_DEPENDENT_EH_ABI 1
   #endif
-#elif !defined(__GLIBCXX__) // __has_include(<cxxabi.h>)
+#elif !defined(__GLIBCXX__) // defined(LIBCXX_BUILDING_LIBCXXABI)
   static std::terminate_handler  __terminate_handler;
   static std::unexpected_handler __unexpected_handler;
-#endif // __has_include(<cxxabi.h>)
+#endif // defined(LIBCXX_BUILDING_LIBCXXABI)
 
 namespace std
 {
diff --git a/src/experimental/memory_resource.cpp b/src/experimental/memory_resource.cpp
new file mode 100644
index 0000000..ff0fbb6
--- /dev/null
+++ b/src/experimental/memory_resource.cpp
@@ -0,0 +1,139 @@
+//===------------------------ 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; }
+};
+
+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)));
+
+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/future.cpp b/src/future.cpp
index 3132b18..e1758f3 100644
--- a/src/future.cpp
+++ b/src/future.cpp
@@ -221,10 +221,12 @@
 {
     if (__state_)
     {
+#ifndef _LIBCPP_NO_EXCEPTIONS
         if (!__state_->__has_value() && __state_->use_count() > 1)
             __state_->set_exception(make_exception_ptr(
                       future_error(make_error_code(future_errc::broken_promise))
                                                       ));
+#endif // _LIBCPP_NO_EXCEPTIONS
         __state_->__release_shared();
     }
 }
diff --git a/src/support/atomic_support.h b/src/include/atomic_support.h
similarity index 88%
rename from src/support/atomic_support.h
rename to src/include/atomic_support.h
index e738a51..8b719c5 100644
--- a/src/support/atomic_support.h
+++ b/src/include/atomic_support.h
@@ -1,3 +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.
+//
+//===----------------------------------------------------------------------===////
+
 #ifndef ATOMIC_SUPPORT_H
 #define ATOMIC_SUPPORT_H
 
@@ -103,6 +112,13 @@
     *__dest = __val;
 }
 
+template <class _ValueType, class _FromType>
+inline _LIBCPP_INLINE_VISIBILITY
+void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val)
+{
+    *__dest = __val;
+}
+
 template <class _ValueType>
 inline _LIBCPP_INLINE_VISIBILITY
 _ValueType __libcpp_atomic_load(_ValueType const* __val,
diff --git a/src/config_elast.h b/src/include/config_elast.h
similarity index 100%
rename from src/config_elast.h
rename to src/include/config_elast.h
diff --git a/src/ios.cpp b/src/ios.cpp
index e2e0363..6364eec 100644
--- a/src/ios.cpp
+++ b/src/ios.cpp
@@ -18,7 +18,7 @@
 
 #include "__locale"
 #include "algorithm"
-#include "config_elast.h"
+#include "include/config_elast.h"
 #include "istream"
 #include "limits"
 #include "memory"
@@ -155,7 +155,7 @@
 }
 
 // xalloc
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
 atomic<int> ios_base::__xindex_ = ATOMIC_VAR_INIT(0);
 #else
 int ios_base::__xindex_ = 0;
diff --git a/src/locale.cpp b/src/locale.cpp
index d2450e7..5c526cb 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -126,11 +126,6 @@
 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
 {
@@ -166,10 +161,6 @@
     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),
@@ -815,7 +806,8 @@
 {
 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
     return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
-#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
+#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
+      defined(__NetBSD__)
     return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
 #else
     return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
@@ -828,7 +820,8 @@
     for (; low != high; ++low)
 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
         *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
-#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
+#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
+      defined(__NetBSD__)
         *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
                              : *low;
 #else
@@ -842,7 +835,8 @@
 {
 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
     return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
-#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
+#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
+      defined(__NetBSD__)
     return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
 #else
     return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
@@ -855,7 +849,8 @@
     for (; low != high; ++low)
 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
         *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
-#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
+#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
+      defined(__NetBSD__)
         *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
                              : *low;
 #else
@@ -925,7 +920,7 @@
 #elif defined(__NetBSD__)
     return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
-    return isascii(c) ? 
+    return isascii(c) ?
       static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
 #else
     return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
@@ -958,7 +953,7 @@
       static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
 #elif defined(__NetBSD__)
     return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
-#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
+#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
     return isascii(c) ?
       static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
 #else
@@ -1015,7 +1010,7 @@
     return low;
 }
 
-#ifdef __EMSCRIPTEN__
+#if defined(__EMSCRIPTEN__)
 extern "C" const unsigned short ** __ctype_b_loc();
 extern "C" const int ** __ctype_tolower_loc();
 extern "C" const int ** __ctype_toupper_loc();
@@ -1172,7 +1167,7 @@
 {
     return *__ctype_toupper_loc();
 }
-#endif // __GLIBC__ || __EMSCRIPTEN__ || __NETBSD__
+#endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__
 
 // template <> class ctype_byname<char>
 
@@ -1408,33 +1403,21 @@
 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;
 }
 
@@ -1443,11 +1426,7 @@
 {
     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;
@@ -1557,22 +1536,14 @@
     {
         // 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;
@@ -1589,11 +1560,7 @@
         {
             // 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?
@@ -1626,23 +1593,15 @@
     {
         // 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:
@@ -1670,11 +1629,7 @@
         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;
@@ -1694,11 +1649,7 @@
 {
     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,20 +1664,12 @@
 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;
 }
@@ -1744,11 +1687,7 @@
     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:
@@ -1770,11 +1709,7 @@
 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
@@ -2893,10 +2828,10 @@
     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)
     {
@@ -4332,11 +4267,7 @@
             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)
@@ -4375,11 +4306,7 @@
             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)
@@ -4980,11 +4907,7 @@
     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;
@@ -5164,11 +5087,7 @@
         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;
@@ -5176,11 +5095,7 @@
         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;
@@ -5193,11 +5108,7 @@
         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;
@@ -5205,11 +5116,7 @@
         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;
@@ -5220,11 +5127,7 @@
     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;
@@ -5233,11 +5136,7 @@
     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;
@@ -5512,11 +5411,7 @@
     __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;
@@ -5907,11 +5802,7 @@
         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
@@ -5955,11 +5846,7 @@
         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
@@ -6020,11 +5907,7 @@
         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
@@ -6037,11 +5920,7 @@
     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;
@@ -6056,11 +5935,7 @@
     {
         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;
@@ -6072,11 +5947,7 @@
     {
         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;
@@ -6103,11 +5974,7 @@
         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
@@ -6120,11 +5987,7 @@
     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;
@@ -6143,11 +6006,7 @@
     {
         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;
@@ -6163,11 +6022,7 @@
     {
         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 66fb143..08f2259 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -13,7 +13,7 @@
 #include "mutex"
 #include "thread"
 #endif
-#include "support/atomic_support.h"
+#include "include/atomic_support.h"
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -124,15 +124,15 @@
 
 #endif  // _LIBCPP_NO_RTTI
 
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
 
 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 @@
     return muts[hash<const void*>()(p) & (__sp_mut_count-1)];
 }
 
-#endif // __has_feature(cxx_atomic) && !_LIBCPP_HAS_NO_THREADS
+#endif // defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
 
 void
 declare_reachable(void*)
diff --git a/src/mutex.cpp b/src/mutex.cpp
index 5f8ba0a..9f808ca 100644
--- a/src/mutex.cpp
+++ b/src/mutex.cpp
@@ -12,7 +12,7 @@
 #include "limits"
 #include "system_error"
 #include "cassert"
-#include "support/atomic_support.h"
+#include "include/atomic_support.h"
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 #ifndef _LIBCPP_HAS_NO_THREADS
@@ -23,13 +23,13 @@
 
 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 @@
 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 @@
 
 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 @@
 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 @@
 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 @@
 bool
 recursive_mutex::try_lock() _NOEXCEPT
 {
-    return pthread_mutex_trylock(&__m_) == 0;
+    return __libcpp_mutex_trylock(&__m_) == 0;
 }
 
 // timed_mutex
@@ -165,9 +143,9 @@
 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 @@
 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 @@
 // 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 @@
 #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 @@
         {
 #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/new.cpp b/src/new.cpp
index c28fcb5..f4f73d8 100644
--- a/src/new.cpp
+++ b/src/new.cpp
@@ -13,10 +13,6 @@
 
 #include "new"
 
-#ifndef __has_include
-#define __has_include(inc) 0
-#endif
-
 #if defined(__APPLE__) && !defined(LIBCXXRT)
     #include <cxxabi.h>
 
@@ -27,9 +23,9 @@
         #define __new_handler __cxxabiapple::__cxa_new_handler
     #endif
 #else  // __APPLE__
-    #if defined(LIBCXXRT) || __has_include(<cxxabi.h>)
+    #if defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI)
         #include <cxxabi.h>
-    #endif  // __has_include(<cxxabi.h>)
+    #endif  // defined(LIBCXX_BUILDING_LIBCXXABI)
     #if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
         static std::new_handler __new_handler;
     #endif  // _LIBCPPABI_VERSION
@@ -38,7 +34,7 @@
 #ifndef __GLIBCXX__
 
 // Implement all new and delete operators as weak definitions
-// in this shared library, so that they can be overriden by programs
+// in this shared library, so that they can be overridden by programs
 // that define non-weak copies of the functions.
 
 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
diff --git a/src/regex.cpp b/src/regex.cpp
index 17dd6ea..a736359 100644
--- a/src/regex.cpp
+++ b/src/regex.cpp
@@ -69,21 +69,12 @@
 
 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 @@
     {"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/stdexcept.cpp b/src/stdexcept.cpp
index aff4b18..0a08bfe 100644
--- a/src/stdexcept.cpp
+++ b/src/stdexcept.cpp
@@ -13,12 +13,8 @@
 #include "string"
 #include "system_error"
 
-#ifndef __has_include
-#define __has_include(inc) 0
-#endif
-
 /* For _LIBCPPABI_VERSION */
-#if __has_include(<cxxabi.h>) || defined(__APPLE_) || defined(LIBCXXRT)
+#if defined(LIBCXX_BUILDING_LIBCXXABI) || defined(__APPLE__) || defined(LIBCXXRT)
 #include <cxxabi.h>
 #endif
 
diff --git a/src/system_error.cpp b/src/system_error.cpp
index 18f668f..3023e20 100644
--- a/src/system_error.cpp
+++ b/src/system_error.cpp
@@ -12,7 +12,7 @@
 #define _LIBCPP_BUILDING_SYSTEM_ERROR
 #include "system_error"
 
-#include "config_elast.h"
+#include "include/config_elast.h"
 #include "cstring"
 #include "string"
 
diff --git a/src/thread.cpp b/src/thread.cpp
index bd27f28..406e71d 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,7 +46,7 @@
 void
 thread::join()
 {
-    int ec = pthread_join(__t_, 0);
+    int ec = __libcpp_thread_join(&__t_);
 #ifndef _LIBCPP_NO_EXCEPTIONS
     if (ec)
         throw system_error(error_code(ec, system_category()), "thread::join failed");
@@ -57,7 +62,7 @@
     int ec = EINVAL;
     if (__t_ != 0)
     {
-        ec = pthread_detach(__t_);
+        ec = __libcpp_thread_detach(&__t_);
         if (ec == 0)
             __t_ = 0;
     }
diff --git a/src/typeinfo.cpp b/src/typeinfo.cpp
index b428120..5c0a609 100644
--- a/src/typeinfo.cpp
+++ b/src/typeinfo.cpp
@@ -8,13 +8,8 @@
 //===----------------------------------------------------------------------===//
 #include <stdlib.h>
 
-#ifndef __has_include
-#define __has_include(inc) 0
-#endif
-
-#ifdef __APPLE__
-#include <cxxabi.h>
-#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>)
+#if defined(__APPLE__) || defined(LIBCXXRT) ||                                 \
+    defined(LIBCXX_BUILDING_LIBCXXABI)
 #include <cxxabi.h>
 #endif
 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 60dd7c2..2d1cdb2 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -10,23 +10,28 @@
     "Configuration variant to use for LIT.")
 
 pythonize_bool(LIBCXX_ENABLE_EXCEPTIONS)
+pythonize_bool(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
 pythonize_bool(LIBCXX_ENABLE_RTTI)
 pythonize_bool(LIBCXX_ENABLE_SHARED)
 pythonize_bool(LIBCXX_BUILD_32_BITS)
-pythonize_bool(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE)
-pythonize_bool(LIBCXX_ENABLE_STDIN)
-pythonize_bool(LIBCXX_ENABLE_STDOUT)
-pythonize_bool(LIBCXX_ENABLE_THREADS)
-pythonize_bool(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS)
-pythonize_bool(LIBCXX_ENABLE_MONOTONIC_CLOCK)
 pythonize_bool(LIBCXX_GENERATE_COVERAGE)
+pythonize_bool(LIBCXXABI_ENABLE_SHARED)
 pythonize_bool(LIBCXXABI_USE_LLVM_UNWINDER)
+pythonize_bool(LIBCXX_HAS_ATOMIC_LIB)
 
 # The tests shouldn't link to any ABI library when it has been linked into
-# libc++ statically.
-if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY)
+# libc++ statically or via a linker script.
+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
@@ -39,15 +44,19 @@
   ${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/libcxx/atomics/atomics.flag/init_bool.pass.cpp b/test/libcxx/atomics/atomics.flag/init_bool.pass.cpp
new file mode 100644
index 0000000..d7b172c
--- /dev/null
+++ b/test/libcxx/atomics/atomics.flag/init_bool.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: libcpp-has-no-threads
+
+// <atomic>
+
+// struct atomic_flag
+
+// TESTING EXTENSION atomic_flag(bool)
+
+#include <atomic>
+#include <cassert>
+
+int main()
+{
+    {
+        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/libcpp-has-no-threads.fail.cpp b/test/libcxx/atomics/libcpp-has-no-threads.fail.cpp
similarity index 100%
rename from test/std/atomics/libcpp-has-no-threads.fail.cpp
rename to test/libcxx/atomics/libcpp-has-no-threads.fail.cpp
diff --git a/test/std/atomics/libcpp-has-no-threads.pass.cpp b/test/libcxx/atomics/libcpp-has-no-threads.pass.cpp
similarity index 86%
rename from test/std/atomics/libcpp-has-no-threads.pass.cpp
rename to test/libcxx/atomics/libcpp-has-no-threads.pass.cpp
index 9c0cccb..e587e6b 100644
--- a/test/std/atomics/libcpp-has-no-threads.pass.cpp
+++ b/test/libcxx/atomics/libcpp-has-no-threads.pass.cpp
@@ -10,7 +10,7 @@
 
 #ifdef _LIBCPP_HAS_NO_THREADS
 #error This should be XFAIL'd for the purpose of detecting that the LIT feature\
- 'libcpp-has-no-threads' is available iff _LIBCPP_HAS_NO_THREADS is defined
+   'libcpp-has-no-threads' is available iff _LIBCPP_HAS_NO_THREADS is defined
 #endif
 
 int main()
diff --git a/test/libcxx/compiler.py b/test/libcxx/compiler.py
index 24ac431..7dfb13a 100644
--- a/test/libcxx/compiler.py
+++ b/test/libcxx/compiler.py
@@ -1,3 +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.
+#
+#===----------------------------------------------------------------------===##
+
 import os
 import lit.util
 import libcxx.util
@@ -161,3 +170,28 @@
             return True
         else:
             return False
+
+    def addWarningFlagIfSupported(self, flag):
+        """
+        addWarningFlagIfSupported - Add a warning flag if the compiler
+        supports it. Unlike addCompileFlagIfSupported, this function detects
+        when "-Wno-<warning>" flags are unsupported. If flag is a
+        "-Wno-<warning>" GCC will not emit an unknown option diagnostic unless
+        another error is triggered during compilation.
+        """
+        assert isinstance(flag, str)
+        if not flag.startswith('-Wno-'):
+            return self.addCompileFlagIfSupported(flag)
+        flags = ['-Werror', flag]
+        cmd = self.compileCmd('-', os.devnull, flags)
+        # Remove '-v' because it will cause the command line invocation
+        # to be printed as part of the error output.
+        # TODO(EricWF): Are there other flags we need to worry about?
+        if '-v' in cmd:
+            cmd.remove('-v')
+        out, err, rc = lit.util.executeCommand(cmd, input='#error\n')
+        assert rc != 0
+        if flag in err:
+            return False
+        self.compile_flags += [flag]
+        return True
diff --git a/test/std/containers/associative/tree_balance_after_insert.pass.cpp b/test/libcxx/containers/associative/tree_balance_after_insert.pass.cpp
similarity index 100%
rename from test/std/containers/associative/tree_balance_after_insert.pass.cpp
rename to test/libcxx/containers/associative/tree_balance_after_insert.pass.cpp
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 0000000..0befd74
--- /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
similarity index 100%
rename from test/std/containers/associative/tree_left_rotate.pass.cpp
rename to test/libcxx/containers/associative/tree_left_rotate.pass.cpp
diff --git a/test/std/containers/associative/tree_remove.pass.cpp b/test/libcxx/containers/associative/tree_remove.pass.cpp
similarity index 100%
rename from test/std/containers/associative/tree_remove.pass.cpp
rename to test/libcxx/containers/associative/tree_remove.pass.cpp
diff --git a/test/std/containers/associative/tree_right_rotate.pass.cpp b/test/libcxx/containers/associative/tree_right_rotate.pass.cpp
similarity index 100%
rename from test/std/containers/associative/tree_right_rotate.pass.cpp
rename to test/libcxx/containers/associative/tree_right_rotate.pass.cpp
diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/libcxx/containers/gnu_cxx/hash_map.pass.cpp
similarity index 63%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/libcxx/containers/gnu_cxx/hash_map.pass.cpp
index e16e439..52433d2 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/libcxx/containers/gnu_cxx/hash_map.pass.cpp
@@ -7,16 +7,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+#include <ext/hash_map>
 
-// vector<const int> v;  // an extension
+namespace __gnu_cxx {
+template class hash_map<int, int>;
+}
 
-#include <vector>
-#include <type_traits>
-
-int main()
-{
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+int main() {
+  typedef __gnu_cxx::hash_map<int, int> Map;
+  Map m;
+  Map m2(m);
+  ((void)m2);
 }
diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/libcxx/containers/gnu_cxx/hash_set.pass.cpp
similarity index 63%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/libcxx/containers/gnu_cxx/hash_set.pass.cpp
index e16e439..dc127e9 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/libcxx/containers/gnu_cxx/hash_set.pass.cpp
@@ -7,16 +7,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+#include <ext/hash_set>
 
-// vector<const int> v;  // an extension
+namespace __gnu_cxx {
+template class hash_set<int>;
+}
 
-#include <vector>
-#include <type_traits>
-
-int main()
-{
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+int main() {
+  typedef __gnu_cxx::hash_set<int> Set;
+  Set s;
+  Set s2(s);
+  ((void)s2);
 }
diff --git a/test/libcxx/containers/sequences/deque/incomplete.pass.cpp b/test/libcxx/containers/sequences/deque/incomplete.pass.cpp
new file mode 100644
index 0000000..dbeea5f
--- /dev/null
+++ b/test/libcxx/containers/sequences/deque/incomplete.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// deque()
+// deque::iterator()
+
+#define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
+#include <deque>
+#include <cassert>
+
+struct A {
+  std::deque<A> d;
+  std::deque<A>::iterator it;
+  std::deque<A>::reverse_iterator it2;
+};
+
+int main()
+{
+  A a;
+  assert(a.d.size() == 0);
+  a.it = a.d.begin();
+  a.it2 = a.d.rend();
+}
diff --git a/test/std/containers/sequences/list/list.special/db_swap_1.pass.cpp b/test/libcxx/containers/sequences/list/list.special/db_swap_1.pass.cpp
similarity index 100%
rename from test/std/containers/sequences/list/list.special/db_swap_1.pass.cpp
rename to test/libcxx/containers/sequences/list/list.special/db_swap_1.pass.cpp
diff --git a/test/libcxx/containers/sequences/vector/asan.pass.cpp b/test/libcxx/containers/sequences/vector/asan.pass.cpp
index 0a11147..b102fc0 100644
--- a/test/libcxx/containers/sequences/vector/asan.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/asan.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5
+
 // <vector>
 
 // reference operator[](size_type n);
@@ -21,8 +23,11 @@
 #include "test_macros.h"
 
 #ifndef _LIBCPP_HAS_NO_ASAN
-extern "C" void __asan_set_error_exit_code(int);
+extern "C" void __sanitizer_set_death_callback(void (*callback)(void));
 
+void do_exit() {
+  exit(0);
+}
 
 int main()
 {
@@ -48,7 +53,7 @@
         assert(is_contiguous_container_asan_correct(v));
     }
 
-    __asan_set_error_exit_code(0);
+    __sanitizer_set_death_callback(do_exit);
     {
         typedef int T;
         typedef std::vector<T> C;
diff --git a/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp b/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp
index c100da1..9af3f6b 100644
--- a/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // Test asan vector annotations with a class that throws in a CTOR.
 
 #include <vector>
diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/libcxx/containers/sequences/vector/const_value_type.pass.cpp
similarity index 90%
rename from test/std/containers/sequences/vector/const_value_type.pass.cpp
rename to test/libcxx/containers/sequences/vector/const_value_type.pass.cpp
index e16e439..2a150f7 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
similarity index 100%
rename from test/std/containers/sequences/vector/db_back.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/sequences/vector/db_cback.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/sequences/vector/db_cfront.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/sequences/vector/db_cindex.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/sequences/vector/db_front.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/sequences/vector/db_index.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/sequences/vector/db_iterators_2.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/sequences/vector/db_iterators_3.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/sequences/vector/db_iterators_4.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/sequences/vector/db_iterators_5.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/sequences/vector/db_iterators_6.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/sequences/vector/db_iterators_7.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/sequences/vector/db_iterators_8.pass.cpp
rename to test/libcxx/containers/sequences/vector/db_iterators_8.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 0000000..a6d1ea7
--- /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
similarity index 100%
rename from test/std/containers/unord/next_prime.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/unord/unord.map/db_iterators_7.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/unord/unord.map/db_iterators_8.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/unord/unord.map/db_local_iterators_7.pass.cpp
rename to 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
similarity index 100%
rename from test/std/containers/unord/unord.map/db_local_iterators_8.pass.cpp
rename to test/libcxx/containers/unord/unord.map/db_local_iterators_8.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 76ceafe..0000000
--- 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/libcxx/depr/depr.c.headers/extern_c.pass.cpp b/test/libcxx/depr/depr.c.headers/extern_c.pass.cpp
new file mode 100644
index 0000000..d4d8b5f
--- /dev/null
+++ b/test/libcxx/depr/depr.c.headers/extern_c.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.
+//
+//===----------------------------------------------------------------------===//
+
+// Sometimes C++'s <foo.h> headers get included within extern "C" contexts. This
+// is ill-formed (no diagnostic required), per [using.headers]p3, but we permit
+// it as an extension.
+
+extern "C" {
+#include <assert.h>
+// complex.h is not supported in extern "C".
+#include <ctype.h>
+#include <errno.h>
+#include <fenv.h>
+#include <float.h>
+#include <inttypes.h>
+#include <iso646.h>
+#include <limits.h>
+#include <locale.h>
+#include <math.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdalign.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+// tgmath.h is not supported in extern "C".
+#include <time.h>
+// FIXME: #include <uchar.h>
+#include <wchar.h>
+#include <wctype.h>
+}
+
+int main() {}
diff --git a/test/libcxx/double_include.sh.cpp b/test/libcxx/double_include.sh.cpp
index 5620e5b..99767cf 100644
--- a/test/libcxx/double_include.sh.cpp
+++ b/test/libcxx/double_include.sh.cpp
@@ -15,6 +15,12 @@
 // RUN: %cxx -o %t.exe %t.first.o %t.second.o %flags %link_flags
 // RUN: %run
 
+
+// Prevent <ext/hash_map> from generating deprecated warnings for this test.
+#if defined(__DEPRECATED)
+#undef __DEPRECATED
+#endif
+
 #include <algorithm>
 #include <array>
 #include <bitset>
@@ -50,6 +56,7 @@
 #include <deque>
 #include <exception>
 #include <experimental/algorithm>
+#include <experimental/any>
 #include <experimental/chrono>
 #include <experimental/dynarray>
 #include <experimental/optional>
diff --git a/test/libcxx/experimental/any/small_type.pass.cpp b/test/libcxx/experimental/any/small_type.pass.cpp
index bcd15f1..e6595d4 100644
--- a/test/libcxx/experimental/any/small_type.pass.cpp
+++ b/test/libcxx/experimental/any/small_type.pass.cpp
@@ -16,6 +16,12 @@
 #include <experimental/any>
 #include "any_helpers.h"
 
+constexpr std::size_t BufferSize = (sizeof(void*) * 3);
+constexpr std::size_t BufferAlignment = alignof(void*);
+// Clang doesn't like "alignof(BufferAlignment * 2)" due to PR13986.
+// So we create "DoubleBufferAlignment" instead.
+constexpr std::size_t DoubleBufferAlignment = BufferAlignment * 2;
+
 class SmallThrowsDtor
 {
 public:
@@ -25,6 +31,30 @@
     ~SmallThrowsDtor() noexcept(false) {}
 };
 
+
+struct alignas(1) MaxSizeType {
+    char buff[BufferSize];
+};
+
+struct alignas(BufferAlignment) MaxAlignType {
+};
+
+struct alignas(BufferAlignment) MaxSizeAndAlignType {
+    char buff[BufferSize];
+};
+
+
+struct alignas(1) OverSizeType {
+    char buff[BufferSize + 1];
+};
+
+struct alignas(DoubleBufferAlignment) OverAlignedType {
+};
+
+struct alignas(DoubleBufferAlignment) OverSizeAndAlignedType {
+    char buff[BufferSize + 1];
+};
+
 int main()
 {
     using std::experimental::any;
@@ -33,8 +63,52 @@
     static_assert(_IsSmallObject<void*>::value, "");
     static_assert(!_IsSmallObject<SmallThrowsDtor>::value, "");
     static_assert(!_IsSmallObject<large>::value, "");
-    // long double is over aligned.
-    static_assert(sizeof(long double) <= sizeof(void*) * 3, "");
-    static_assert(alignof(long double) > alignof(void*), "");
-    static_assert(!_IsSmallObject<long double>::value, "");
+    {
+        // Check a type that meets the size requirement *exactly* and has
+        // a lesser alignment requirement is considered small.
+        typedef MaxSizeType T;
+        static_assert(sizeof(T) == BufferSize, "");
+        static_assert(alignof(T) < BufferAlignment,   "");
+        static_assert(_IsSmallObject<T>::value, "");
+    }
+    {
+        // Check a type that meets the alignment requirement *exactly* and has
+        // a lesser size is considered small.
+        typedef MaxAlignType T;
+        static_assert(sizeof(T) < BufferSize, "");
+        static_assert(alignof(T) == BufferAlignment,   "");
+        static_assert(_IsSmallObject<T>::value, "");
+    }
+    {
+        // Check a type that meets the size and alignment requirements *exactly*
+        // is considered small.
+        typedef MaxSizeAndAlignType T;
+        static_assert(sizeof(T) == BufferSize, "");
+        static_assert(alignof(T) == BufferAlignment,   "");
+        static_assert(_IsSmallObject<T>::value, "");
+    }
+    {
+        // Check a type that meets the alignment requirements but is over-sized
+        // is not considered small.
+        typedef OverSizeType T;
+        static_assert(sizeof(T) > BufferSize, "");
+        static_assert(alignof(T) < BufferAlignment, "");
+        static_assert(!_IsSmallObject<T>::value, "");
+    }
+    {
+        // Check a type that meets the size requirements but is over-aligned
+        // is not considered small.
+        typedef OverAlignedType T;
+        static_assert(sizeof(T) < BufferSize, "");
+        static_assert(alignof(T) > BufferAlignment, "");
+        static_assert(!_IsSmallObject<T>::value, "");
+    }
+    {
+        // Check a type that exceeds both the size an alignment requirements
+        // is not considered small.
+        typedef OverSizeAndAlignedType T;
+        static_assert(sizeof(T) > BufferSize, "");
+        static_assert(alignof(T) > BufferAlignment, "");
+        static_assert(!_IsSmallObject<T>::value, "");
+    }
 }
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 0effac2..738c0c7 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
@@ -7,6 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
+// UNSUPPORTED: c++98, c++03, c++11
+
 // dynarray.cons
 
 // explicit dynarray(size_type c);
@@ -16,22 +19,21 @@
 
 // ~dynarray();
 
-  
-#include <__config>
-
-#if _LIBCPP_STD_VER > 11
 
 #include <experimental/dynarray>
 #include <cassert>
 
 #include <algorithm>
 #include <complex>
+#include <limits>
+#include <new>
 #include <string>
 
+
 using std::experimental::dynarray;
 
 template <class T>
-void test ( const std::initializer_list<T> &vals ) {
+void testInitList( const std::initializer_list<T> &vals ) {
     typedef dynarray<T> dynA;
     
     dynA d1 ( vals );
@@ -41,12 +43,14 @@
 
 
 template <class T>
-void test ( const T &val ) {
+void test ( const T &val, bool DefaultValueIsIndeterminate = false) {
     typedef dynarray<T> dynA;
     
     dynA d1 ( 4 );
     assert ( d1.size () == 4 );
-    assert ( std::all_of ( d1.begin (), d1.end (), []( const T &item ){ return item == T(); } ));
+    if (!DefaultValueIsIndeterminate) {
+        assert ( std::all_of ( d1.begin (), d1.end (), []( const T &item ){ return item == T(); } ));
+    }
 
     dynA d2 ( 7, val );
     assert ( d2.size () == 7 );
@@ -60,27 +64,23 @@
 void test_bad_length () {
     try { dynarray<int> ( std::numeric_limits<size_t>::max() / sizeof ( int ) + 1 ); }
     catch ( std::bad_array_length & ) { return ; }
+    catch (...) { assert(false); }
     assert ( false );
-    }
+}
 
-void test_bad_alloc () {
-    try { dynarray<int> ( std::numeric_limits<size_t>::max() / sizeof ( int ) - 1 ); }
-    catch ( std::bad_alloc & ) { return ; }
-    assert ( false );
-    }
 
 int main()
 {
-//  test<int> ( 14 );       // ints don't get default initialized
-    test<long> ( 0 );
-    test<double> ( 14.0 );
+    test<int> ( 14, /* DefaultValueIsIndeterminate */ true );       // ints don't get default initialized
+    test<long> ( 0, true);
+    test<double> ( 14.0, true );
     test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
     test<std::string> ( "fourteen" );
     
-    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"), 
-                std::string("5"), std::string("8")} );
+    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 );
@@ -88,8 +88,4 @@
     assert ( std::all_of ( d1.begin (), d1.end (), []( long item ){ return item == 3L; } ));
 
     test_bad_length ();
-    test_bad_alloc ();
 }
-#else
-int main() {}
-#endif
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default_throws_bad_alloc.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default_throws_bad_alloc.pass.cpp
new file mode 100644
index 0000000..612e661
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default_throws_bad_alloc.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: libcpp-no-exceptions
+// dynarray.cons
+
+// explicit dynarray(size_type c);
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// The sanitizers replace new/delete with versions that do not throw bad_alloc.
+// UNSUPPORTED: sanitizer-new-delete, ubsan
+
+
+#include <experimental/dynarray>
+#include <limits>
+#include <new>
+#include <cassert>
+
+
+using std::experimental::dynarray;
+
+int main() {
+    try { dynarray<int>((std::numeric_limits<size_t>::max() / sizeof(int)) - 1); }
+    catch (std::bad_alloc &) { return 0; }
+    catch (...) { assert(false); }
+    assert(false);
+}
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 b669f25..1bbd8cd 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
@@ -7,15 +7,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: c++98, c++03, c++11
+
 // dynarray.data
 
 // T* data() noexcept;
 // const T* data() const noexcept;
 
-  
-#include <__config>
-
-#if _LIBCPP_STD_VER > 11
 
 #include <experimental/dynarray>
 #include <cassert>
@@ -27,41 +25,44 @@
 using std::experimental::dynarray;
 
 template <class T>
-void dyn_test_const ( const dynarray<T> &dyn ) {
+void dyn_test_const(const dynarray<T> &dyn, bool CheckEquals = true) {
     const T *data = dyn.data ();
     assert ( data != NULL );
-    assert ( std::equal ( dyn.begin(), dyn.end(), data ));
+    if (CheckEquals) {
+        assert ( std::equal ( dyn.begin(), dyn.end(), data ));
     }
+}
 
 template <class T>
-void dyn_test ( dynarray<T> &dyn ) {
+void dyn_test( dynarray<T> &dyn, bool CheckEquals = true) {
     T *data = dyn.data ();
     assert ( data != NULL );
-    assert ( std::equal ( dyn.begin(), dyn.end(), data ));
+    if (CheckEquals) {
+        assert ( std::equal ( dyn.begin(), dyn.end(), data ));
     }
+}
 
     
 
 template <class T>
-void test ( const T &val ) {
+void test(const T &val, bool DefaultValueIsIndeterminate = false) {
     typedef dynarray<T> dynA;
+
+    const bool CheckDefaultValues = !DefaultValueIsIndeterminate;
+
+    dynA d1(4);
+    dyn_test(d1, CheckDefaultValues);
+    dyn_test_const(d1, CheckDefaultValues);
     
-    dynA d1 ( 4 );
-    dyn_test ( d1 );
-    dyn_test_const ( d1 );
-    
-    dynA d2 ( 7, val );
+    dynA d2 (7, val);
     dyn_test ( d2 );
     dyn_test_const ( d2 );
-    }
+}
 
 int main()
 {
-    test<int> ( 14 );
-    test<double> ( 14.0 );
+    test<int>(14, /* DefaultValueIsIndeterminate */ true);
+    test<double>(14.0, true);
     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 4d77cf7..8c0d085 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,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // dynarray.overview
 
 // const_reference at(size_type n) const;
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 e82aa64..2af862a 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
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: c++98, c++03, c++11
+
 // dynarray.overview
 
 // reference       front();
@@ -14,10 +16,6 @@
 // reference       back();
 // const_reference back()  const;
 
-  
-#include <__config>
-
-#if _LIBCPP_STD_VER > 11
 
 #include <experimental/dynarray>
 #include <cassert>
@@ -29,40 +27,47 @@
 using std::experimental::dynarray;
 
 template <class T>
-void dyn_test_const ( const dynarray<T> &dyn ) {
+void dyn_test_const ( const dynarray<T> &dyn, bool CheckValues = true ) {
     const T *data = dyn.data ();
-    assert ( *data == dyn.front ());
-    assert ( *(data + dyn.size() - 1 ) == dyn.back ());
+    assert(data == &dyn.front());
+    assert((data + dyn.size() - 1) == &dyn.back());
+    if (CheckValues) {
+        assert ( *data == dyn.front ());
+        assert ( *(data + dyn.size() - 1 ) == dyn.back ());
     }
+}
 
 template <class T>
-void dyn_test ( dynarray<T> &dyn ) {
+void dyn_test ( dynarray<T> &dyn, bool CheckValues = true ) {
     T *data = dyn.data ();
-    assert ( *data == dyn.front ());
-    assert ( *(data + dyn.size() - 1 ) == dyn.back ());
+    assert(data == &dyn.front());
+    assert((data + dyn.size() - 1) == &dyn.back());
+    if (CheckValues) {
+        assert ( *data == dyn.front ());
+        assert ( *(data + dyn.size() - 1 ) == dyn.back ());
     }
+}
 
 
 template <class T>
-void test ( const T &val ) {
+void test ( const T &val, bool DefaultValueIsIndeterminate = false) {
     typedef dynarray<T> dynA;
-    
+
+    const bool CheckDefaultValues = ! DefaultValueIsIndeterminate;
+
     dynA d1 ( 4 );
-    dyn_test ( d1 );
-    dyn_test_const ( d1 );
+    dyn_test ( d1, CheckDefaultValues );
+    dyn_test_const ( d1, CheckDefaultValues );
     
     dynA d2 ( 7, val );
     dyn_test ( d2 );
     dyn_test_const ( d2 );
-    }
+}
 
 int main()
 {
-    test<int> ( 14 );
-    test<double> ( 14.0 );
+    test<int> ( 14, /* DefaultValueIsIndeterminate */ true);
+    test<double> ( 14.0, true );
     test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
     test<std::string> ( "fourteen" );
 }
-#else
-int main() {}
-#endif
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 0000000..83b3041
--- /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 0000000..020133f
--- /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 0000000..001c689
--- /dev/null
+++ b/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/max_size.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/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 0000000..ccb9b71
--- /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/std/containers/sequences/vector/const_value_type.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_deque_libcpp_version.pass.cpp
similarity index 66%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/libcxx/experimental/memory/memory.resource.aliases/header_deque_libcpp_version.pass.cpp
index e16e439..04b361d 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_deque_libcpp_version.pass.cpp
@@ -7,16 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// UNSUPPORTED: c++98, c++03
 
-// vector<const int> v;  // an extension
+// <experimental/deque>
 
-#include <vector>
-#include <type_traits>
+#include <experimental/deque>
+
+#ifndef _LIBCPP_VERSION
+#error header must provide _LIBCPP_VERSION
+#endif
 
 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/const_value_type.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_forward_list_libcpp_version.pass.cpp
similarity index 66%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/libcxx/experimental/memory/memory.resource.aliases/header_forward_list_libcpp_version.pass.cpp
index e16e439..11fc21b 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_forward_list_libcpp_version.pass.cpp
@@ -7,16 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// UNSUPPORTED: c++98, c++03
 
-// vector<const int> v;  // an extension
+// <experimental/forward_list>
 
-#include <vector>
-#include <type_traits>
+#include <experimental/forward_list>
+
+#ifndef _LIBCPP_VERSION
+#error header must provide _LIBCPP_VERSION
+#endif
 
 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/const_value_type.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_list_libcpp_version.pass.cpp
similarity index 66%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/libcxx/experimental/memory/memory.resource.aliases/header_list_libcpp_version.pass.cpp
index e16e439..9a72979 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_list_libcpp_version.pass.cpp
@@ -7,16 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// UNSUPPORTED: c++98, c++03
 
-// vector<const int> v;  // an extension
+// <experimental/list>
 
-#include <vector>
-#include <type_traits>
+#include <experimental/list>
+
+#ifndef _LIBCPP_VERSION
+#error header must provide _LIBCPP_VERSION
+#endif
 
 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/const_value_type.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_map_libcpp_version.pass.cpp
similarity index 66%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/libcxx/experimental/memory/memory.resource.aliases/header_map_libcpp_version.pass.cpp
index e16e439..24a1bf3 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_map_libcpp_version.pass.cpp
@@ -7,16 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// UNSUPPORTED: c++98, c++03
 
-// vector<const int> v;  // an extension
+// <experimental/map>
 
-#include <vector>
-#include <type_traits>
+#include <experimental/map>
+
+#ifndef _LIBCPP_VERSION
+#error header must provide _LIBCPP_VERSION
+#endif
 
 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/const_value_type.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_regex_libcpp_version.pass.cpp
similarity index 66%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/libcxx/experimental/memory/memory.resource.aliases/header_regex_libcpp_version.pass.cpp
index e16e439..ff81bc0 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_regex_libcpp_version.pass.cpp
@@ -7,16 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// UNSUPPORTED: c++98, c++03
 
-// vector<const int> v;  // an extension
+// <experimental/regex>
 
-#include <vector>
-#include <type_traits>
+#include <experimental/regex>
+
+#ifndef _LIBCPP_VERSION
+#error header must provide _LIBCPP_VERSION
+#endif
 
 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/const_value_type.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_set_libcpp_version.pass.cpp
similarity index 66%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/libcxx/experimental/memory/memory.resource.aliases/header_set_libcpp_version.pass.cpp
index e16e439..6b02f46 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_set_libcpp_version.pass.cpp
@@ -7,16 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// UNSUPPORTED: c++98, c++03
 
-// vector<const int> v;  // an extension
+// <experimental/set>
 
-#include <vector>
-#include <type_traits>
+#include <experimental/set>
+
+#ifndef _LIBCPP_VERSION
+#error header must provide _LIBCPP_VERSION
+#endif
 
 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/const_value_type.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_string_libcpp_version.pass.cpp
similarity index 66%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/libcxx/experimental/memory/memory.resource.aliases/header_string_libcpp_version.pass.cpp
index e16e439..b4b7fdf 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_string_libcpp_version.pass.cpp
@@ -7,16 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// UNSUPPORTED: c++98, c++03
 
-// vector<const int> v;  // an extension
+// <experimental/string>
 
-#include <vector>
-#include <type_traits>
+#include <experimental/string>
+
+#ifndef _LIBCPP_VERSION
+#error header must provide _LIBCPP_VERSION
+#endif
 
 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/const_value_type.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_unordered_map_libcpp_version.pass.cpp
similarity index 66%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/libcxx/experimental/memory/memory.resource.aliases/header_unordered_map_libcpp_version.pass.cpp
index e16e439..ab9cc18 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_unordered_map_libcpp_version.pass.cpp
@@ -7,16 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// UNSUPPORTED: c++98, c++03
 
-// vector<const int> v;  // an extension
+// <experimental/unordered_map>
 
-#include <vector>
-#include <type_traits>
+#include <experimental/unordered_map>
+
+#ifndef _LIBCPP_VERSION
+#error header must provide _LIBCPP_VERSION
+#endif
 
 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/const_value_type.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_unordered_set_libcpp_version.pass.cpp
similarity index 66%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/libcxx/experimental/memory/memory.resource.aliases/header_unordered_set_libcpp_version.pass.cpp
index e16e439..37533c7 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_unordered_set_libcpp_version.pass.cpp
@@ -7,16 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// UNSUPPORTED: c++98, c++03
 
-// vector<const int> v;  // an extension
+// <experimental/unordered_set>
 
-#include <vector>
-#include <type_traits>
+#include <experimental/unordered_set>
+
+#ifndef _LIBCPP_VERSION
+#error header must provide _LIBCPP_VERSION
+#endif
 
 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/const_value_type.pass.cpp b/test/libcxx/experimental/memory/memory.resource.aliases/header_vector_libcpp_version.pass.cpp
similarity index 66%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/libcxx/experimental/memory/memory.resource.aliases/header_vector_libcpp_version.pass.cpp
index e16e439..103d32b 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/libcxx/experimental/memory/memory.resource.aliases/header_vector_libcpp_version.pass.cpp
@@ -7,16 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// UNSUPPORTED: c++98, c++03
 
-// vector<const int> v;  // an extension
+// <experimental/vector>
 
-#include <vector>
-#include <type_traits>
+#include <experimental/vector>
+
+#ifndef _LIBCPP_VERSION
+#error header must provide _LIBCPP_VERSION
+#endif
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
 }
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 0000000..6385ee9
--- /dev/null
+++ b/test/libcxx/experimental/memory/memory.resource.global/global_memory_resource_lifetime.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: 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 0000000..abdfda8
--- /dev/null
+++ b/test/libcxx/experimental/memory/memory.resource.global/new_delete_resource_lifetime.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.
+//
+//===----------------------------------------------------------------------===//
+
+// 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/std/containers/sequences/vector/const_value_type.pass.cpp b/test/libcxx/experimental/memory/memory.resource.synop/version.pass.cpp
similarity index 67%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/libcxx/experimental/memory/memory.resource.synop/version.pass.cpp
index e16e439..d05575e 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/libcxx/experimental/memory/memory.resource.synop/version.pass.cpp
@@ -7,16 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// UNSUPPORTED: c++98, c++03
 
-// vector<const int> v;  // an extension
+// <experimental/memory_resource>
 
-#include <vector>
-#include <type_traits>
+#include <experimental/memory_resource>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
 }
diff --git a/test/std/extensions/hash/specializations.fail.cpp b/test/libcxx/extensions/hash/specializations.fail.cpp
similarity index 100%
rename from test/std/extensions/hash/specializations.fail.cpp
rename to 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
similarity index 100%
rename from test/std/extensions/hash/specializations.pass.cpp
rename to 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
similarity index 100%
rename from test/std/extensions/hash_map/const_iterator.fail.cpp
rename to 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
similarity index 100%
rename from test/std/extensions/nothing_to_do.pass.cpp
rename to test/libcxx/extensions/nothing_to_do.pass.cpp
diff --git a/test/libcxx/iterators/trivial_iterators.pass.cpp b/test/libcxx/iterators/trivial_iterators.pass.cpp
new file mode 100644
index 0000000..0b7a473
--- /dev/null
+++ b/test/libcxx/iterators/trivial_iterators.pass.cpp
@@ -0,0 +1,187 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+
+// <iterator>
+
+// __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. 
+// 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.
+//
+
+#include <iterator>
+#include <cassert>
+#include <string>
+#include <vector>
+#include <initializer_list>
+
+#include "test_iterators.h"
+
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+#define DELETE_FUNCTION = delete
+#else
+#define DELETE_FUNCTION
+#endif
+
+class T;  // incomplete
+
+class my_input_iterator_tag : public std::input_iterator_tag {};
+
+template <class It>
+class my_input_iterator
+{
+    It it_;
+
+    template <class U> friend class input_iterator;
+public:
+    typedef          my_input_iterator_tag                     iterator_category;
+    typedef typename std::iterator_traits<It>::value_type      value_type;
+    typedef typename std::iterator_traits<It>::difference_type difference_type;
+    typedef It                                                 pointer;
+    typedef typename std::iterator_traits<It>::reference       reference;
+
+    It base() const {return it_;}
+
+    my_input_iterator() : it_() {}
+    explicit my_input_iterator(It it) : it_(it) {}
+    template <class U>
+        my_input_iterator(const input_iterator<U>& u) :it_(u.it_) {}
+
+    reference operator*() const {return *it_;}
+    pointer operator->() const {return it_;}
+
+    my_input_iterator& operator++() {++it_; return *this;}
+    my_input_iterator operator++(int)
+        {my_input_iterator tmp(*this); ++(*this); return tmp;}
+
+    friend bool operator==(const my_input_iterator& x, const my_input_iterator& y)
+        {return x.it_ == y.it_;}
+    friend bool operator!=(const my_input_iterator& x, const my_input_iterator& y)
+        {return !(x == y);}
+
+    template <class T>
+    void operator,(T const &) DELETE_FUNCTION;
+};
+
+template <class T, class U>
+inline
+bool
+operator==(const my_input_iterator<T>& x, const my_input_iterator<U>& y)
+{
+    return x.base() == y.base();
+}
+
+template <class T, class U>
+inline
+bool
+operator!=(const my_input_iterator<T>& x, const my_input_iterator<U>& y)
+{
+    return !(x == y);
+}
+
+
+int main()
+{
+//  basic tests
+    static_assert(( std::__libcpp_is_trivial_iterator<char *>::value), "");
+    static_assert(( std::__libcpp_is_trivial_iterator<const char *>::value), "");
+    static_assert(( std::__libcpp_is_trivial_iterator<int *>::value), "");
+    static_assert(( std::__libcpp_is_trivial_iterator<T *>::value), "");
+
+    static_assert(( std::__libcpp_is_trivial_iterator<std::move_iterator<char *> >      ::value), "");
+    static_assert(( std::__libcpp_is_trivial_iterator<std::move_iterator<const char *> >::value), "");
+    static_assert(( std::__libcpp_is_trivial_iterator<std::move_iterator<int *> >       ::value), "");
+    static_assert(( std::__libcpp_is_trivial_iterator<std::move_iterator<T *> >         ::value), "");
+
+    static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<char *> >      ::value), "");
+    static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<const char *> >::value), "");
+    static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<int *> >       ::value), "");
+    static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<T *> >         ::value), "");
+
+    static_assert(( std::__libcpp_is_trivial_iterator<std::__wrap_iter<char *> >      ::value), "");
+    static_assert(( std::__libcpp_is_trivial_iterator<std::__wrap_iter<const char *> >::value), "");
+    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), ""); 
+    
+//  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), "");    
+
+
+//	Iterator classification
+	static_assert(( std::__is_input_iterator        <char *>::value), "" );
+	static_assert(( std::__is_forward_iterator      <char *>::value), "" );
+	static_assert(( std::__is_bidirectional_iterator<char *>::value), "" );
+	static_assert(( std::__is_random_access_iterator<char *>::value), "" );
+	static_assert((!std::__is_exactly_input_iterator<char *>::value), "" );
+
+	static_assert(( std::__is_input_iterator        <input_iterator<char *> >::value), "" );
+	static_assert((!std::__is_forward_iterator      <input_iterator<char *> >::value), "" );
+	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), "" );
+	static_assert((!std::__is_random_access_iterator<forward_iterator<char *> >::value), "" );
+	static_assert((!std::__is_exactly_input_iterator<forward_iterator<char *> >::value), "" );
+
+	static_assert(( std::__is_input_iterator        <bidirectional_iterator<char *> >::value), "" );
+	static_assert(( std::__is_forward_iterator      <bidirectional_iterator<char *> >::value), "" );
+	static_assert(( std::__is_bidirectional_iterator<bidirectional_iterator<char *> >::value), "" );
+	static_assert((!std::__is_random_access_iterator<bidirectional_iterator<char *> >::value), "" );
+	static_assert((!std::__is_exactly_input_iterator<bidirectional_iterator<char *> >::value), "" );
+
+	static_assert(( std::__is_input_iterator        <random_access_iterator<char *> >::value), "" );
+	static_assert(( std::__is_forward_iterator      <random_access_iterator<char *> >::value), "" );
+	static_assert(( std::__is_bidirectional_iterator<random_access_iterator<char *> >::value), "" );
+	static_assert(( std::__is_random_access_iterator<random_access_iterator<char *> >::value), "" );
+	static_assert((!std::__is_exactly_input_iterator<random_access_iterator<char *> >::value), "" );
+
+	static_assert(( std::__is_input_iterator        <my_input_iterator<char *> >::value), "" );
+	static_assert((!std::__is_forward_iterator      <my_input_iterator<char *> >::value), "" );
+	static_assert((!std::__is_bidirectional_iterator<my_input_iterator<char *> >::value), "" );
+	static_assert((!std::__is_random_access_iterator<my_input_iterator<char *> >::value), "" );
+	static_assert(( std::__is_exactly_input_iterator<my_input_iterator<char *> >::value), "" );
+
+//
+//  iterators from libc++'s containers
+//
+
+//  string
+    static_assert(( std::__libcpp_is_trivial_iterator<std::vector<char>::iterator>              ::value), "");
+    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), "");
+    static_assert(( std::__libcpp_is_trivial_iterator<std::basic_string<char>::reverse_iterator>      ::value), "");
+    static_assert(( std::__libcpp_is_trivial_iterator<std::basic_string<char>::const_reverse_iterator>::value), "");
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+//  Initializer list  (which has no reverse iterators)
+    static_assert(( std::__libcpp_is_trivial_iterator<std::initializer_list<char>::iterator>              ::value), "");
+    static_assert(( std::__libcpp_is_trivial_iterator<std::initializer_list<char>::const_iterator>        ::value), "");
+#endif
+
+}
diff --git a/test/std/localization/locale.categories/__scan_keyword.pass.cpp b/test/libcxx/localization/locale.categories/__scan_keyword.pass.cpp
similarity index 100%
rename from test/std/localization/locale.categories/__scan_keyword.pass.cpp
rename to test/libcxx/localization/locale.categories/__scan_keyword.pass.cpp
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
similarity index 100%
rename from test/std/localization/locales/locale/locale.types/locale.facet/facet.pass.cpp
rename to 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
similarity index 100%
rename from test/std/localization/locales/locale/locale.types/locale.id/id.pass.cpp
rename to test/libcxx/localization/locales/locale/locale.types/locale.id/id.pass.cpp
diff --git a/test/libcxx/selftest/test_macros.pass.cpp b/test/libcxx/selftest/test_macros.pass.cpp
index 2c8ed4f..69e75b7 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
similarity index 100%
rename from test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_db1.pass.cpp
rename to 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
similarity index 100%
rename from test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_db2.pass.cpp
rename to 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
similarity index 100%
rename from test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db1.pass.cpp
rename to 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
similarity index 100%
rename from test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db2.pass.cpp
rename to 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
similarity index 100%
rename from test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db3.pass.cpp
rename to 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
similarity index 100%
rename from test/std/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db4.pass.cpp
rename to test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db4.pass.cpp
diff --git a/test/libcxx/strings/basic.string/string.modifiers/erase_pop_back_db1.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_pop_back_db1.pass.cpp
new file mode 100644
index 0000000..8a6c3f0
--- /dev/null
+++ b/test/libcxx/strings/basic.string/string.modifiers/erase_pop_back_db1.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// 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_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 0000000..fbb26d1
--- /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/libcxx/strings/basic.string/string.modifiers/insert_iter_size_char_db1.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/insert_iter_size_char_db1.pass.cpp
new file mode 100644
index 0000000..7ddd2b0
--- /dev/null
+++ b/test/libcxx/strings/basic.string/string.modifiers/insert_iter_size_char_db1.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// 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_DEBUG >= 1
+    {
+        std::string s;
+        std::string s2;
+        s.insert(s2.begin(), 1, 'a');
+        assert(false);
+    }
+#endif
+}
diff --git a/test/libcxx/strings/iterators.exceptions.pass.cpp b/test/libcxx/strings/iterators.exceptions.pass.cpp
new file mode 100644
index 0000000..7b7eaba
--- /dev/null
+++ b/test/libcxx/strings/iterators.exceptions.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.
+//
+//===----------------------------------------------------------------------===//
+//
+// XFAIL: libcpp-no-exceptions
+// <iterator>
+
+// __libcpp_is_trivial_iterator<Tp>
+
+// __libcpp_string_gets_noexcept_iterator determines if an iterator can be used
+// w/o worrying about whether or not certain operations can throw.
+// This gives us a "fast path for string operations"
+//
+
+#include <iterator>
+#include <cassert>
+#include <string>
+#include <vector>
+#include <initializer_list>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+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), "");
+    static_assert((!std::__libcpp_string_gets_noexcept_iterator<forward_iterator      <char *> >::value), "");
+    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 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
+//
+
+//  string
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::iterator>              ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::const_iterator>        ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::reverse_iterator>      ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::const_reverse_iterator>::value), "");
+
+//  vector
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::iterator>              ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::const_iterator>        ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::reverse_iterator>      ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::const_reverse_iterator>::value), "");
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+//  Initializer list  (which has no reverse iterators)
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::initializer_list<char>::iterator>              ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::initializer_list<char>::const_iterator>        ::value), "");
+#endif
+}
diff --git a/test/libcxx/strings/iterators.noexcept.pass.cpp b/test/libcxx/strings/iterators.noexcept.pass.cpp
new file mode 100644
index 0000000..f39a4de
--- /dev/null
+++ b/test/libcxx/strings/iterators.noexcept.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.
+//
+//===----------------------------------------------------------------------===//
+//
+
+// <iterator>
+
+// __libcpp_is_trivial_iterator<Tp>
+
+// __libcpp_string_gets_noexcept_iterator determines if an iterator can be used
+// w/o worrying about whether or not certain operations can throw.
+// This gives us a "fast path for string operations".
+//
+// When exceptions are disabled, all iterators should get this "fast path"
+//
+
+#define	_LIBCPP_NO_EXCEPTIONS
+
+#include <iterator>
+#include <cassert>
+#include <string>
+#include <vector>
+#include <initializer_list>
+
+#include "test_iterators.h"
+
+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), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<forward_iterator      <char *> >::value), "");
+    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
+//
+
+//  string
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::iterator>              ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::const_iterator>        ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::reverse_iterator>      ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::vector<char>::const_reverse_iterator>::value), "");
+
+//  vector
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::iterator>              ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::const_iterator>        ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::reverse_iterator>      ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::basic_string<char>::const_reverse_iterator>::value), "");
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+//  Initializer list  (which has no reverse iterators)
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::initializer_list<char>::iterator>              ::value), "");
+    static_assert(( std::__libcpp_string_gets_noexcept_iterator<std::initializer_list<char>::const_iterator>        ::value), "");
+#endif
+}
diff --git a/test/libcxx/test/config.py b/test/libcxx/test/config.py
index 502b688..897dd0c 100644
--- a/test/libcxx/test/config.py
+++ b/test/libcxx/test/config.py
@@ -1,4 +1,12 @@
-import importlib
+#===----------------------------------------------------------------------===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is dual licensed under the MIT and the University of Illinois Open
+# Source Licenses. See LICENSE.TXT for details.
+#
+#===----------------------------------------------------------------------===##
+
 import locale
 import os
 import platform
@@ -12,6 +20,7 @@
 
 from libcxx.test.format import LibcxxTestFormat
 from libcxx.compiler import CXXCompiler
+from libcxx.test.target_info import make_target_info
 from libcxx.test.executor import *
 from libcxx.test.tracing import *
 
@@ -42,16 +51,17 @@
         ld_fn(config, site_cfg)
         lit_config.load_config = ld_fn
 
-
 class Configuration(object):
     # pylint: disable=redefined-outer-name
     def __init__(self, lit_config, config):
         self.lit_config = lit_config
         self.config = config
         self.cxx = None
+        self.project_obj_root = None
         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
@@ -89,6 +99,7 @@
         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()
@@ -141,13 +152,7 @@
         self.executor = te
 
     def configure_target_info(self):
-        default = "libcxx.test.target_info.LocalTI"
-        info_str = self.get_lit_conf('target_info', default)
-        mod_path, _, info = info_str.rpartition('.')
-        mod = importlib.import_module(mod_path)
-        self.target_info = getattr(mod, info)()
-        if info_str != default:
-            self.lit_config.note("inferred target_info as: %r" % info_str)
+        self.target_info = make_target_info(self)
 
     def configure_cxx(self):
         # Gather various compiler parameters.
@@ -179,11 +184,20 @@
             'libcxx_src_root', os.path.dirname(self.config.test_source_root))
 
     def configure_obj_root(self):
+        self.project_obj_root = self.get_lit_conf('project_obj_root')
         self.libcxx_obj_root = self.get_lit_conf('libcxx_obj_root')
+        if not self.libcxx_obj_root and self.project_obj_root is not None:
+            possible_root = os.path.join(self.project_obj_root, 'projects', 'libcxx')
+            if os.path.isdir(possible_root):
+                self.libcxx_obj_root = possible_root
+            else:
+                self.libcxx_obj_root = self.project_obj_root
 
     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
@@ -208,16 +222,23 @@
             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
-        # default value. Otherwise we default to internal on Windows and
-        # external elsewhere, as bash on Windows is usually very slow.
+        # default value. Otherwise we ask the target_info.
         use_lit_shell_default = os.environ.get('LIT_USE_INTERNAL_SHELL')
         if use_lit_shell_default is not None:
             use_lit_shell_default = use_lit_shell_default != '0'
         else:
-            use_lit_shell_default = sys.platform == 'win32'
+            use_lit_shell_default = self.target_info.use_lit_shell_default()
         # Check for the command line parameter using the default value if it is
         # not present.
         use_lit_shell = self.get_lit_bool('use_lit_shell',
@@ -236,63 +257,10 @@
         if additional_features:
             for f in additional_features.split(','):
                 self.config.available_features.add(f.strip())
+        self.target_info.add_locale_features(self.config.available_features)
 
-        # Figure out which of the required locales we support
-        locales = {
-            'Darwin': {
-                'en_US.UTF-8': 'en_US.UTF-8',
-                'cs_CZ.ISO8859-2': 'cs_CZ.ISO8859-2',
-                'fr_FR.UTF-8': 'fr_FR.UTF-8',
-                'fr_CA.ISO8859-1': 'fr_CA.ISO8859-1',
-                'ru_RU.UTF-8': 'ru_RU.UTF-8',
-                'zh_CN.UTF-8': 'zh_CN.UTF-8',
-            },
-            'FreeBSD': {
-                'en_US.UTF-8': 'en_US.UTF-8',
-                'cs_CZ.ISO8859-2': 'cs_CZ.ISO8859-2',
-                'fr_FR.UTF-8': 'fr_FR.UTF-8',
-                'fr_CA.ISO8859-1': 'fr_CA.ISO8859-1',
-                'ru_RU.UTF-8': 'ru_RU.UTF-8',
-                'zh_CN.UTF-8': 'zh_CN.UTF-8',
-            },
-            'Linux': {
-                'en_US.UTF-8': 'en_US.UTF-8',
-                'cs_CZ.ISO8859-2': 'cs_CZ.ISO-8859-2',
-                'fr_FR.UTF-8': 'fr_FR.UTF-8',
-                'fr_CA.ISO8859-1': 'fr_CA.ISO-8859-1',
-                'ru_RU.UTF-8': 'ru_RU.UTF-8',
-                'zh_CN.UTF-8': 'zh_CN.UTF-8',
-            },
-            'Windows': {
-                'en_US.UTF-8': 'English_United States.1252',
-                'cs_CZ.ISO8859-2': 'Czech_Czech Republic.1250',
-                'fr_FR.UTF-8': 'French_France.1252',
-                'fr_CA.ISO8859-1': 'French_Canada.1252',
-                'ru_RU.UTF-8': 'Russian_Russia.1251',
-                'zh_CN.UTF-8': 'Chinese_China.936',
-            },
-        }
-
-        target_system = self.target_info.system()
         target_platform = self.target_info.platform()
 
-        if target_system in locales:
-            default_locale = locale.setlocale(locale.LC_ALL)
-            for feature, loc in locales[target_system].items():
-                try:
-                    locale.setlocale(locale.LC_ALL, loc)
-                    self.config.available_features.add(
-                        'locale.{0}'.format(feature))
-                except locale.Error:
-                    self.lit_config.warning('The locale {0} is not supported by '
-                                            'your platform. Some tests will be '
-                                            'unsupported.'.format(loc))
-            locale.setlocale(locale.LC_ALL, default_locale)
-        else:
-            # Warn that the user doesn't get any free XFAILs for locale issues
-            self.lit_config.warning("No locales entry for target_system: %s" %
-                                    target_system)
-
         # Write an "available feature" that combines the triple when
         # use_system_cxx_lib is enabled. This is so that we can easily write
         # XFAIL markers for tests that are known to fail with versions of
@@ -304,17 +272,6 @@
         # Insert the platform name into the available features as a lower case.
         self.config.available_features.add(target_platform)
 
-        # Some linux distributions have different locale data than others.
-        # Insert the distributions name and name-version into the available
-        # features to allow tests to XFAIL on them.
-        if target_platform == 'linux':
-            name = self.target_info.platform_name()
-            ver = self.target_info.platform_ver()
-            if name:
-                self.config.available_features.add(name)
-            if name and ver:
-                self.config.available_features.add('%s-%s' % (name, ver))
-
         # Simulator testing can take a really long time for some of these tests
         # so add a feature check so we can REQUIRES: long_tests in them
         self.long_tests = self.get_lit_bool('long_tests')
@@ -336,6 +293,10 @@
         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)
@@ -344,38 +305,33 @@
         # Try and get the std version from the command line. Fall back to
         # default given in lit.site.cfg is not present. If default is not
         # present then force c++11.
-        std = self.get_lit_conf('std', 'c++11')
+        std = self.get_lit_conf('std')
+        if not std:
+            # Choose the newest possible language dialect if none is given.
+            possible_stds = ['c++1z', 'c++14', 'c++11', 'c++03']
+            for s in possible_stds:
+                if self.cxx.hasCompileFlag('-std=%s' % s):
+                    std = s
+                    self.lit_config.note(
+                        'inferred language dialect as: %s' % std)
+                    break
+            if not std:
+                self.lit_config.fatal(
+                    'Failed to infer a supported language dialect from one of %r'
+                    % possible_stds)
         self.cxx.compile_flags += ['-std={0}'.format(std)]
         self.config.available_features.add(std)
         # Configure include paths
         self.cxx.compile_flags += ['-nostdinc++']
         self.configure_compile_flags_header_includes()
-        if self.target_info.platform() == 'linux':
-            self.cxx.compile_flags += ['-D__STDC_FORMAT_MACROS',
-                                       '-D__STDC_LIMIT_MACROS',
-                                       '-D__STDC_CONSTANT_MACROS']
+        self.target_info.add_cxx_compile_flags(self.cxx.compile_flags)
         # Configure feature flags.
         self.configure_compile_flags_exceptions()
         self.configure_compile_flags_rtti()
-        self.configure_compile_flags_no_global_filesystem_namespace()
-        self.configure_compile_flags_no_stdin()
-        self.configure_compile_flags_no_stdout()
+        self.configure_compile_flags_abi_version()
         enable_32bit = self.get_lit_bool('enable_32bit', False)
         if enable_32bit:
             self.cxx.flags += ['-m32']
-        # Configure threading features.
-        enable_threads = self.get_lit_bool('enable_threads', True)
-        enable_monotonic_clock = self.get_lit_bool('enable_monotonic_clock',
-                                                   True)
-        if not enable_threads:
-            self.configure_compile_flags_no_threads()
-            if not enable_monotonic_clock:
-                self.configure_compile_flags_no_monotonic_clock()
-        elif not enable_monotonic_clock:
-            self.lit_config.fatal('enable_monotonic_clock cannot be false when'
-                                  ' enable_threads is true.')
-        self.configure_compile_flags_no_thread_unsafe_c_functions()
-
         # Use verbose output for better errors
         self.cxx.flags += ['-v']
         sysroot = self.get_lit_conf('sysroot')
@@ -389,8 +345,8 @@
 
     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(
             'libcxx_headers', os.path.join(self.libcxx_src_root, 'include'))
         if not os.path.isdir(libcxx_headers):
@@ -398,6 +354,56 @@
                                   % libcxx_headers)
         self.cxx.compile_flags += ['-I' + libcxx_headers]
 
+    def configure_config_site_header(self):
+        # Check for a possible __config_site in the build directory. We
+        # use this if it exists.
+        if self.libcxx_obj_root is None:
+            return
+        config_site_header = os.path.join(self.libcxx_obj_root, '__config_site')
+        if not os.path.isfile(config_site_header):
+            return
+        contained_macros = self.parse_config_site_and_add_features(
+            config_site_header)
+        self.lit_config.note('Using __config_site header %s with macros: %r'
+            % (config_site_header, contained_macros))
+        # FIXME: This must come after the call to
+        # 'parse_config_site_and_add_features(...)' in order for it to work.
+        self.cxx.compile_flags += ['-include', config_site_header]
+
+    def parse_config_site_and_add_features(self, header):
+        """ parse_config_site_and_add_features - Deduce and add the test
+            features that that are implied by the #define's in the __config_site
+            header. Return a dictionary containing the macros found in the
+            '__config_site' header.
+        """
+        # Parse the macro contents of __config_site by dumping the macros
+        # using 'c++ -dM -E' and filtering the predefines.
+        predefines = self.cxx.dumpMacros()
+        macros = self.cxx.dumpMacros(header)
+        feature_macros_keys = set(macros.keys()) - set(predefines.keys())
+        feature_macros = {}
+        for k in feature_macros_keys:
+            feature_macros[k] = macros[k]
+        # We expect the header guard to be one of the definitions
+        assert '_LIBCPP_CONFIG_SITE' in feature_macros
+        del feature_macros['_LIBCPP_CONFIG_SITE']
+        # The __config_site header should be non-empty. Otherwise it should
+        # have never been emitted by CMake.
+        assert len(feature_macros) > 0
+        # Transform each macro name into the feature name used in the tests.
+        # Ex. _LIBCPP_HAS_NO_THREADS -> libcpp-has-no-threads
+        for m in feature_macros:
+            if m == '_LIBCPP_ABI_VERSION':
+                self.config.available_features.add('libcpp-abi-version-v%s'
+                    % feature_macros[m])
+                continue
+            assert m.startswith('_LIBCPP_HAS_') or m == '_LIBCPP_ABI_UNSTABLE'
+            m = m.lower()[1:].replace('_', '-')
+            self.config.available_features.add(m)
+        return feature_macros
+
+
+
     def configure_compile_flags_exceptions(self):
         enable_exceptions = self.get_lit_bool('enable_exceptions', True)
         if not enable_exceptions:
@@ -410,43 +416,16 @@
             self.config.available_features.add('libcpp-no-rtti')
             self.cxx.compile_flags += ['-fno-rtti', '-D_LIBCPP_NO_RTTI']
 
-    def configure_compile_flags_no_global_filesystem_namespace(self):
-        enable_global_filesystem_namespace = self.get_lit_bool(
-            'enable_global_filesystem_namespace', True)
-        if not enable_global_filesystem_namespace:
-            self.config.available_features.add(
-                'libcpp-has-no-global-filesystem-namespace')
-            self.cxx.compile_flags += [
-                '-D_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE']
-
-    def configure_compile_flags_no_stdin(self):
-        enable_stdin = self.get_lit_bool('enable_stdin', True)
-        if not enable_stdin:
-            self.config.available_features.add('libcpp-has-no-stdin')
-            self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_STDIN']
-
-    def configure_compile_flags_no_stdout(self):
-        enable_stdout = self.get_lit_bool('enable_stdout', True)
-        if not enable_stdout:
-            self.config.available_features.add('libcpp-has-no-stdout')
-            self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_STDOUT']
-
-    def configure_compile_flags_no_threads(self):
-        self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_THREADS']
-        self.config.available_features.add('libcpp-has-no-threads')
-
-    def configure_compile_flags_no_thread_unsafe_c_functions(self):
-        enable_thread_unsafe_c_functions = self.get_lit_bool(
-            'enable_thread_unsafe_c_functions', True)
-        if not enable_thread_unsafe_c_functions:
-            self.cxx.compile_flags += [
-                '-D_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS']
-            self.config.available_features.add(
-                'libcpp-has-no-thread-unsafe-c-functions')
-
-    def configure_compile_flags_no_monotonic_clock(self):
-        self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_MONOTONIC_CLOCK']
-        self.config.available_features.add('libcpp-has-no-monotonic-clock')
+    def configure_compile_flags_abi_version(self):
+        abi_version = self.get_lit_conf('abi_version', '').strip()
+        abi_unstable = self.get_lit_bool('abi_unstable')
+        # Only add the ABI version when it is non-default.
+        # FIXME(EricWF): Get the ABI version from the "__config_site".
+        if abi_version and abi_version != '1':
+          self.cxx.compile_flags += ['-D_LIBCPP_ABI_VERSION=' + abi_version]
+        if abi_unstable:
+          self.config.available_features.add('libcpp-abi-unstable')
+          self.cxx.compile_flags += ['-D_LIBCPP_ABI_UNSTABLE']
 
     def configure_link_flags(self):
         no_default_flags = self.get_lit_bool('no_default_flags', False)
@@ -466,23 +445,11 @@
         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.
@@ -492,11 +459,20 @@
                                     '-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')
@@ -505,10 +481,17 @@
         elif cxx_abi == 'libsupc++':
             self.cxx.link_flags += ['-lsupc++']
         elif cxx_abi == 'libcxxabi':
-            # Don't link libc++abi explicitly on OS X because the symbols
-            # should be available in libc++ directly.
-            if self.target_info.platform() != 'darwin':
-                self.cxx.link_flags += ['-lc++abi']
+            if self.target_info.allow_cxxabi_link():
+                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':
@@ -518,26 +501,7 @@
                 'C++ ABI setting %s unsupported for tests' % cxx_abi)
 
     def configure_extra_library_flags(self):
-        enable_threads = self.get_lit_bool('enable_threads', True)
-        llvm_unwinder = self.get_lit_bool('llvm_unwinder', False)
-        target_platform = self.target_info.platform()
-        if target_platform == 'darwin':
-            self.cxx.link_flags += ['-lSystem']
-        elif target_platform == 'linux':
-            if not llvm_unwinder:
-                self.cxx.link_flags += ['-lgcc_eh']
-            self.cxx.link_flags += ['-lc', '-lm']
-            if enable_threads:
-                self.cxx.link_flags += ['-lpthread']
-            self.cxx.link_flags += ['-lrt']
-            if llvm_unwinder:
-                self.cxx.link_flags += ['-lunwind', '-ldl']
-            else:
-                self.cxx.link_flags += ['-lgcc_s']
-        elif target_platform.startswith('freebsd'):
-            self.cxx.link_flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
-        else:
-            self.lit_config.fatal("unrecognized system: %r" % target_platform)
+        self.target_info.add_cxx_link_flags(self.cxx.link_flags)
 
     def configure_color_diagnostics(self):
         use_color = self.get_lit_conf('color_diagnostics')
@@ -572,22 +536,28 @@
         if enable_warnings:
             self.cxx.compile_flags += [
                 '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER',
-                '-Wall', '-Werror'
+                '-Wall', '-Wextra', '-Werror'
             ]
-            self.cxx.addCompileFlagIfSupported('-Wno-attributes')
-            if self.cxx.type == 'clang' or self.cxx.type == 'apple-clang':
-                self.cxx.addCompileFlagIfSupported('-Wno-pessimizing-move')
-                self.cxx.addCompileFlagIfSupported('-Wno-c++11-extensions')
-                self.cxx.addCompileFlagIfSupported('-Wno-user-defined-literals')
+            self.cxx.addWarningFlagIfSupported('-Wno-attributes')
+            self.cxx.addWarningFlagIfSupported('-Wno-pessimizing-move')
+            self.cxx.addWarningFlagIfSupported('-Wno-c++11-extensions')
+            self.cxx.addWarningFlagIfSupported('-Wno-user-defined-literals')
+            # TODO(EricWF) Remove the unused warnings once the test suite
+            # 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
                 # causes an unused local typedef whenever it is used.
-                self.cxx.addCompileFlagIfSupported('-Wno-unused-local-typedef')
+                self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef')
 
     def configure_sanitizer(self):
         san = self.get_lit_conf('use_sanitizer', '').strip()
         if san:
+            self.target_info.add_sanitizer_features(san, self.config.available_features)
             # Search for llvm-symbolizer along the compiler path first
             # and then along the PATH env variable.
             symbolizer_search_paths = os.environ.get('PATH', '')
@@ -600,8 +570,6 @@
                                              symbolizer_search_paths)
             # Setup the sanitizer compile flags
             self.cxx.flags += ['-g', '-fno-omit-frame-pointer']
-            if self.target_info.platform() == 'linux':
-                self.cxx.link_flags += ['-ldl']
             if san == 'Address':
                 self.cxx.flags += ['-fsanitize=address']
                 if llvm_symbolizer is not None:
@@ -622,9 +590,8 @@
                                    '-fno-sanitize=vptr,function',
                                    '-fno-sanitize-recover']
                 self.cxx.compile_flags += ['-O3']
+                self.env['UBSAN_OPTIONS'] = 'print_stacktrace=1'
                 self.config.available_features.add('ubsan')
-                if self.target_info.platform() == 'darwin':
-                    self.config.available_features.add('sanitizer-new-delete')
             elif san == 'Thread':
                 self.cxx.flags += ['-fsanitize=thread']
                 self.config.available_features.add('tsan')
@@ -671,7 +638,7 @@
         for k, v in self.env.items():
             exec_env_str += ' %s=%s' % (k, v)
         # Configure run env substitution.
-        exec_str = ''
+        exec_str = exec_env_str
         if self.lit_config.useValgrind:
             exec_str = ' '.join(self.lit_config.valgrindArgs) + exec_env_str
         sub.append(('%exec', exec_str))
@@ -708,18 +675,4 @@
                 "inferred target_triple as: %r" % self.config.target_triple)
 
     def configure_env(self):
-        if self.target_info.platform() == 'darwin':
-            library_paths = []
-            # Configure the library path for libc++
-            libcxx_library = self.get_lit_conf('libcxx_library')
-            if self.use_system_cxx_lib:
-                pass
-            elif libcxx_library:
-                library_paths += [os.path.dirname(libcxx_library)]
-            elif self.cxx_library_root:
-                library_paths += [self.cxx_library_root]
-            # Configure the abi library path
-            if self.abi_library_root:
-                library_paths += [self.abi_library_root]
-            if library_paths:
-                self.env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths)
+        self.target_info.configure_env(self.env)
diff --git a/test/libcxx/test/executor.py b/test/libcxx/test/executor.py
index f0356ce..ee4288f 100644
--- a/test/libcxx/test/executor.py
+++ b/test/libcxx/test/executor.py
@@ -1,3 +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.
+#
+#===----------------------------------------------------------------------===##
+
 import os
 
 from libcxx.test import tracing
diff --git a/test/libcxx/test/format.py b/test/libcxx/test/format.py
index 238dcdb..865869a 100644
--- a/test/libcxx/test/format.py
+++ b/test/libcxx/test/format.py
@@ -1,3 +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.
+#
+#===----------------------------------------------------------------------===##
+
 import errno
 import os
 import time
@@ -64,20 +73,24 @@
             return (lit.Test.UNSUPPORTED,
                     "A lit.local.cfg marked this unsupported")
 
-        res = lit.TestRunner.parseIntegratedTestScript(
+        script = lit.TestRunner.parseIntegratedTestScript(
             test, require_script=is_sh_test)
         # Check if a result for the test was returned. If so return that
         # result.
-        if isinstance(res, lit.Test.Result):
-            return res
+        if isinstance(script, lit.Test.Result):
+            return script
         if lit_config.noExecute:
             return lit.Test.Result(lit.Test.PASS)
-        # res is not an instance of lit.test.Result. Expand res into its parts.
-        script, tmpBase, execDir = res
+
         # Check that we don't have run lines on tests that don't support them.
         if not is_sh_test and len(script) != 0:
             lit_config.fatal('Unsupported RUN line found in test %s' % name)
 
+        tmpDir, tmpBase = lit.TestRunner.getTempPaths(test)
+        substitutions = lit.TestRunner.getDefaultSubstitutions(test, tmpDir,
+                                                               tmpBase)
+        script = lit.TestRunner.applySubstitutions(script, substitutions)
+
         # Dispatch the test based on its suffix.
         if is_sh_test:
             if not isinstance(self.executor, LocalExecutor):
@@ -86,11 +99,11 @@
                 return lit.Test.UNSUPPORTED, 'ShTest format not yet supported'
             return lit.TestRunner._runShTest(test, lit_config,
                                              self.execute_external, script,
-                                             tmpBase, execDir)
+                                             tmpBase)
         elif is_fail_test:
             return self._evaluate_fail_test(test)
         elif is_pass_test:
-            return self._evaluate_pass_test(test, tmpBase, execDir, lit_config)
+            return self._evaluate_pass_test(test, tmpBase, lit_config)
         else:
             # No other test type is supported
             assert False
@@ -98,7 +111,8 @@
     def _clean(self, exec_path):  # pylint: disable=no-self-use
         libcxx.util.cleanFile(exec_path)
 
-    def _evaluate_pass_test(self, test, tmpBase, execDir, lit_config):
+    def _evaluate_pass_test(self, test, tmpBase, lit_config):
+        execDir = os.path.dirname(test.getExecPath())
         source_path = test.getSourcePath()
         exec_path = tmpBase + '.exe'
         object_path = tmpBase + '.o'
@@ -147,7 +161,13 @@
                        'expected-error', 'expected-no-diagnostics']
         use_verify = self.use_verify_for_fail and \
                      any([tag in contents for tag in verify_tags])
+        # 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']
diff --git a/test/libcxx/test/target_info.py b/test/libcxx/test/target_info.py
index a617377..a743595 100644
--- a/test/libcxx/test/target_info.py
+++ b/test/libcxx/test/target_info.py
@@ -1,55 +1,223 @@
+#===----------------------------------------------------------------------===//
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is dual licensed under the MIT and the University of Illinois Open
+# Source Licenses. See LICENSE.TXT for details.
+#
+#===----------------------------------------------------------------------===//
+
+import importlib
+import lit.util  # pylint: disable=import-error,no-name-in-module
 import locale
+import os
 import platform
 import sys
 
-class TargetInfo(object):
+class DefaultTargetInfo(object):
+    def __init__(self, full_config):
+        self.full_config = full_config
+
     def platform(self):
-        raise NotImplementedError
+        return sys.platform.lower().strip()
 
-    def system(self):
-        raise NotImplementedError
+    def add_locale_features(self, features):
+        self.full_config.lit_config.warning(
+            "No locales entry for target_system: %s" % self.platform())
 
-    def platform_ver(self):
-        raise NotImplementedError
-
-    def platform_name(self):
-        raise NotImplementedError
-
-    def supports_locale(self, loc):
-        raise NotImplementedError
+    def add_cxx_compile_flags(self, flags): pass
+    def add_cxx_link_flags(self, flags): pass
+    def configure_env(self, env): pass
+    def allow_cxxabi_link(self): return True
+    def add_sanitizer_features(self, sanitizer_type, features): pass
+    def use_lit_shell_default(self): return False
 
 
-class LocalTI(TargetInfo):
-    def platform(self):
-        platform_name = sys.platform.lower().strip()
-        # Strip the '2' from linux2.
-        if platform_name.startswith('linux'):
-            platform_name = 'linux'
-        return platform_name
+def test_locale(loc):
+    assert loc is not None
+    default_locale = locale.setlocale(locale.LC_ALL)
+    try:
+        locale.setlocale(locale.LC_ALL, loc)
+        return True
+    except locale.Error:
+        return False
+    finally:
+        locale.setlocale(locale.LC_ALL, default_locale)
 
-    def system(self):
-        return platform.system()
 
-    def platform_name(self):
-        if self.platform() == 'linux':
-            name, _, _ = platform.linux_distribution()
-            name = name.lower().strip()
-            if name:
-                return name
-        return None
+def add_common_locales(features, lit_config):
+    # A list of locales needed by the test-suite.
+    # The list uses the canonical name for the locale used in the test-suite
+    # TODO: On Linux ISO8859 *may* needs to hyphenated.
+    locales = [
+        'en_US.UTF-8',
+        'fr_FR.UTF-8',
+        'ru_RU.UTF-8',
+        'zh_CN.UTF-8',
+        'fr_CA.ISO8859-1',
+        'cs_CZ.ISO8859-2'
+    ]
+    for loc in locales:
+        if test_locale(loc):
+            features.add('locale.{0}'.format(loc))
+        else:
+            lit_config.warning('The locale {0} is not supported by '
+                               'your platform. Some tests will be '
+                               'unsupported.'.format(loc))
 
-    def platform_ver(self):
-        if self.platform() == 'linux':
-            _, ver, _ = platform.linux_distribution()
-            ver = ver.lower().strip()
-            if ver:
-                return ver
-        return None
 
-    def supports_locale(self, loc):
+class DarwinLocalTI(DefaultTargetInfo):
+    def __init__(self, full_config):
+        super(DarwinLocalTI, self).__init__(full_config)
+
+    def add_locale_features(self, features):
+        add_common_locales(features, self.full_config.lit_config)
+
+    def add_cxx_compile_flags(self, flags):
         try:
-            locale.setlocale(locale.LC_ALL, loc)
+            out = lit.util.capture(['xcrun', '--show-sdk-path']).strip()
+            res = 0
+        except OSError:
+            res = -1
+        if res == 0 and out:
+            sdk_path = out
+            self.full_config.lit_config.note('using SDKROOT: %r' % sdk_path)
+            flags += ["-isysroot", sdk_path]
+
+    def add_cxx_link_flags(self, flags):
+        flags += ['-lSystem']
+
+    def configure_env(self, env):
+        library_paths = []
+        # Configure the library path for libc++
+        if self.full_config.use_system_cxx_lib:
+            pass
+        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]
+        if library_paths:
+            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
-        except locale.Error:
-            return False
+        # Don't link libc++abi explicitly on OS X because the symbols
+        # should be available in libc++ directly.
+        return False
+
+    def add_sanitizer_features(self, sanitizer_type, features):
+        if san == 'Undefined':
+            features.add('sanitizer-new-delete')
+
+
+class FreeBSDLocalTI(DefaultTargetInfo):
+    def __init__(self, full_config):
+        super(FreeBSDLocalTI, self).__init__(full_config)
+
+    def add_locale_features(self, features):
+        add_common_locales(features, self.full_config.lit_config)
+
+    def add_cxx_link_flags(self, flags):
+        flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
+
+
+class LinuxLocalTI(DefaultTargetInfo):
+    def __init__(self, full_config):
+        super(LinuxLocalTI, self).__init__(full_config)
+
+    def platform(self):
+        return 'linux'
+
+    def platform_name(self):
+        name, _, _ = platform.linux_distribution()
+        name = name.lower().strip()
+        return name # Permitted to be None
+
+    def platform_ver(self):
+        _, ver, _ = platform.linux_distribution()
+        ver = ver.lower().strip()
+        return ver # Permitted to be None.
+
+    def add_locale_features(self, features):
+        add_common_locales(features, self.full_config.lit_config)
+        # Some linux distributions have different locale data than others.
+        # Insert the distributions name and name-version into the available
+        # features to allow tests to XFAIL on them.
+        name = self.platform_name()
+        ver = self.platform_ver()
+        if name:
+            features.add(name)
+        if name and ver:
+            features.add('%s-%s' % (name, ver))
+
+    def add_cxx_compile_flags(self, flags):
+        flags += ['-D__STDC_FORMAT_MACROS',
+                  '-D__STDC_LIMIT_MACROS',
+                  '-D__STDC_CONSTANT_MACROS']
+
+    def add_cxx_link_flags(self, flags):
+        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
+            # linkSanitizerRuntimeDeps function in
+            # clang/lib/Driver/Tools.cpp
+            flags += ['-lpthread', '-lrt', '-lm', '-ldl']
+
+
+class WindowsLocalTI(DefaultTargetInfo):
+    def __init__(self, full_config):
+        super(WindowsLocalTI, self).__init__(full_config)
+
+    def add_locale_features(self, features):
+        add_common_locales(features, self.full_config.lit_config)
+
+    def use_lit_shell_default(self):
+        # Default to the internal shell on Windows, as bash on Windows is
+        # usually very slow.
+        return True
+
+
+def make_target_info(full_config):
+    default = "libcxx.test.target_info.LocalTI"
+    info_str = full_config.get_lit_conf('target_info', default)
+    if info_str != default:
+        mod_path, _, info = info_str.rpartition('.')
+        mod = importlib.import_module(mod_path)
+        target_info = getattr(mod, info)(full_config)
+        full_config.lit_config.note("inferred target_info as: %r" % info_str)
+        return target_info
+    target_system = platform.system()
+    if target_system == 'Darwin':  return DarwinLocalTI(full_config)
+    if target_system == 'FreeBSD': return FreeBSDLocalTI(full_config)
+    if target_system == 'Linux':   return LinuxLocalTI(full_config)
+    if target_system == 'Windows': return WindowsLocalTI(full_config)
+    return DefaultTargetInfo(full_config)
 
diff --git a/test/libcxx/test/tracing.py b/test/libcxx/test/tracing.py
index efef158..c590ba3 100644
--- a/test/libcxx/test/tracing.py
+++ b/test/libcxx/test/tracing.py
@@ -1,3 +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.
+#
+#===----------------------------------------------------------------------===##
+
 import os
 import inspect
 
@@ -11,14 +20,14 @@
         # Perform the call itself, logging before, after, and anything thrown.
         try:
             if log_calls:
-                print '{}: Calling {}'.format(label, call_str)
+                print('{}: Calling {}'.format(label, call_str))
             res = function(*args, **kwargs)
             if log_results:
-                print '{}: {} -> {}'.format(label, call_str, res)
+                print('{}: {} -> {}'.format(label, call_str, res))
             return res
         except Exception as ex:
             if log_results:
-                print '{}: {} raised {}'.format(label, call_str, type(ex))
+                print('{}: {} raised {}'.format(label, call_str, type(ex)))
             raise ex
 
     return wrapper
diff --git a/test/std/thread/futures/version.pass.cpp b/test/libcxx/thread/futures/version.pass.cpp
similarity index 100%
rename from test/std/thread/futures/version.pass.cpp
rename to test/libcxx/thread/futures/version.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 0000000..d9ac92c
--- /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 0000000..4e85a03
--- /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 0000000..40b97c3
--- /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 0000000..c1425c9
--- /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 0000000..e03f5ea
--- /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/libcxx/type_traits/convert_to_integral.pass.cpp b/test/libcxx/type_traits/convert_to_integral.pass.cpp
index b97832b..3fdc98f 100644
--- a/test/libcxx/type_traits/convert_to_integral.pass.cpp
+++ b/test/libcxx/type_traits/convert_to_integral.pass.cpp
@@ -1,7 +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.
+//
+//===----------------------------------------------------------------------===//
+//
 // TODO: Make this test pass for all standards.
 // XFAIL: c++98, c++03
 
+// <type_traits>
+
+// __convert_to_integral(Tp)
+
+// Test that the __convert_to_integral functions properly converts Tp to the
+// correct type and value for integral, enum and user defined types.
+
 #include <limits>
 #include <type_traits>
 #include <cstdint>
diff --git a/test/libcxx/type_traits/lazy_metafunctions.pass.cpp b/test/libcxx/type_traits/lazy_metafunctions.pass.cpp
new file mode 100644
index 0000000..8f75080
--- /dev/null
+++ b/test/libcxx/type_traits/lazy_metafunctions.pass.cpp
@@ -0,0 +1,137 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler 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
+
+// <type_traits>
+
+// __lazy_enable_if, __lazy_not, __lazy_and and __lazy_or
+
+// Test the libc++ lazy meta-programming helpers in <type_traits>
+
+#include <type_traits>
+
+template <class Type>
+struct Identity {
+    typedef Type type;
+};
+
+typedef std::true_type TrueT;
+typedef std::false_type FalseT;
+
+typedef Identity<TrueT>  LazyTrueT;
+typedef Identity<FalseT> LazyFalseT;
+
+// A type that cannot be instantiated
+template <class T>
+struct CannotInst {
+    typedef T type;
+    static_assert(std::is_same<T, T>::value == false, "");
+};
+
+
+template <int Value>
+struct NextInt {
+    typedef NextInt<Value + 1> type;
+    static const int value = Value;
+};
+
+template <int Value>
+const int NextInt<Value>::value;
+
+
+template <class Type>
+struct HasTypeImp {
+    template <class Up, class = typename Up::type>
+    static TrueT test(int);
+    template <class>
+    static FalseT test(...);
+
+    typedef decltype(test<Type>(0)) type;
+};
+
+// A metafunction that returns True if Type has a nested 'type' typedef
+// and false otherwise.
+template <class Type>
+struct HasType : HasTypeImp<Type>::type {};
+
+void LazyEnableIfTest() {
+    {
+        typedef std::__lazy_enable_if<true, NextInt<0> > Result;
+        static_assert(HasType<Result>::value, "");
+        static_assert(Result::type::value == 1, "");
+    }
+    {
+        typedef std::__lazy_enable_if<false, CannotInst<int> > Result;
+        static_assert(!HasType<Result>::value, "");
+    }
+}
+
+void LazyNotTest() {
+    {
+        typedef std::__lazy_not<LazyTrueT> NotT;
+        static_assert(std::is_same<typename NotT::type, FalseT>::value, "");
+        static_assert(NotT::value == false, "");
+    }
+    {
+        typedef std::__lazy_not<LazyFalseT> NotT;
+        static_assert(std::is_same<typename NotT::type, TrueT>::value, "");
+        static_assert(NotT::value == true, "");
+    }
+    {
+         // Check that CannotInst<int> is not instantiated.
+        typedef std::__lazy_not<CannotInst<int> > NotT;
+
+        static_assert(std::is_same<NotT, NotT>::value, "");
+
+    }
+}
+
+void LazyAndTest() {
+    { // Test that it acts as the identity function for a single value
+        static_assert(std::__lazy_and<LazyFalseT>::value == false, "");
+        static_assert(std::__lazy_and<LazyTrueT>::value == true, "");
+    }
+    {
+        static_assert(std::__lazy_and<LazyTrueT, LazyTrueT>::value == true, "");
+        static_assert(std::__lazy_and<LazyTrueT, LazyFalseT>::value == false, "");
+        static_assert(std::__lazy_and<LazyFalseT, LazyTrueT>::value == false, "");
+        static_assert(std::__lazy_and<LazyFalseT, LazyFalseT>::value == false, "");
+    }
+    { // Test short circuiting - CannotInst<T> should never be instantiated.
+        static_assert(std::__lazy_and<LazyFalseT, CannotInst<int>>::value == false, "");
+        static_assert(std::__lazy_and<LazyTrueT, LazyFalseT, CannotInst<int>>::value == false, "");
+    }
+}
+
+
+void LazyOrTest() {
+    { // Test that it acts as the identity function for a single value
+        static_assert(std::__lazy_or<LazyFalseT>::value == false, "");
+        static_assert(std::__lazy_or<LazyTrueT>::value == true, "");
+    }
+    {
+        static_assert(std::__lazy_or<LazyTrueT, LazyTrueT>::value == true, "");
+        static_assert(std::__lazy_or<LazyTrueT, LazyFalseT>::value == true, "");
+        static_assert(std::__lazy_or<LazyFalseT, LazyTrueT>::value == true, "");
+        static_assert(std::__lazy_or<LazyFalseT, LazyFalseT>::value == false, "");
+    }
+    { // Test short circuiting - CannotInst<T> should never be instantiated.
+        static_assert(std::__lazy_or<LazyTrueT, CannotInst<int>>::value == true, "");
+        static_assert(std::__lazy_or<LazyFalseT, LazyTrueT, CannotInst<int>>::value == true, "");
+    }
+}
+
+
+int main() {
+    LazyEnableIfTest();
+    LazyNotTest();
+    LazyAndTest();
+    LazyOrTest();
+}
\ No newline at end of file
diff --git a/test/libcxx/util.py b/test/libcxx/util.py
index 28f2619..8899ffa 100644
--- a/test/libcxx/util.py
+++ b/test/libcxx/util.py
@@ -1,3 +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.
+#
+#===----------------------------------------------------------------------===##
+
 from contextlib import contextmanager
 import os
 import tempfile
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
similarity index 85%
rename from test/std/utilities/function.objects/func.require/bullet_1_and_2.pass.cpp
rename to test/libcxx/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp
index e579f20..509c751 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 @@
 #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 @@
         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 @@
         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 @@
 
     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 @@
 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 @@
     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
similarity index 60%
rename from test/std/utilities/function.objects/func.require/bullet_3_and_4.pass.cpp
rename to test/libcxx/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp
index b6fe190..803c501 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 @@
         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 @@
             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 @@
             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 @@
             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 @@
             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 @@
     }
 
     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 @@
     }
 
     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
similarity index 98%
rename from test/std/utilities/function.objects/func.require/bullet_5.pass.cpp
rename to test/libcxx/utilities/function.objects/func.require/bullet_7.pass.cpp
index 3f3c96a..0d14a35 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
similarity index 87%
rename from test/std/utilities/function.objects/func.require/invoke.pass.cpp
rename to test/libcxx/utilities/function.objects/func.require/invoke.pass.cpp
index 2568163..1d42513 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 @@
 {
     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 @@
 {
     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/libcxx/utilities/function.objects/func.require/invoke_helpers.h b/test/libcxx/utilities/function.objects/func.require/invoke_helpers.h
new file mode 100644
index 0000000..7e7a5fd
--- /dev/null
+++ b/test/libcxx/utilities/function.objects/func.require/invoke_helpers.h
@@ -0,0 +1,456 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The 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 INVOKE_HELPERS_H
+#define INVOKE_HELPERS_H
+
+#include <type_traits>
+#include <cassert>
+#include <functional>
+
+#include "test_macros.h"
+
+template <int I>
+struct Int : public std::integral_constant<int, I> {};
+
+template <bool P>
+struct Bool : public std::integral_constant<bool, P> {};
+
+struct Q_None {
+    template <class T>
+    struct apply { typedef T type; };
+};
+
+struct Q_Const {
+    template <class T>
+    struct apply { typedef T const type; };
+};
+
+struct Q_Volatile {
+    template <class T>
+    struct apply { typedef T volatile type; };
+};
+
+struct Q_CV {
+    template <class T>
+    struct apply { typedef T const volatile type; };
+};
+
+// Caster - A functor object that performs cv-qualifier and value category
+//   conversions.
+//   QualTag - A metafunction type that applies cv-qualifiers to its argument.
+//   RValue - True if the resulting object should be an RValue reference.
+//            False otherwise.
+template <class QualTag, bool RValue = false>
+struct Caster {
+    template <class T>
+    struct apply {
+        typedef typename std::remove_reference<T>::type RawType;
+        typedef typename QualTag::template apply<RawType>::type CVType;
+#if TEST_STD_VER >= 11
+        typedef typename std::conditional<RValue,
+            CVType&&, CVType&
+        >::type type;
+#else
+        typedef CVType& type;
+#endif
+    };
+
+    template <class T>
+    typename apply<T>::type
+    operator()(T& obj) const {
+        typedef typename apply<T>::type OutType;
+        return static_cast<OutType>(obj);
+    }
+};
+
+typedef Caster<Q_None>           LValueCaster;
+typedef Caster<Q_Const>          ConstCaster;
+typedef Caster<Q_Volatile>       VolatileCaster;
+typedef Caster<Q_CV>             CVCaster;
+typedef Caster<Q_None,     true> MoveCaster;
+typedef Caster<Q_Const,    true> MoveConstCaster;
+typedef Caster<Q_Volatile, true> MoveVolatileCaster;
+typedef Caster<Q_CV,       true> MoveCVCaster;
+
+
+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); };
+
+//==============================================================================
+// ArgType - A non-copyable type intended to be used as a dummy argument type
+//   to test functions.
+struct ArgType {
+    int value;
+    explicit ArgType(int val = 0) : value(val) {}
+private:
+    ArgType(ArgType const&);
+    ArgType& operator=(ArgType const&);
+};
+
+//==============================================================================
+// DerivedFromBase - A type that derives from it's template argument 'Base'
+template <class Base>
+struct DerivedFromType : public Base {
+    DerivedFromType() : Base() {}
+    template <class Tp>
+    explicit DerivedFromType(Tp const& t) : Base(t) {}
+};
+
+//==============================================================================
+// DerefToType - A type that dereferences to it's template argument 'To'.
+//   The cv-ref qualifiers of the 'DerefToType' object do not propagate
+//   to the resulting 'To' object.
+template <class To>
+struct DerefToType {
+    To object;
+
+    DerefToType() {}
+
+    template <class Up>
+    explicit DerefToType(Up const& val) : object(val) {}
+
+    To& operator*() const volatile { return const_cast<To&>(object); }
+};
+
+//==============================================================================
+// DerefPropToType - A type that dereferences to it's template argument 'To'.
+//   The cv-ref qualifiers of the 'DerefPropToType' object propagate
+//   to the resulting 'To' object.
+template <class To>
+struct DerefPropType {
+    To object;
+
+    DerefPropType() {}
+
+    template <class Up>
+    explicit DerefPropType(Up const& val) : object(val) {}
+
+#if TEST_STD_VER < 11
+    To& operator*() { return object; }
+    To const& operator*() const { return object; }
+    To volatile& operator*() volatile  { return object; }
+    To const volatile& operator*() const volatile { return object; }
+#else
+    To& operator*() & { return object; }
+    To const& operator*() const & { return object; }
+    To volatile& operator*() volatile  & { return object; }
+    To const volatile& operator*() const volatile & { return object; }
+    To&& operator*() && { return static_cast<To &&>(object); }
+    To const&& operator*() const && { return static_cast<To const&&>(object); }
+    To volatile&& operator*() volatile  && { return static_cast<To volatile&&>(object); }
+    To const volatile&& operator*() const volatile && { return static_cast<To const volatile&&>(object); }
+#endif
+};
+
+//==============================================================================
+// MethodID - A type that uniquely identifies a member function for a class.
+//   This type is used to communicate between the member functions being tested
+//   and the tests invoking them.
+// - Test methods should call 'setUncheckedCall()' whenever they are invoked.
+// - Tests consume the unchecked call using checkCall(<return-value>)` to assert
+//   that the method has been called and that the return value of `__invoke`
+//   matches what the method actually returned.
+template <class T>
+struct MethodID {
+    typedef void* IDType;
+
+    static int dummy; // A dummy memory location.
+    static void* id; // The "ID" is the value of this pointer.
+    static bool unchecked_call; // Has a call happened that has not been checked.
+
+    static void*& setUncheckedCall() {
+        assert(unchecked_call == false);
+        unchecked_call = true;
+        return id;
+    }
+
+    static bool checkCalled(void*& return_value) {
+        bool old = unchecked_call;
+        unchecked_call = false;
+        return old && id == return_value && &id == &return_value;
+    }
+};
+
+template <class T> int   MethodID<T>::dummy = 0;
+template <class T> void* MethodID<T>::id = (void*)&MethodID<T>::dummy;
+template <class T> bool  MethodID<T>::unchecked_call = false;
+
+
+//==============================================================================
+// FunctionPtrID - Like MethodID but for free function pointers.
+template <class T, T*>
+struct FunctionPtrID {
+    static int dummy; // A dummy memory location.
+    static void* id; // The "ID" is the value of this pointer.
+    static bool unchecked_call; // Has a call happened that has not been checked.
+
+    static void*& setUncheckedCall() {
+        assert(unchecked_call == false);
+        unchecked_call = true;
+        return id;
+    }
+
+    static bool checkCalled(void*& return_value) {
+        bool old = unchecked_call;
+        unchecked_call = false;
+        return old && id == return_value && &id == &return_value;
+    }
+};
+
+template <class T, T* Ptr> int   FunctionPtrID<T, Ptr>::dummy = 0;
+template <class T, T* Ptr> void* FunctionPtrID<T, Ptr>::id = (void*)&FunctionPtrID<T, Ptr>::dummy;
+template <class T, T* Ptr> bool  FunctionPtrID<T, Ptr>::unchecked_call = false;
+
+//==============================================================================
+// BasicTest - The basic test structure for everything except
+// member object pointers.
+// ID - The "Function Identifier" type used either MethodID or FunctionPtrID.
+// Arity - The Arity of the call signature.
+// ObjectCaster - The object transformation functor type.
+// ArgCaster - The extra argument transformation functor type.
+template <class ID, int Arity, class ObjectCaster = LValueCaster,
+                               class ArgCaster    = LValueCaster>
+struct BasicTest {
+    template <class ObjectT>
+    void runTest(ObjectT& object) {
+        Int<Arity> A;
+        runTestImp(A, object);
+    }
+
+    template <class MethodPtr, class ObjectT>
+    void runTest(MethodPtr ptr, ObjectT& object) {
+        Int<Arity> A;
+        runTestImp(A, ptr, object);
+    }
+
+private:
+    typedef void*& CallRet;
+    ObjectCaster object_cast;
+    ArgCaster arg_cast;
+    ArgType a0, a1, a2;
+
+    //==========================================================================
+    //                       BULLET 1, 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));
+        }
+#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));
+        }
+#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));
+        }
+#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));
+        }
+#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 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));
+        }
+#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));
+        }
+#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));
+        }
+#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));
+        }
+#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
+    }
+};
+
+#endif // INVOKE_HELPERS_H
diff --git a/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp b/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp
index 25dd311..fce8443 100644
--- a/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp
+++ b/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp
@@ -87,7 +87,8 @@
   }
   {
     // Test with in-place shared_count.
-    Ptr p = std::make_shared<int>(42);
+    int val = 42;
+    Ptr p = std::make_shared<int>(val);
     run_test(p);
     assert(p.use_count() == 1);
   }
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 0000000..1746de3
--- /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
similarity index 100%
rename from test/std/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp
rename to test/libcxx/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp
diff --git a/test/std/utilities/date.time/asctime.thread-unsafe.fail.cpp b/test/libcxx/utilities/time/date.time/asctime.thread-unsafe.fail.cpp
similarity index 100%
rename from test/std/utilities/date.time/asctime.thread-unsafe.fail.cpp
rename to test/libcxx/utilities/time/date.time/asctime.thread-unsafe.fail.cpp
diff --git a/test/std/utilities/date.time/ctime.thread-unsafe.fail.cpp b/test/libcxx/utilities/time/date.time/ctime.thread-unsafe.fail.cpp
similarity index 100%
rename from test/std/utilities/date.time/ctime.thread-unsafe.fail.cpp
rename to test/libcxx/utilities/time/date.time/ctime.thread-unsafe.fail.cpp
diff --git a/test/std/utilities/date.time/gmtime.thread-unsafe.fail.cpp b/test/libcxx/utilities/time/date.time/gmtime.thread-unsafe.fail.cpp
similarity index 100%
rename from test/std/utilities/date.time/gmtime.thread-unsafe.fail.cpp
rename to test/libcxx/utilities/time/date.time/gmtime.thread-unsafe.fail.cpp
diff --git a/test/std/utilities/date.time/localtime.thread-unsafe.fail.cpp b/test/libcxx/utilities/time/date.time/localtime.thread-unsafe.fail.cpp
similarity index 100%
rename from test/std/utilities/date.time/localtime.thread-unsafe.fail.cpp
rename to test/libcxx/utilities/time/date.time/localtime.thread-unsafe.fail.cpp
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in
index 765ee7c..e2febcb 100644
--- a/test/lit.site.cfg.in
+++ b/test/lit.site.cfg.in
@@ -1,18 +1,14 @@
 @AUTO_GEN_COMMENT@
 config.cxx_under_test           = "@LIBCXX_COMPILER@"
+config.project_obj_root         = "@CMAKE_BINARY_DIR@"
 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_rtti              = "@LIBCXX_ENABLE_RTTI@"
 config.enable_shared            = "@LIBCXX_ENABLE_SHARED@"
 config.enable_32bit             = "@LIBCXX_BUILD_32_BITS@"
-config.enable_global_filesystem_namespace = "@LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE@"
-config.enable_stdin             = "@LIBCXX_ENABLE_STDIN@"
-config.enable_stdout            = "@LIBCXX_ENABLE_STDOUT@"
-config.enable_threads           = "@LIBCXX_ENABLE_THREADS@"
-config.enable_thread_unsafe_c_functions = "@LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS@"
-config.enable_monotonic_clock   = "@LIBCXX_ENABLE_MONOTONIC_CLOCK@"
 config.cxx_abi                  = "@LIBCXX_CXX_ABI_LIBNAME@"
 config.use_sanitizer            = "@LLVM_USE_SANITIZER@"
 config.sanitizer_library        = "@LIBCXX_SANITIZER_LIBRARY@"
@@ -25,6 +21,8 @@
 config.target_info              = "@LIBCXX_TARGET_INFO@"
 config.executor                 = "@LIBCXX_EXECUTOR@"
 config.llvm_unwinder            = "@LIBCXXABI_USE_LLVM_UNWINDER@"
+config.use_libatomic            = "@LIBCXX_HAS_ATOMIC_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.sorting/alg.clamp/clamp.comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.clamp/clamp.comp.pass.cpp
new file mode 100644
index 0000000..e0d8127
--- /dev/null
+++ b/test/std/algorithms/alg.sorting/alg.clamp/clamp.comp.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+// XFAIL: 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>
+
+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 _LIBCPP_STD_VER > 11
+    {
+    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, "" );
+    }
+#endif
+}
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 0000000..838aaed
--- /dev/null
+++ b/test/std/algorithms/alg.sorting/alg.clamp/clamp.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+// XFAIL: 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>
+
+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 _LIBCPP_STD_VER > 11
+    {
+    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, "" );
+    }
+#endif
+}
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 a66b2ff..789ccef 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_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort_comp.pass.cpp
index d822f6c..4b7c5ee 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
@@ -62,6 +62,7 @@
 
 int main()
 {
+    {
     int i = 0;
     std::partial_sort(&i, &i, &i);
     assert(i == 0);
@@ -73,6 +74,7 @@
     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 8a60f81..64093d6 100644
--- a/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp
+++ b/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp
@@ -22,13 +22,13 @@
 int main()
 {
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f;
         f.test_and_set();
         atomic_flag_clear(&f);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f;
         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 92e57ec..e1a9349 100644
--- a/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
+++ b/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
@@ -22,37 +22,37 @@
 int main()
 {
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f;
         f.test_and_set();
         atomic_flag_clear_explicit(&f, std::memory_order_relaxed);
         assert(f.test_and_set() == 0);
     }
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f;
         f.test_and_set();
         atomic_flag_clear_explicit(&f, std::memory_order_release);
         assert(f.test_and_set() == 0);
     }
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f;
         f.test_and_set();
         atomic_flag_clear_explicit(&f, std::memory_order_seq_cst);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f;
         f.test_and_set();
         atomic_flag_clear_explicit(&f, std::memory_order_relaxed);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f;
         f.test_and_set();
         atomic_flag_clear_explicit(&f, std::memory_order_release);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f;
         f.test_and_set();
         atomic_flag_clear_explicit(&f, std::memory_order_seq_cst);
         assert(f.test_and_set() == 0);
diff --git a/test/std/atomics/atomics.flag/clear.pass.cpp b/test/std/atomics/atomics.flag/clear.pass.cpp
index 7c93626..65051af 100644
--- a/test/std/atomics/atomics.flag/clear.pass.cpp
+++ b/test/std/atomics/atomics.flag/clear.pass.cpp
@@ -22,49 +22,49 @@
 int main()
 {
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f;
         f.test_and_set();
         f.clear();
         assert(f.test_and_set() == 0);
     }
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f;
         f.test_and_set();
         f.clear(std::memory_order_relaxed);
         assert(f.test_and_set() == 0);
     }
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f;
         f.test_and_set();
         f.clear(std::memory_order_release);
         assert(f.test_and_set() == 0);
     }
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f;
         f.test_and_set();
         f.clear(std::memory_order_seq_cst);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f;
         f.test_and_set();
         f.clear();
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f;
         f.test_and_set();
         f.clear(std::memory_order_relaxed);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f;
         f.test_and_set();
         f.clear(std::memory_order_release);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f;
         f.test_and_set();
         f.clear(std::memory_order_seq_cst);
         assert(f.test_and_set() == 0);
diff --git a/test/std/atomics/atomics.flag/init.pass.cpp b/test/std/atomics/atomics.flag/init.pass.cpp
index c90509d..c4a121b 100644
--- a/test/std/atomics/atomics.flag/init.pass.cpp
+++ b/test/std/atomics/atomics.flag/init.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// XFAIL: c++98, c++03
 
 // <atomic>
 
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 0000000..5577a72
--- /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{});
+    CHECK_ALWAYS_LOCK_FREE(struct{ int i; });
+    CHECK_ALWAYS_LOCK_FREE(struct{ int i[2]; });
+    CHECK_ALWAYS_LOCK_FREE(struct{ long long int i[2]; });
+    CHECK_ALWAYS_LOCK_FREE(struct{ long long int i[4]; });
+    CHECK_ALWAYS_LOCK_FREE(struct{ long long int i[8]; });
+    CHECK_ALWAYS_LOCK_FREE(struct{ long long int i[16]; });
+    CHECK_ALWAYS_LOCK_FREE(struct{ char c; /* padding */ long long int i; });
+    CHECK_ALWAYS_LOCK_FREE(union{ 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 a975a69..0ace9cf 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 @@
     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/trivially_copyable.fail.cpp b/test/std/atomics/atomics.types.generic/trivially_copyable.fail.cpp
index f2bf4db..d940980 100644
--- a/test/std/atomics/atomics.types.generic/trivially_copyable.fail.cpp
+++ b/test/std/atomics/atomics.types.generic/trivially_copyable.fail.cpp
@@ -57,12 +57,12 @@
     NotTriviallyCopyable ( int i ) : i_(i) {}
     NotTriviallyCopyable ( const NotTriviallyCopyable &rhs) : i_(rhs.i_) {}
     int i_;
-    };
+};
 
-template <class T>
+template <class T, class >
 void test ( T t ) {
     std::atomic<T> t0(t);
-    }
+}
 
 int main()
 {
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 f1cc993..7b221dc 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
@@ -24,10 +24,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A a;
@@ -52,37 +53,10 @@
         assert(a == T(2));
         assert(t == T(2));
     }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
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 f667ab7..27de5be 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
@@ -27,10 +27,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A a;
@@ -59,37 +60,10 @@
         assert(a == T(2));
         assert(t == T(2));
     }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
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 175c445..8c12715 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
@@ -25,11 +25,11 @@
 #include <cassert>
 
 #include <cmpxchg_loop.h>
+#include "atomic_helpers.h"
 
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A a;
@@ -54,37 +54,10 @@
         assert(a == T(2));
         assert(t == T(2));
     }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
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 46f80bf..90a93f0 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
@@ -29,10 +29,11 @@
 
 #include <cmpxchg_loop.h>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A a;
@@ -61,37 +62,10 @@
         assert(a == T(2));
         assert(t == T(2));
     }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
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 525e74a..035d974 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
@@ -24,10 +24,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_init(&t, T(1));
@@ -37,37 +38,11 @@
     std::atomic_init(&vt, T(3));
     assert(std::atomic_exchange(&vt, T(4)) == T(3));
     assert(vt == T(4));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
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 9fe4ac8..4d66bb5 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
@@ -24,10 +24,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_init(&t, T(1));
@@ -39,37 +40,11 @@
     assert(std::atomic_exchange_explicit(&vt, T(4), std::memory_order_seq_cst)
            == T(3));
     assert(vt == T(4));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
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 3408def..48ff601 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
@@ -32,10 +32,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -50,62 +51,33 @@
         assert(std::atomic_fetch_add(&t, T(2)) == T(1));
         assert(t == T(3));
     }
-}
-
-template <class T>
-void
-testp()
-{
-    {
-        typedef std::atomic<T> A;
-        typedef typename std::remove_pointer<T>::type X;
-        A t;
-        std::atomic_init(&t, T(1*sizeof(X)));
-        assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X)));
-        assert(t == T(3*sizeof(X)));
-    }
-    {
-        typedef std::atomic<T> A;
-        typedef typename std::remove_pointer<T>::type X;
-        volatile A t;
-        std::atomic_init(&t, T(1*sizeof(X)));
-        assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X)));
-        assert(t == T(3*sizeof(X)));
-    }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-    A(const A& a) : i(a.i) {}
-    A(const volatile A& a) : i(a.i) {}
-
-    void operator=(const volatile A& a) volatile {i = a.i;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+template <class T>
+void testp()
+{
+    {
+        typedef std::atomic<T> A;
+        typedef typename std::remove_pointer<T>::type X;
+        A t;
+        std::atomic_init(&t, T(1*sizeof(X)));
+        assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X)));
+        assert(t == T(3*sizeof(X)));
+    }
+    {
+        typedef std::atomic<T> A;
+        typedef typename std::remove_pointer<T>::type X;
+        volatile A t;
+        std::atomic_init(&t, T(1*sizeof(X)));
+        assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X)));
+        assert(t == T(3*sizeof(X)));
+    }
+}
+
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
     testp<int*>();
     testp<const int*>();
 }
diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
index 9977bd4..2dc90c9 100644
--- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
+++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
@@ -32,10 +32,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -52,7 +53,8 @@
                                             std::memory_order_seq_cst) == T(1));
         assert(t == T(3));
     }
-}
+  }
+};
 
 template <class T>
 void
@@ -78,38 +80,9 @@
     }
 }
 
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-    A(const A& a) : i(a.i) {}
-    A(const volatile A& a) : i(a.i) {}
-
-    void operator=(const volatile A& a) volatile {i = a.i;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
-};
-
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
     testp<int*>();
     testp<const int*>();
 }
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 4c7c043..57355d3 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
@@ -23,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -41,24 +42,10 @@
         assert(std::atomic_fetch_and(&t, T(2)) == T(3));
         assert(t == T(2));
     }
-}
+  }
+};
 
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
 }
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 d83bbf2..26ff5f6 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
@@ -23,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -43,24 +44,10 @@
                std::memory_order_seq_cst) == T(3));
         assert(t == T(2));
     }
-}
+  }
+};
 
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
 }
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 acf6d43..ca44fdc 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
@@ -23,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -41,24 +42,10 @@
         assert(std::atomic_fetch_or(&t, T(2)) == T(3));
         assert(t == T(3));
     }
-}
+  }
+};
 
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
 }
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 72685e4..72bbde7 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
@@ -23,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -43,24 +44,10 @@
                std::memory_order_seq_cst) == T(3));
         assert(t == T(3));
     }
-}
+  }
+};
 
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
 }
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 ed8b541..2743040 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
@@ -32,10 +32,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -50,62 +51,33 @@
         assert(std::atomic_fetch_sub(&t, T(2)) == T(3));
         assert(t == T(1));
     }
-}
-
-template <class T>
-void
-testp()
-{
-    {
-        typedef std::atomic<T> A;
-        typedef typename std::remove_pointer<T>::type X;
-        A t;
-        std::atomic_init(&t, T(3*sizeof(X)));
-        assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X)));
-        assert(t == T(1*sizeof(X)));
-    }
-    {
-        typedef std::atomic<T> A;
-        typedef typename std::remove_pointer<T>::type X;
-        volatile A t;
-        std::atomic_init(&t, T(3*sizeof(X)));
-        assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X)));
-        assert(t == T(1*sizeof(X)));
-    }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-    A(const A& a) : i(a.i) {}
-    A(const volatile A& a) : i(a.i) {}
-
-    void operator=(const volatile A& a) volatile {i = a.i;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+template <class T>
+void testp()
+{
+    {
+        typedef std::atomic<T> A;
+        typedef typename std::remove_pointer<T>::type X;
+        A t;
+        std::atomic_init(&t, T(3*sizeof(X)));
+        assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X)));
+        assert(t == T(1*sizeof(X)));
+    }
+    {
+        typedef std::atomic<T> A;
+        typedef typename std::remove_pointer<T>::type X;
+        volatile A t;
+        std::atomic_init(&t, T(3*sizeof(X)));
+        assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X)));
+        assert(t == T(1*sizeof(X)));
+    }
+}
+
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
     testp<int*>();
     testp<const int*>();
 }
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 e6c92ea..6e94c50 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
@@ -33,10 +33,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -53,64 +54,35 @@
                                             std::memory_order_seq_cst) == T(3));
         assert(t == T(1));
     }
-}
-
-template <class T>
-void
-testp()
-{
-    {
-        typedef std::atomic<T> A;
-        typedef typename std::remove_pointer<T>::type X;
-        A t;
-        std::atomic_init(&t, T(3*sizeof(X)));
-        assert(std::atomic_fetch_sub_explicit(&t, 2,
-                                  std::memory_order_seq_cst) == T(3*sizeof(X)));
-        assert(t == T(1*sizeof(X)));
-    }
-    {
-        typedef std::atomic<T> A;
-        typedef typename std::remove_pointer<T>::type X;
-        volatile A t;
-        std::atomic_init(&t, T(3*sizeof(X)));
-        assert(std::atomic_fetch_sub_explicit(&t, 2,
-                                  std::memory_order_seq_cst) == T(3*sizeof(X)));
-        assert(t == T(1*sizeof(X)));
-    }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-    A(const A& a) : i(a.i) {}
-    A(const volatile A& a) : i(a.i) {}
-
-    void operator=(const volatile A& a) volatile {i = a.i;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+template <class T>
+void testp()
+{
+    {
+        typedef std::atomic<T> A;
+        typedef typename std::remove_pointer<T>::type X;
+        A t;
+        std::atomic_init(&t, T(3*sizeof(X)));
+        assert(std::atomic_fetch_sub_explicit(&t, 2,
+                                  std::memory_order_seq_cst) == T(3*sizeof(X)));
+        assert(t == T(1*sizeof(X)));
+    }
+    {
+        typedef std::atomic<T> A;
+        typedef typename std::remove_pointer<T>::type X;
+        volatile A t;
+        std::atomic_init(&t, T(3*sizeof(X)));
+        assert(std::atomic_fetch_sub_explicit(&t, 2,
+                                  std::memory_order_seq_cst) == T(3*sizeof(X)));
+        assert(t == T(1*sizeof(X)));
+    }
+}
+
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
     testp<int*>();
     testp<const int*>();
 }
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 fc6b97b..42d57de 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
@@ -23,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -41,24 +42,10 @@
         assert(std::atomic_fetch_xor(&t, T(2)) == T(3));
         assert(t == T(1));
     }
-}
+  }
+};
 
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
 }
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 58772aa..8f388fe 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
@@ -23,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -43,24 +44,10 @@
                std::memory_order_seq_cst) == T(3));
         assert(t == T(1));
     }
-}
+  }
+};
 
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
 }
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
new file mode 100644
index 0000000..6cbc0c3
--- /dev/null
+++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ATOMIC_HELPERS_H
+#define ATOMIC_HELPERS_H
+
+#include <cassert>
+
+#include "test_macros.h"
+
+struct UserAtomicType
+{
+    int i;
+
+    explicit UserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {}
+
+    friend bool operator==(const UserAtomicType& x, const UserAtomicType& y)
+    { return x.i == y.i; }
+};
+
+template < template <class TestArg> class TestFunctor > 
+struct TestEachIntegralType {
+    void operator()() const {
+        TestFunctor<char>()(); 
+        TestFunctor<signed char>()();
+        TestFunctor<unsigned char>()();
+        TestFunctor<short>()();
+        TestFunctor<unsigned short>()();
+        TestFunctor<int>()();
+        TestFunctor<unsigned int>()();
+        TestFunctor<long>()();
+        TestFunctor<unsigned long>()();
+        TestFunctor<long long>()();
+        TestFunctor<unsigned long long>()();
+        TestFunctor<wchar_t>();
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+        TestFunctor<char16_t>()();
+        TestFunctor<char32_t>()();
+#endif
+    }
+};
+
+template < template <class TestArg> class TestFunctor > 
+struct TestEachAtomicType {
+    void operator()() const {
+        TestEachIntegralType<TestFunctor>()();
+        TestFunctor<UserAtomicType>()();
+        TestFunctor<int*>()();
+        TestFunctor<const int*>()();
+    }
+};
+
+
+#endif // ATOMIC_HELPER_H
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 137b6f6..884c02d 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
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
-//  ... assertion fails line 34
+//  ... assertion fails line 36
 
 // <atomic>
 
@@ -24,10 +24,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_init(&t, T(1));
@@ -35,37 +36,10 @@
     volatile A vt;
     std::atomic_init(&vt, T(2));
     assert(vt == T(2));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
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 ee22912..5d50016 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
@@ -22,17 +22,19 @@
 #include <atomic>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     bool b1 = std::atomic_is_lock_free(static_cast<const A*>(&t));
     volatile A vt;
     bool b2 = std::atomic_is_lock_free(static_cast<const volatile A*>(&vt));
     assert(b1 == b2);
-}
+  }
+};
 
 struct A
 {
@@ -41,23 +43,6 @@
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestFn<A>()();
+    TestEachAtomicType<TestFn>()();
 }
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 66918c7..e7b8e64 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
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
-//  ... assertion fails line 34
+//  ... assertion fails line 35
 
 // <atomic>
 
@@ -24,10 +24,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_init(&t, T(1));
@@ -35,37 +36,10 @@
     volatile A vt;
     std::atomic_init(&vt, T(2));
     assert(std::atomic_load(&vt) == T(2));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
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 5f402a9..56533fa 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
@@ -24,10 +24,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_init(&t, T(1));
@@ -35,37 +36,10 @@
     volatile A vt;
     std::atomic_init(&vt, T(2));
     assert(std::atomic_load_explicit(&vt, std::memory_order_seq_cst) == T(2));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
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 2b9582b..e61dae9 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
@@ -8,7 +8,6 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
-//  ... assertion fails line 31
 
 // <atomic>
 
@@ -24,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_store(&t, T(1));
@@ -35,37 +35,11 @@
     volatile A vt;
     std::atomic_store(&vt, T(2));
     assert(vt == T(2));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
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 8fe0c7d..e57cf8b 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
@@ -8,7 +8,6 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
-//  ... assertion fails line 31
 
 // <atomic>
 
@@ -24,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_store_explicit(&t, T(1), std::memory_order_seq_cst);
@@ -35,37 +35,11 @@
     volatile A vt;
     std::atomic_store_explicit(&vt, T(2), std::memory_order_seq_cst);
     assert(vt == T(2));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp
index 5fed691..9f25807 100644
--- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp
+++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// XFAIL: c++98, c++03
 
 // <atomic>
 
diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp
index f85172a..f6944c7 100644
--- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp
+++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp
@@ -22,6 +22,8 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 struct UserType {
     int i;
 
@@ -34,27 +36,29 @@
 };
 
 template <class Tp>
-void test() {
-    typedef std::atomic<Tp> Atomic;
-    static_assert(std::is_literal_type<Atomic>::value, "");
-    constexpr Tp t(42);
-    {
-        constexpr Atomic a(t);
-        assert(a == t);
+struct TestFunc {
+    void operator()() const {
+        typedef std::atomic<Tp> Atomic;
+        static_assert(std::is_literal_type<Atomic>::value, "");
+        constexpr Tp t(42);
+        {
+            constexpr Atomic a(t);
+            assert(a == t);
+        }
+        {
+            constexpr Atomic a{t};
+            assert(a == t);
+        }
+        {
+            constexpr Atomic a = ATOMIC_VAR_INIT(t);
+            assert(a == t);
+        }
     }
-    {
-        constexpr Atomic a{t};
-        assert(a == t);
-    }
-    {
-        constexpr Atomic a = ATOMIC_VAR_INIT(t);
-        assert(a == t);
-    }
-}
+};
 
 
 int main()
 {
-    test<int>();
-    test<UserType>();
+    TestFunc<UserType>()();
+    TestEachIntegralType<TestFunc>()();
 }
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 0000000..2026219
--- /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/sequences/vector/const_value_type.pass.cpp b/test/std/containers/associative/map/allocator_mismatch.fail.cpp
similarity index 65%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/associative/map/allocator_mismatch.fail.cpp
index e16e439..f5da145 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/associative/map/allocator_mismatch.fail.cpp
@@ -7,16 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <map>
+//   The container's value type must be the same as the allocator's value type
 
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
+#include <map>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    std::map<int, int, std::less<int>, std::allocator<long> > m;
 }
diff --git a/test/std/containers/associative/map/compare.pass.cpp b/test/std/containers/associative/map/compare.pass.cpp
index 26ac7af..9d1c13d 100644
--- a/test/std/containers/associative/map/compare.pass.cpp
+++ b/test/std/containers/associative/map/compare.pass.cpp
@@ -44,7 +44,7 @@
         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 0000000..84c2451
--- /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 86b1e3d..0da2850 100644
--- a/test/std/containers/associative/map/map.access/at.pass.cpp
+++ b/test/std/containers/associative/map/map.access/at.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <map>
 
 // class map
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 ab1144c..3b1c21f 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 @@
     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 @@
     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 7e0fd41..e5580bc 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);
@@ -38,7 +41,7 @@
     assert(m.size() == 2);
     }
     {
-    typedef std::pair<MoveOnly, double> V;
+    typedef std::pair<const MoveOnly, double> V;
     std::map<MoveOnly, double, std::less<MoveOnly>, min_allocator<V>> m;
     assert(m.size() == 0);
     assert(m[1] == 0.0);
@@ -52,5 +55,27 @@
     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.cons/default_noexcept.pass.cpp b/test/std/containers/associative/map/map.cons/default_noexcept.pass.cpp
index 1f11fc9..dedc89b 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
@@ -33,16 +33,17 @@
 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, "");
     }
     {
-        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
+        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C;
         static_assert(std::is_nothrow_default_constructible<C>::value, "");
     }
     {
-        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
+        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C;
         static_assert(!std::is_nothrow_default_constructible<C>::value, "");
     }
     {
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 eed26d3..9baa19b 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
@@ -31,16 +31,17 @@
 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_destructible<C>::value, "");
     }
     {
-        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
+        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C;
         static_assert(std::is_nothrow_destructible<C>::value, "");
     }
     {
-        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
+        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C;
         static_assert(std::is_nothrow_destructible<C>::value, "");
     }
     {
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 f80b1d3..3b28118 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
@@ -33,16 +33,17 @@
 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_move_assignable<C>::value, "");
     }
     {
-        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
+        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C;
         static_assert(!std::is_nothrow_move_assignable<C>::value, "");
     }
     {
-        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
+        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C;
         static_assert(std::is_nothrow_move_assignable<C>::value, "");
     }
     {
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 9347b83..0f1fd39 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
@@ -31,16 +31,17 @@
 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_move_constructible<C>::value, "");
     }
     {
-        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
+        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C;
         static_assert(std::is_nothrow_move_constructible<C>::value, "");
     }
     {
-        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
+        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C;
         static_assert(std::is_nothrow_move_constructible<C>::value, "");
     }
     {
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 0000000..d98047d
--- /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 3d28242..e2ffcba 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"
 
+template <class Container>
+void do_insert_cv_test()
+{
+    typedef Container M;
+    typedef std::pair<typename M::iterator, bool> R;
+    typedef typename M::value_type VT;
+    M m;
+
+    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);
+
+    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);
+
+    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);
+
+    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);
+}
+
 int main()
 {
-    {
-        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);
-
-        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);
-
-        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
+    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;
-        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);
-
-        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);
-
-        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);
+        do_insert_cv_test<M>();
     }
 #endif
 }
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 278db46..0c7e124 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"
 
+template <class Container>
+void do_insert_iter_cv_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(m.end(), v1);
+    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);
+
+    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);
+
+    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);
+}
+
 int main()
 {
-    {
-        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);
-
-        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(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
+    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;
-        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(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);
+        do_insert_iter_cv_test<M>();
     }
 #endif
 }
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 42b41fd..3edb9c0 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
@@ -19,69 +21,78 @@
 
 #include "MoveOnly.h"
 #include "min_allocator.h"
+#include "test_macros.h"
 
+template <class Container, class Pair>
+void do_insert_iter_rv_test()
+{
+    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(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()
 {
-#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);
+    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(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);
-    }
-#if __cplusplus >= 201103L
     {
         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_iter_rv_test<M, P>();
+        do_insert_iter_rv_test<M, CP>();
+    }
+    {
+        typedef std::map<int, MoveOnly> M;
         typedef M::iterator R;
         M m;
-        R r = m.insert(m.end(), P(2, 2));
+        R r = m.insert(m.end(), {2, MoveOnly(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));
+        r = m.insert(m.end(), {1, MoveOnly(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));
+        r = m.insert(m.end(), {3, MoveOnly(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));
+        r = m.insert(m.end(), {3, MoveOnly(3)});
         assert(r == prev(m.end()));
         assert(m.size() == 3);
         assert(r->first == 3);
         assert(r->second == 3);
     }
-#endif
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
 }
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 484ed06..526bcee 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
@@ -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 @@
 
 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 @@
         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 a9d3277..503d929 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,10 +7,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: c++98, c++03
+
 // <map>
 
 // class map
 
+// pair<iterator, bool> insert( value_type&& v);  // C++17 and later
 // template <class P>
 //   pair<iterator, bool> insert(P&& p);
 
@@ -19,75 +22,86 @@
 
 #include "MoveOnly.h"
 #include "min_allocator.h"
+#include "test_macros.h"
+
+template <class Container, class Pair>
+void do_insert_rv_test()
+{
+    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(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(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(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);
+}
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    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>>();
+
+    {
+        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>();
+    }
     {
         typedef std::map<int, MoveOnly> M;
         typedef std::pair<M::iterator, bool> R;
         M m;
-        R r = m.insert(M::value_type(2, 2));
+        R r = m.insert({2, MoveOnly(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));
+        r = m.insert({1, MoveOnly(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));
+        r = m.insert({3, MoveOnly(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));
+        r = m.insert({3, MoveOnly(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 __cplusplus >= 201103L
-    {
-        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(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(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);
-    }
-#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 8e0dd75..7144ed2 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
@@ -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 @@
 
 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;
@@ -183,7 +179,4 @@
         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.special/swap_noexcept.pass.cpp b/test/std/containers/associative/map/map.special/swap_noexcept.pass.cpp
index 4598e99..63ed926 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)
@@ -22,6 +24,7 @@
 #include <map>
 #include <cassert>
 
+#include "test_macros.h"
 #include "MoveOnly.h"
 #include "test_allocator.h"
 
@@ -93,19 +96,19 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
+    typedef std::pair<const MoveOnly, MoveOnly> V;
     {
         typedef std::map<MoveOnly, MoveOnly> C;
         C c1, c2;
         static_assert(noexcept(swap(c1, c2)), "");
     }
     {
-        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
+        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C;
         C c1, c2;
         static_assert(noexcept(swap(c1, c2)), "");
     }
     {
-        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
+        typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C;
         C c1, c2;
         static_assert(noexcept(swap(c1, c2)), "");
     }
@@ -117,32 +120,31 @@
 
 #if TEST_STD_VER >= 14
     { // POCS allocator, throwable swap for comp
-    typedef std::map<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;
+    typedef std::map<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc <V>> C;
     C c1, c2;
     static_assert(!noexcept(swap(c1, c2)), "");
     }
     { // always equal allocator, throwable swap for comp
-    typedef std::map<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;
+    typedef std::map<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc2<V>> C;
     C c1, c2;
     static_assert(!noexcept(swap(c1, c2)), "");
     }
     { // POCS allocator, nothrow swap for comp
-    typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;
+    typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc <V>> C;
     C c1, c2;
     static_assert( noexcept(swap(c1, c2)), "");
     }
     { // always equal allocator, nothrow swap for comp
-    typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
+    typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc2<V>> C;
     C c1, c2;
     static_assert( noexcept(swap(c1, c2)), "");
     }
 
     { // NOT always equal allocator, nothrow swap for comp
-    typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C;
+    typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc3<V>> C;
     C c1, c2;
     static_assert( noexcept(swap(c1, c2)), "");
     }
 #endif
 
-#endif
 }
diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/std/containers/associative/multimap/allocator_mismatch.fail.cpp
similarity index 65%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/associative/multimap/allocator_mismatch.fail.cpp
index e16e439..1882321 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/associative/multimap/allocator_mismatch.fail.cpp
@@ -7,16 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <map>
+//   The container's value type must be the same as the allocator's value type
 
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
+#include <map>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    std::multimap<int, int, std::less<int>, std::allocator<long> > 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 0000000..c461eb3
--- /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/multimap.cons/default_noexcept.pass.cpp b/test/std/containers/associative/multimap/multimap.cons/default_noexcept.pass.cpp
index d1db40b..5f05a0d 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
@@ -33,16 +33,17 @@
 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, "");
     }
     {
-        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
+        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C;
         static_assert(std::is_nothrow_default_constructible<C>::value, "");
     }
     {
-        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
+        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C;
         static_assert(!std::is_nothrow_default_constructible<C>::value, "");
     }
     {
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 cb55e3f..dd17012 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
@@ -31,16 +31,17 @@
 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_destructible<C>::value, "");
     }
     {
-        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
+        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C;
         static_assert(std::is_nothrow_destructible<C>::value, "");
     }
     {
-        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
+        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C;
         static_assert(std::is_nothrow_destructible<C>::value, "");
     }
     {
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 8ad9e8b..635a8dc 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
@@ -33,16 +33,17 @@
 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_move_assignable<C>::value, "");
     }
     {
-        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
+        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C;
         static_assert(!std::is_nothrow_move_assignable<C>::value, "");
     }
     {
-        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
+        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C;
         static_assert(std::is_nothrow_move_assignable<C>::value, "");
     }
     {
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 66ea873..0f31f04 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
@@ -31,16 +31,17 @@
 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_move_constructible<C>::value, "");
     }
     {
-        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
+        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C;
         static_assert(std::is_nothrow_move_constructible<C>::value, "");
     }
     {
-        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
+        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C;
         static_assert(std::is_nothrow_move_constructible<C>::value, "");
     }
     {
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 0000000..225bf67
--- /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 d9afc9d..5387431 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"
 
+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);
+
+    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);
+
+    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);
+
+    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> 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> 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_iter_cv.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_cv.pass.cpp
index b83c802..05e1096 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"
 
+template <class Container>
+void do_insert_hint_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(m.end(), v1);
+    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);
+
+    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);
+
+    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()
 {
-    {
-        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);
-
-        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);
-    }
-#if __cplusplus >= 201103L
+    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_rv.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/insert_iter_rv.pass.cpp
index b44f464..47e0d37 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
@@ -19,69 +21,79 @@
 
 #include "MoveOnly.h"
 #include "min_allocator.h"
+#include "test_macros.h"
+
+template <class Container, class Pair>
+void do_insert_rv_test()
+{
+    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(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()
 {
-#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);
+    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(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);
-    }
-#if __cplusplus >= 201103L
     {
         typedef std::multimap<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>();
+
+    }
+    {
+        typedef std::multimap<int, MoveOnly> M;
         typedef M::iterator R;
         M m;
-        R r = m.insert(m.cend(), P(2, 2));
+        R r = m.insert(m.cend(), {2, MoveOnly(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));
+        r = m.insert(m.cend(), {1, MoveOnly(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));
+        r = m.insert(m.cend(), {3, MoveOnly(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));
+        r = m.insert(m.cend(), {3, MoveOnly(2)});
         assert(r == prev(m.end()));
         assert(m.size() == 4);
         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 b1c0435..022de87 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
@@ -19,67 +21,73 @@
 
 #include "MoveOnly.h"
 #include "min_allocator.h"
+#include "test_macros.h"
+
+template <class Container>
+void do_insert_rv_test()
+{
+    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(VT(1, 1));
+    assert(r == m.begin());
+    assert(m.size() == 2);
+    assert(r->first == 1);
+    assert(r->second == 1);
+
+    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(VT(3, 3));
+    assert(r == prev(m.end()));
+    assert(m.size() == 4);
+    assert(r->first == 3);
+    assert(r->second == 3);
+}
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    do_insert_rv_test<std::multimap<int, MoveOnly>>();
+    {
+        typedef std::multimap<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M;
+        do_insert_rv_test<M>();
+    }
     {
         typedef std::multimap<int, MoveOnly> M;
         typedef M::iterator R;
         M m;
-        R r = m.insert(M::value_type(2, 2));
+        R r = m.insert({2, MoveOnly(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));
+        r = m.insert({1, MoveOnly(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));
+        r = m.insert({3, MoveOnly(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));
+        r = m.insert({3, MoveOnly(3)});
         assert(r == prev(m.end()));
         assert(m.size() == 4);
         assert(r->first == 3);
         assert(r->second == 3);
     }
-#if __cplusplus >= 201103L
-    {
-        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);
-    }
-#endif
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
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 1013c62..d1c5718 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)
@@ -22,6 +24,7 @@
 #include <map>
 #include <cassert>
 
+#include "test_macros.h"
 #include "MoveOnly.h"
 #include "test_allocator.h"
 
@@ -93,19 +96,19 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
+    typedef std::pair<const MoveOnly, MoveOnly> V;
     {
         typedef std::multimap<MoveOnly, MoveOnly> C;
         C c1, c2;
         static_assert(noexcept(swap(c1, c2)), "");
     }
     {
-        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
+        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C;
         C c1, c2;
         static_assert(noexcept(swap(c1, c2)), "");
     }
     {
-        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
+        typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C;
         C c1, c2;
         static_assert(noexcept(swap(c1, c2)), "");
     }
@@ -117,32 +120,30 @@
 
 #if TEST_STD_VER >= 14
     { // POCS allocator, throwable swap for comp
-    typedef std::multimap<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;
+    typedef std::multimap<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc <V>> C;
     C c1, c2;
     static_assert(!noexcept(swap(c1, c2)), "");
     }
     { // always equal allocator, throwable swap for comp
-    typedef std::multimap<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;
+    typedef std::multimap<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc2<V>> C;
     C c1, c2;
     static_assert(!noexcept(swap(c1, c2)), "");
     }
     { // POCS allocator, nothrow swap for comp
-    typedef std::multimap<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;
+    typedef std::multimap<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc <V>> C;
     C c1, c2;
     static_assert( noexcept(swap(c1, c2)), "");
     }
     { // always equal allocator, nothrow swap for comp
-    typedef std::multimap<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
+    typedef std::multimap<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc2<V>> C;
     C c1, c2;
     static_assert( noexcept(swap(c1, c2)), "");
     }
 
     { // NOT always equal allocator, nothrow swap for comp
-    typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C;
+    typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc3<V>> C;
     C c1, c2;
     static_assert( noexcept(swap(c1, c2)), "");
     }
 #endif
-
-#endif
 }
diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/std/containers/associative/multiset/allocator_mismatch.fail.cpp
similarity index 65%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/associative/multiset/allocator_mismatch.fail.cpp
index e16e439..b2b30d6 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/associative/multiset/allocator_mismatch.fail.cpp
@@ -7,16 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <set>
+//   The container's value type must be the same as the allocator's value type
 
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
+#include <set>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    std::multiset<int, std::less<int>, std::allocator<long> > ms;
 }
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 0000000..0355e18
--- /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/sequences/vector/const_value_type.pass.cpp b/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp
similarity index 62%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp
index e16e439..a280d10 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp
@@ -7,16 +7,20 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <set>
 
-// vector<const int> v;  // an extension
+// class multiset
 
-#include <vector>
-#include <type_traits>
+// insert(...)
+
+// UNSUPPORTED: c++98, c++03
+
+#include <set>
+
+#include "container_test_types.h"
+#include "../../set_allocator_requirement_test_templates.h"
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+  testMultisetInsert<TCT::multiset<> >();
 }
diff --git a/test/std/containers/associative/multiset/iterator.pass.cpp b/test/std/containers/associative/multiset/iterator.pass.cpp
index d1f0ecf..8874272 100644
--- a/test/std/containers/associative/multiset/iterator.pass.cpp
+++ b/test/std/containers/associative/multiset/iterator.pass.cpp
@@ -70,7 +70,7 @@
         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);
     }
     {
@@ -151,7 +151,7 @@
         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/multiset.cons/iter_iter_alloc.pass.cpp b/test/std/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp
index 4ed00c7..4313f46 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 @@
     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.special/swap_noexcept.pass.cpp b/test/std/containers/associative/multiset/multiset.special/swap_noexcept.pass.cpp
index 8e2c67c..c742c7f 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)
@@ -22,6 +24,7 @@
 #include <set>
 #include <cassert>
 
+#include "test_macros.h"
 #include "MoveOnly.h"
 #include "test_allocator.h"
 
@@ -93,7 +96,6 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
     {
         typedef std::multiset<MoveOnly> C;
         C c1, c2;
@@ -143,6 +145,4 @@
     static_assert( noexcept(swap(c1, c2)), "");
     }
 #endif
-
-#endif
 }
diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/std/containers/associative/set/allocator_mismatch.fail.cpp
similarity index 65%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/associative/set/allocator_mismatch.fail.cpp
index e16e439..6905d93 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/associative/set/allocator_mismatch.fail.cpp
@@ -7,16 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <set>
+//   The container's value type must be the same as the allocator's value type
 
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
+#include <set>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    std::set<int, std::less<int>, std::allocator<long> > s;
 }
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 0000000..d3a1d66
--- /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 0000000..b14340b
--- /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/set.cons/iter_iter_alloc.pass.cpp b/test/std/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp
index 5ccb6e5..077a749 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 @@
     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.special/swap_noexcept.pass.cpp b/test/std/containers/associative/set/set.special/swap_noexcept.pass.cpp
index 3ec6976..76528e1 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)
@@ -22,6 +24,7 @@
 #include <set>
 #include <cassert>
 
+#include "test_macros.h"
 #include "MoveOnly.h"
 #include "test_allocator.h"
 
@@ -93,7 +96,6 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
     {
         typedef std::set<MoveOnly> C;
         C c1, c2;
@@ -144,5 +146,4 @@
     }
 #endif
 
-#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 0000000..0d3025e
--- /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 ade20d4..802cd00 100644
--- a/test/std/containers/container.adaptors/priority.queue/types.pass.cpp
+++ b/test/std/containers/container.adaptors/priority.queue/types.pass.cpp
@@ -48,13 +48,13 @@
 
 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::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/sequences/vector/const_value_type.pass.cpp b/test/std/containers/container.adaptors/queue/queue.defn/types.fail.cpp
similarity index 68%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/container.adaptors/queue/queue.defn/types.fail.cpp
index e16e439..2b8341f 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/container.adaptors/queue/queue.defn/types.fail.cpp
@@ -7,16 +7,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <queue>
 
-// vector<const int> v;  // an extension
-
-#include <vector>
+#include <queue>
+#include <cassert>
 #include <type_traits>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+//  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 cc918a3..7f1883a 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 @@
 
 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/stack/stack.defn/types.fail.cpp b/test/std/containers/container.adaptors/stack/stack.defn/types.fail.cpp
new file mode 100644
index 0000000..ee4c544
--- /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 afc5ebd..77a798b 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 @@
 
 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/map_allocator_requirement_test_templates.h b/test/std/containers/map_allocator_requirement_test_templates.h
new file mode 100644
index 0000000..2ae3a2e
--- /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 34db59d..64ea75a 100644
--- a/test/std/containers/sequences/array/array.cons/initializer_list.pass.cpp
+++ b/test/std/containers/sequences/array/array.cons/initializer_list.pass.cpp
@@ -14,7 +14,9 @@
 #include <array>
 #include <cassert>
 
-#include "../suppress_array_warnings.h"
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
 
 int main()
 {
@@ -33,4 +35,18 @@
         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.data/data.pass.cpp b/test/std/containers/sequences/array/array.data/data.pass.cpp
index 80b7d06..d7aed70 100644
--- a/test/std/containers/sequences/array/array.data/data.pass.cpp
+++ b/test/std/containers/sequences/array/array.data/data.pass.cpp
@@ -14,7 +14,9 @@
 #include <array>
 #include <cassert>
 
-#include "../suppress_array_warnings.h"
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
 
 int main()
 {
diff --git a/test/std/containers/sequences/array/array.data/data_const.pass.cpp b/test/std/containers/sequences/array/array.data/data_const.pass.cpp
index 1c9abdd..58840e9 100644
--- a/test/std/containers/sequences/array/array.data/data_const.pass.cpp
+++ b/test/std/containers/sequences/array/array.data/data_const.pass.cpp
@@ -14,7 +14,9 @@
 #include <array>
 #include <cassert>
 
-#include "../suppress_array_warnings.h"
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
 
 int main()
 {
diff --git a/test/std/containers/sequences/array/array.fill/fill.pass.cpp b/test/std/containers/sequences/array/array.fill/fill.pass.cpp
index f98dbbd..5bc42ce 100644
--- a/test/std/containers/sequences/array/array.fill/fill.pass.cpp
+++ b/test/std/containers/sequences/array/array.fill/fill.pass.cpp
@@ -14,7 +14,9 @@
 #include <array>
 #include <cassert>
 
-#include "../suppress_array_warnings.h"
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
 
 int main()
 {
diff --git a/test/std/containers/sequences/array/array.size/size.pass.cpp b/test/std/containers/sequences/array/array.size/size.pass.cpp
index 89b893a..a833fdc 100644
--- a/test/std/containers/sequences/array/array.size/size.pass.cpp
+++ b/test/std/containers/sequences/array/array.size/size.pass.cpp
@@ -14,7 +14,9 @@
 #include <array>
 #include <cassert>
 
-#include "../suppress_array_warnings.h"
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
 
 int main()
 {
diff --git a/test/std/containers/sequences/array/array.special/swap.pass.cpp b/test/std/containers/sequences/array/array.special/swap.pass.cpp
index 82ce904..413f291 100644
--- a/test/std/containers/sequences/array/array.special/swap.pass.cpp
+++ b/test/std/containers/sequences/array/array.special/swap.pass.cpp
@@ -14,7 +14,27 @@
 #include <array>
 #include <cassert>
 
-#include "../suppress_array_warnings.h"
+#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()
 {
@@ -42,4 +62,24 @@
         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 22bf657..8d01dbf 100644
--- a/test/std/containers/sequences/array/array.swap/swap.pass.cpp
+++ b/test/std/containers/sequences/array/array.swap/swap.pass.cpp
@@ -10,11 +10,23 @@
 // <array>
 
 // void swap(array& a);
+// namespace std { void swap(array<T, N> &x, array<T, N> &y);
 
-#include <array>
 #include <cassert>
+#include <array>
 
-#include "../suppress_array_warnings.h"
+#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()
 {
@@ -35,6 +47,22 @@
     }
     {
         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 = {};
@@ -42,4 +70,24 @@
         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/array.tuple/get.fail.cpp b/test/std/containers/sequences/array/array.tuple/get.fail.cpp
index 6b2385d..13323dd 100644
--- a/test/std/containers/sequences/array/array.tuple/get.fail.cpp
+++ b/test/std/containers/sequences/array/array.tuple/get.fail.cpp
@@ -20,7 +20,10 @@
 #include <cassert>
 
 #include "test_macros.h"
-#include "../suppress_array_warnings.h"
+
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
 
 int main()
 {
diff --git a/test/std/containers/sequences/array/array.tuple/get.pass.cpp b/test/std/containers/sequences/array/array.tuple/get.pass.cpp
index c455707..4f210c4 100644
--- a/test/std/containers/sequences/array/array.tuple/get.pass.cpp
+++ b/test/std/containers/sequences/array/array.tuple/get.pass.cpp
@@ -16,7 +16,9 @@
 
 #include "test_macros.h"
 
-#include "../suppress_array_warnings.h"
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
 
 
 #if TEST_STD_VER > 11
diff --git a/test/std/containers/sequences/array/array.tuple/get_const.pass.cpp b/test/std/containers/sequences/array/array.tuple/get_const.pass.cpp
index ddc2ab2..04606bf 100644
--- a/test/std/containers/sequences/array/array.tuple/get_const.pass.cpp
+++ b/test/std/containers/sequences/array/array.tuple/get_const.pass.cpp
@@ -16,7 +16,9 @@
 
 #include "test_macros.h"
 
-#include "../suppress_array_warnings.h"
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
 
 int main()
 {
diff --git a/test/std/containers/sequences/array/array.tuple/get_const_rv.pass.cpp b/test/std/containers/sequences/array/array.tuple/get_const_rv.pass.cpp
new file mode 100644
index 0000000..a22c91a
--- /dev/null
+++ b/test/std/containers/sequences/array/array.tuple/get_const_rv.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <array>
+
+// template <size_t I, class T, size_t N> const T&& get(const array<T, N>&& a);
+
+// UNSUPPORTED: c++98, c++03
+
+#include <array>
+#include <memory>
+#include <type_traits>
+#include <utility>
+#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"
+
+int main()
+{
+
+    {
+    typedef std::unique_ptr<double> T;
+    typedef std::array<T, 1> C;
+    const C c = {std::unique_ptr<double>(new double(3.5))};
+    static_assert(std::is_same<const T&&, decltype(std::get<0>(std::move(c)))>::value, "");
+    static_assert(noexcept(std::get<0>(std::move(c))), "");
+    const T&& t = std::get<0>(std::move(c));
+    assert(*t == 3.5);
+    }
+
+#if TEST_STD_VER > 11
+    {
+    typedef double T;
+    typedef std::array<T, 3> C;
+    constexpr const C c = {1, 2, 3.5};
+    static_assert(std::get<0>(std::move(c)) == 1, "");
+    static_assert(std::get<1>(std::move(c)) == 2, "");
+    static_assert(std::get<2>(std::move(c)) == 3.5, "");
+    }
+#endif
+}
diff --git a/test/std/containers/sequences/array/array.tuple/get_rv.pass.cpp b/test/std/containers/sequences/array/array.tuple/get_rv.pass.cpp
index 412c7c7..72ef49b 100644
--- a/test/std/containers/sequences/array/array.tuple/get_rv.pass.cpp
+++ b/test/std/containers/sequences/array/array.tuple/get_rv.pass.cpp
@@ -18,7 +18,9 @@
 #include <utility>
 #include <cassert>
 
-#include "../suppress_array_warnings.h"
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
 
 int main()
 {
diff --git a/test/std/containers/sequences/array/at.pass.cpp b/test/std/containers/sequences/array/at.pass.cpp
index c4f7acb..5cb89df 100644
--- a/test/std/containers/sequences/array/at.pass.cpp
+++ b/test/std/containers/sequences/array/at.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <array>
 
 // reference operator[] (size_type)
@@ -19,7 +20,9 @@
 
 #include "test_macros.h"
 
-#include "suppress_array_warnings.h"
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
 
 int main()
 {
diff --git a/test/std/containers/sequences/array/begin.pass.cpp b/test/std/containers/sequences/array/begin.pass.cpp
index a6218ae..b12ffc8 100644
--- a/test/std/containers/sequences/array/begin.pass.cpp
+++ b/test/std/containers/sequences/array/begin.pass.cpp
@@ -14,7 +14,9 @@
 #include <array>
 #include <cassert>
 
-#include "suppress_array_warnings.h"
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
 
 int main()
 {
diff --git a/test/std/containers/sequences/array/front_back.pass.cpp b/test/std/containers/sequences/array/front_back.pass.cpp
index ebe3a18..bccaade 100644
--- a/test/std/containers/sequences/array/front_back.pass.cpp
+++ b/test/std/containers/sequences/array/front_back.pass.cpp
@@ -19,7 +19,9 @@
 
 #include "test_macros.h"
 
-#include "suppress_array_warnings.h"
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
 
 int main()
 {
diff --git a/test/std/containers/sequences/array/indexing.pass.cpp b/test/std/containers/sequences/array/indexing.pass.cpp
index c550d14..5ccb0b4 100644
--- a/test/std/containers/sequences/array/indexing.pass.cpp
+++ b/test/std/containers/sequences/array/indexing.pass.cpp
@@ -19,7 +19,9 @@
 
 #include "test_macros.h"
 
-#include "suppress_array_warnings.h"
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#include "disable_missing_braces_warning.h"
 
 int main()
 {
diff --git a/test/std/containers/sequences/array/suppress_array_warnings.h b/test/std/containers/sequences/array/suppress_array_warnings.h
deleted file mode 100644
index 1dde3d3..0000000
--- a/test/std/containers/sequences/array/suppress_array_warnings.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef SUPPRESS_ARRAY_WARNINGS_H
-#define SUPPRESS_ARRAY_WARNINGS_H
-
-// std::array is explicitly allowed to be initialized with A a = { init-list };.
-// Disable the missing braces warning for this reason.
-#pragma GCC diagnostic ignored "-Wmissing-braces"
-
-#endif // SUPPRESS_ARRAY_WARNINGS
diff --git a/test/std/containers/sequences/array/types.pass.cpp b/test/std/containers/sequences/array/types.pass.cpp
index 065ade9..a59b63d 100644
--- a/test/std/containers/sequences/array/types.pass.cpp
+++ b/test/std/containers/sequences/array/types.pass.cpp
@@ -44,6 +44,13 @@
         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;
@@ -58,5 +65,12 @@
         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/vector/const_value_type.pass.cpp b/test/std/containers/sequences/deque/allocator_mismatch.fail.cpp
similarity index 65%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/sequences/deque/allocator_mismatch.fail.cpp
index e16e439..9223c1e 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/sequences/deque/allocator_mismatch.fail.cpp
@@ -7,16 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <deque>
+//   The container's value type must be the same as the allocator's value type
 
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
+#include <deque>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    std::deque<int, std::allocator<long> > d;
 }
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 84f04f9..53c6bd3 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 2bf2423..12af643 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.modifiers/erase_iter.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp
index a45b75d..a1c42a7 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"
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 0576aca..15d7400 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"
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 8ad6b53..b37e961 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <deque>
 
 // void push_back(const value_type& x);
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 e01b2a2..b4caa94 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <deque>
 
 // void push_front(const value_type& x);
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 83bcac8..609e66f 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"
 
@@ -51,7 +54,6 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
     {
         typedef std::deque<MoveOnly> C;
         C c1, c2;
@@ -86,5 +88,4 @@
     }
 #endif
 
-#endif
 }
diff --git a/test/std/containers/sequences/deque/types.pass.cpp b/test/std/containers/sequences/deque/types.pass.cpp
index da9470d..73dc964 100644
--- a/test/std/containers/sequences/deque/types.pass.cpp
+++ b/test/std/containers/sequences/deque/types.pass.cpp
@@ -64,6 +64,12 @@
     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,6 +79,7 @@
     test<Copyable, test_allocator<Copyable> >();
     static_assert((std::is_same<std::deque<char>::allocator_type,
                                 std::allocator<char> >::value), "");
+
 #if __cplusplus >= 201103L
     {
         typedef std::deque<short, min_allocator<short>> C;
@@ -85,6 +92,13 @@
 //  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/vector/const_value_type.pass.cpp b/test/std/containers/sequences/forwardlist/allocator_mismatch.fail.cpp
similarity index 65%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/sequences/forwardlist/allocator_mismatch.fail.cpp
index e16e439..b53075d 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/sequences/forwardlist/allocator_mismatch.fail.cpp
@@ -7,16 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <forward_list>
+//   The container's value type must be the same as the allocator's value type
 
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
+#include <forward_list>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    std::forward_list<int, std::allocator<long> > fl;
 }
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 8341f7b..88ecb75 100644
--- a/test/std/containers/sequences/forwardlist/forwardlist.cons/move.pass.cpp
+++ b/test/std/containers/sequences/forwardlist/forwardlist.cons/move.pass.cpp
@@ -24,7 +24,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     {
         typedef MoveOnly T;
-        typedef test_allocator<int> A;
+        typedef test_allocator<T> A;
         typedef std::forward_list<T, A> C;
         T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
         typedef std::move_iterator<T*> I;
@@ -39,7 +39,7 @@
     }
     {
         typedef MoveOnly T;
-        typedef other_allocator<int> A;
+        typedef other_allocator<T> A;
         typedef std::forward_list<T, A> C;
         T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
         typedef std::move_iterator<T*> I;
@@ -55,7 +55,7 @@
 #if __cplusplus >= 201103L
     {
         typedef MoveOnly T;
-        typedef min_allocator<int> A;
+        typedef min_allocator<T> A;
         typedef std::forward_list<T, A> C;
         T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
         typedef std::move_iterator<T*> I;
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 6bb575e..3f0e45a 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
@@ -24,7 +24,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     {
         typedef MoveOnly T;
-        typedef test_allocator<int> A;
+        typedef test_allocator<T> A;
         typedef std::forward_list<T, A> C;
         T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
         typedef std::move_iterator<T*> I;
@@ -39,7 +39,7 @@
     }
     {
         typedef MoveOnly T;
-        typedef test_allocator<int> A;
+        typedef test_allocator<T> A;
         typedef std::forward_list<T, A> C;
         T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
         typedef std::move_iterator<T*> I;
@@ -55,7 +55,7 @@
 #if __cplusplus >= 201103L
     {
         typedef MoveOnly T;
-        typedef min_allocator<int> A;
+        typedef min_allocator<T> A;
         typedef std::forward_list<T, A> C;
         T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
         typedef std::move_iterator<T*> I;
diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/push_front_exception_safety.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/push_front_exception_safety.pass.cpp
index 43c62eb..b501347 100644
--- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/push_front_exception_safety.pass.cpp
+++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/push_front_exception_safety.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <forward_list>
 
 // void push_front(const value_type& x);
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 cbe8142..a49c955 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"
 
@@ -51,7 +54,6 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
     {
         typedef std::forward_list<MoveOnly> C;
         C c1, c2;
@@ -85,6 +87,4 @@
         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 0000000..df27344
--- /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/types.pass.cpp b/test/std/containers/sequences/forwardlist/types.pass.cpp
index a1f8862..9a4e026 100644
--- a/test/std/containers/sequences/forwardlist/types.pass.cpp
+++ b/test/std/containers/sequences/forwardlist/types.pass.cpp
@@ -44,6 +44,13 @@
     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
     {
@@ -57,6 +64,13 @@
 //  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/vector/const_value_type.pass.cpp b/test/std/containers/sequences/list/allocator_mismatch.fail.cpp
similarity index 65%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/sequences/list/allocator_mismatch.fail.cpp
index e16e439..3490d10 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/sequences/list/allocator_mismatch.fail.cpp
@@ -7,16 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <list>
+//   The container's value type must be the same as the allocator's value type
 
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
+#include <list>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    std::list<int, std::allocator<long> > l;
 }
diff --git a/test/std/containers/sequences/list/incomplete_type.pass.cpp b/test/std/containers/sequences/list/incomplete_type.pass.cpp
new file mode 100644
index 0000000..adfb4d4
--- /dev/null
+++ b/test/std/containers/sequences/list/incomplete_type.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>
+
+// Check that std::list and it's iterators can be instantiated with an incomplete
+// type.
+
+#include <list>
+
+struct A {
+    std::list<A> l;
+    std::list<A>::iterator it;
+    std::list<A>::const_iterator cit;
+    std::list<A>::reverse_iterator rit;
+    std::list<A>::const_reverse_iterator crit;
+};
+
+int main() {
+    A a;
+}
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 a7f1917..736b9ba 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,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <list>
 
 // template <InputIterator Iter>
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 eeb74b8..c0f6ed1 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <list>
 
 // iterator insert(const_iterator position, size_type n, const value_type& x);
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 406e93a..1aacb63 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,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <list>
 
 // iterator insert(const_iterator position, const value_type& x);
diff --git a/test/std/containers/sequences/list/list.modifiers/push_back_exception_safety.pass.cpp b/test/std/containers/sequences/list/list.modifiers/push_back_exception_safety.pass.cpp
index 9d3c05e..8d16142 100644
--- a/test/std/containers/sequences/list/list.modifiers/push_back_exception_safety.pass.cpp
+++ b/test/std/containers/sequences/list/list.modifiers/push_back_exception_safety.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <list>
 
 // void push_back(const value_type& x);
diff --git a/test/std/containers/sequences/list/list.modifiers/push_front_exception_safety.pass.cpp b/test/std/containers/sequences/list/list.modifiers/push_front_exception_safety.pass.cpp
index 6609005..aafccee 100644
--- a/test/std/containers/sequences/list/list.modifiers/push_front_exception_safety.pass.cpp
+++ b/test/std/containers/sequences/list/list.modifiers/push_front_exception_safety.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <list>
 
 // void push_front(const value_type& x);
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 9c83ad5..7d7ca12 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"
 
@@ -51,7 +54,6 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
     {
         typedef std::list<MoveOnly> C;
         C c1, c2;
@@ -86,5 +88,4 @@
     }
 #endif
 
-#endif
 }
diff --git a/test/std/containers/sequences/list/types.pass.cpp b/test/std/containers/sequences/list/types.pass.cpp
index 7730360..e70c5d2 100644
--- a/test/std/containers/sequences/list/types.pass.cpp
+++ b/test/std/containers/sequences/list/types.pass.cpp
@@ -31,18 +31,39 @@
 
 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), "");
+	{
+	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 __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, 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/construct_default.pass.cpp b/test/std/containers/sequences/vector.bool/construct_default.pass.cpp
index 0782409..983d363 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 @@
 	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 @@
 	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 94e6801..3d11239 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 @@
 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 @@
     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 ea9d41d..196694d 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 @@
 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 @@
     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 93ecbe8..271e4ee 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 @@
 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 @@
 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 fc772f1..869797b 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 @@
 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);
@@ -31,7 +32,7 @@
 int main()
 {
     test<std::vector<bool> >(50, 3);
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     test<std::vector<bool, min_allocator<bool>> >(50, 3);
 #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 6cca948..905a51c 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 @@
      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)
@@ -33,7 +34,7 @@
 int main()
 {
     test<std::vector<bool> >(50, 3, std::allocator<bool>());
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     test<std::vector<bool, min_allocator<bool>> >(50, 3, 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 5882278..abf322b 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 @@
 {
     unsigned s = x.size();
     C c(x);
-    assert(c.__invariants());
+    LIBCPP_ASSERT(c.__invariants());
     assert(c.size() == s);
     assert(c == x);
 }
@@ -41,15 +43,13 @@
         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> > 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]);
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 2f0192b..28eea46 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 @@
 {
     unsigned s = x.size();
     C c(x, a);
-    assert(c.__invariants());
+    LIBCPP_ASSERT(c.__invariants());
     assert(c.size() == s);
     assert(c == x);
 }
@@ -46,7 +48,7 @@
         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]);
diff --git a/test/std/containers/sequences/vector.bool/find.pass.cpp b/test/std/containers/sequences/vector.bool/find.pass.cpp
index 75567a9..a4b5537 100644
--- a/test/std/containers/sequences/vector.bool/find.pass.cpp
+++ b/test/std/containers/sequences/vector.bool/find.pass.cpp
@@ -15,6 +15,7 @@
 // http://llvm.org/bugs/show_bug.cgi?id=16816
 
 #include <vector>
+#include <algorithm>
 #include <cassert>
 
 int main()
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 b580eb4..4dd871c 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
@@ -28,6 +28,32 @@
     some_alloc(const some_alloc&);
 };
 
+template <class T>
+struct some_alloc2
+{
+    typedef T value_type;
+    
+    some_alloc2() {}
+    some_alloc2(const some_alloc2&);
+    void deallocate(void*, unsigned) {}
+
+    typedef std::false_type propagate_on_container_move_assignment;
+    typedef std::true_type is_always_equal;
+};
+
+template <class T>
+struct some_alloc3
+{
+    typedef T value_type;
+    
+    some_alloc3() {}
+    some_alloc3(const some_alloc3&);
+    void deallocate(void*, unsigned) {}
+
+    typedef std::false_type propagate_on_container_move_assignment;
+    typedef std::false_type is_always_equal;
+};
+
 int main()
 {
 #if __has_feature(cxx_noexcept)
@@ -45,7 +71,22 @@
     }
     {
         typedef std::vector<bool, some_alloc<bool>> C;
+#if TEST_STD_VER > 14
+        static_assert( std::is_nothrow_move_assignable<C>::value, "");
+#else
+        static_assert(!std::is_nothrow_move_assignable<C>::value, "");
+#endif
+    }
+#if TEST_STD_VER > 14
+    {  // POCMA false, is_always_equal true
+        typedef std::vector<bool, some_alloc2<bool>> C;
+        static_assert( std::is_nothrow_move_assignable<C>::value, "");
+    }
+    {  // POCMA false, is_always_equal false
+        typedef std::vector<bool, some_alloc3<bool>> C;
         static_assert(!std::is_nothrow_move_assignable<C>::value, "");
     }
 #endif
+
+#endif
 }
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 0000000..ff73669
--- /dev/null
+++ b/test/std/containers/sequences/vector.bool/reference.swap.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+// vector<bool>
+
+// static void swap(reference x, reference y) noexcept;
+
+#include <vector>
+#include <cassert>
+
+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 __has_feature(cxx_noexcept)
+    static_assert((noexcept(v.swap(r1,r2))), "");
+#endif
+
+	assert(!r1);
+	assert( r2);
+	v.swap(r1, r2);
+	assert( r1);
+	assert(!r2);
+}
\ No newline at end of file
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 6f36473..e1dfe4f 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,6 +24,7 @@
 #include <vector>
 #include <cassert>
 
+#include "test_macros.h"
 #include "test_allocator.h"
 
 template <class T>
@@ -51,7 +54,6 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
     {
         typedef std::vector<bool> C;
         C c1, c2;
@@ -85,6 +87,4 @@
         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 b266b3b..4fb03f5 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 @@
     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<
diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/std/containers/sequences/vector/allocator_mismatch.fail.cpp
similarity index 71%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/sequences/vector/allocator_mismatch.fail.cpp
index e16e439..65fdb63 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/sequences/vector/allocator_mismatch.fail.cpp
@@ -8,15 +8,11 @@
 //===----------------------------------------------------------------------===//
 
 // <vector>
-
-// vector<const int> v;  // an extension
+//   The container's value type must be the same as the allocator's value type
 
 #include <vector>
-#include <type_traits>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    std::vector<int, std::allocator<long> > v;
 }
diff --git a/test/std/containers/sequences/vector/types.pass.cpp b/test/std/containers/sequences/vector/types.pass.cpp
index 0fbc7e3..159a265 100644
--- a/test/std/containers/sequences/vector/types.pass.cpp
+++ b/test/std/containers/sequences/vector/types.pass.cpp
@@ -45,6 +45,9 @@
 {
     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 @@
     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), "");
@@ -76,11 +87,22 @@
     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), "");
+    { 
+
+    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.cons/construct_default.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp
index 5e87c07..e0542e7 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 @@
 	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 @@
 	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 36e231a..5542e91 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 @@
 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 @@
     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 7fa748a..f40088e 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 @@
 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 @@
     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 e033895..46e5ecd 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 @@
 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 @@
 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 @@
     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 5b6c498..d3774d1 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 @@
 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 @@
 {
     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 c62b841..4713aa1 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 @@
      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 @@
 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 677963d..1dd48b1 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 @@
 {
     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()
@@ -46,7 +48,7 @@
         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;
@@ -57,8 +59,6 @@
         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]);
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 128328c..47259c7 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 @@
 {
     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 @@
         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/move_assign_noexcept.pass.cpp b/test/std/containers/sequences/vector/vector.cons/move_assign_noexcept.pass.cpp
index 1c4a4f7..c092244 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
@@ -29,6 +29,33 @@
     some_alloc(const some_alloc&);
 };
 
+template <class T>
+struct some_alloc2
+{
+    typedef T value_type;
+    
+    some_alloc2() {}
+    some_alloc2(const some_alloc2&);
+    void deallocate(void*, unsigned) {}
+
+    typedef std::false_type propagate_on_container_move_assignment;
+    typedef std::true_type is_always_equal;
+};
+
+template <class T>
+struct some_alloc3
+{
+    typedef T value_type;
+    
+    some_alloc3() {}
+    some_alloc3(const some_alloc3&);
+    void deallocate(void*, unsigned) {}
+
+    typedef std::false_type propagate_on_container_move_assignment;
+    typedef std::false_type is_always_equal;
+};
+
+
 int main()
 {
 #if __has_feature(cxx_noexcept)
@@ -46,7 +73,24 @@
     }
     {
         typedef std::vector<MoveOnly, some_alloc<MoveOnly>> C;
+    //  In C++17, move assignment for allocators are not allowed to throw
+#if TEST_STD_VER > 14
+        static_assert( std::is_nothrow_move_assignable<C>::value, "");
+#else
+        static_assert(!std::is_nothrow_move_assignable<C>::value, "");
+#endif
+    }
+
+#if TEST_STD_VER > 14
+    {  // POCMA false, is_always_equal true
+        typedef std::vector<MoveOnly, some_alloc2<MoveOnly>> C;
+        static_assert( std::is_nothrow_move_assignable<C>::value, "");
+    }
+    {  // POCMA false, is_always_equal false
+        typedef std::vector<MoveOnly, some_alloc3<MoveOnly>> C;
         static_assert(!std::is_nothrow_move_assignable<C>::value, "");
     }
 #endif
+
+#endif
 }
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 6615a25..7852253 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <vector>
 
 // void push_back(const value_type& x);
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 1d00ff3..258f22e 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"
 
@@ -52,7 +55,6 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
     {
         typedef std::vector<MoveOnly> C;
         C c1, c2;
@@ -86,6 +88,4 @@
         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 0000000..2e3346f
--- /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 0000000..35bcc27
--- /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/sequences/vector/const_value_type.pass.cpp b/test/std/containers/unord/unord.map/allocator_mismatch.fail.cpp
similarity index 63%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/unord/unord.map/allocator_mismatch.fail.cpp
index e16e439..39fcb11 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/unord/unord.map/allocator_mismatch.fail.cpp
@@ -7,16 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <unordered_map>
+//   The container's value type must be the same as the allocator's value type
 
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
+#include <unordered_map>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    std::unordered_map<int, int, std::hash<int>, std::less<int>, std::allocator<long> > m;
 }
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 0000000..d51b1d8
--- /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/load_factor.pass.cpp b/test/std/containers/unord/unord.map/load_factor.pass.cpp
index b25c019..2d6162f 100644
--- a/test/std/containers/unord/unord.map/load_factor.pass.cpp
+++ b/test/std/containers/unord/unord.map/load_factor.pass.cpp
@@ -18,6 +18,7 @@
 #include <unordered_map>
 #include <string>
 #include <cassert>
+#include <cmath>
 #include <cfloat>
 
 #include "test_macros.h"
@@ -40,7 +41,7 @@
             P(80, "eighty"),
         };
         const C c(std::begin(a), std::end(a));
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
     }
     {
         typedef std::unordered_map<int, std::string> C;
@@ -64,7 +65,7 @@
             P(80, "eighty"),
         };
         const C c(std::begin(a), std::end(a));
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
     }
     {
         typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
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 b19a6e6..d9e1d05 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/rehash.pass.cpp b/test/std/containers/unord/unord.map/rehash.pass.cpp
index 84ece23..e1a882c 100644
--- a/test/std/containers/unord/unord.map/rehash.pass.cpp
+++ b/test/std/containers/unord/unord.map/rehash.pass.cpp
@@ -22,6 +22,12 @@
 #include "min_allocator.h"
 
 template <class C>
+void rehash_postcondition(const C& c, size_t n)
+{
+	assert(c.bucket_count() >= c.size() / c.max_load_factor() && c.bucket_count() >= n);
+}
+
+template <class C>
 void test(const C& c)
 {
     assert(c.size() == 4);
@@ -49,13 +55,16 @@
         test(c);
         assert(c.bucket_count() >= 5);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 5);
         test(c);
         c.max_load_factor(2);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 3);
         test(c);
         c.rehash(31);
+        rehash_postcondition(c, 31);
         assert(c.bucket_count() == 31);
         test(c);
     }
@@ -77,13 +86,16 @@
         test(c);
         assert(c.bucket_count() >= 5);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 5);
         test(c);
         c.max_load_factor(2);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 3);
         test(c);
         c.rehash(31);
+        rehash_postcondition(c, 31);
         assert(c.bucket_count() == 31);
         test(c);
     }
diff --git a/test/std/containers/unord/unord.map/reserve.pass.cpp b/test/std/containers/unord/unord.map/reserve.pass.cpp
index 48667cd..bef237f 100644
--- a/test/std/containers/unord/unord.map/reserve.pass.cpp
+++ b/test/std/containers/unord/unord.map/reserve.pass.cpp
@@ -31,6 +31,21 @@
     assert(c.at(4) == "four");
 }
 
+void reserve_invariant(size_t n) // LWG #2156
+{
+    for (size_t i = 0; i < n; ++i)
+    {
+        std::unordered_map<size_t, size_t> c;
+        c.reserve(n);
+        size_t buckets = c.bucket_count();
+        for (size_t j = 0; j < i; ++j)
+        {
+            c[i] = i;
+            assert(buckets == c.bucket_count());
+        }
+    }
+}
+
 int main()
 {
     {
@@ -88,4 +103,5 @@
         test(c);
     }
 #endif
+    reserve_invariant(20);
 }
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 227343e..447bcab 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
@@ -19,6 +19,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -63,7 +64,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
@@ -103,7 +104,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
@@ -144,7 +145,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 d1757d8..7e91253 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
@@ -19,6 +19,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -63,7 +64,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -103,7 +104,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 ac09053..b60fb2c 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
@@ -19,6 +19,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -58,7 +59,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -92,7 +93,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 7a4130b..f3c086f 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
@@ -19,6 +19,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -59,7 +60,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -94,7 +95,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 036008c..f71c48a 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
@@ -20,6 +20,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -61,7 +62,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -97,7 +98,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 7c83192..c028316 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
@@ -20,6 +20,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -62,7 +63,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -99,7 +100,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/move.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/move.pass.cpp
index 1420204..0f40e34 100644
--- a/test/std/containers/unord/unord.map/unord.map.cnstr/move.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.cnstr/move.pass.cpp
@@ -21,6 +21,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -91,7 +92,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
@@ -158,7 +159,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
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 091a72f..72a634f 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
@@ -19,6 +19,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -64,7 +65,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
@@ -105,7 +106,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
@@ -147,7 +148,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
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 f914b30..b63c47a 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
@@ -20,6 +20,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../NotConstructible.h"
@@ -62,7 +63,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -98,7 +99,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 7a0dbce..675949e 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
@@ -21,6 +21,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../NotConstructible.h"
@@ -64,7 +65,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -101,7 +102,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 61eef5b..d55359f 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
@@ -21,6 +21,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../NotConstructible.h"
@@ -65,7 +66,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -103,7 +104,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 99493fa..61f9f21 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
@@ -22,6 +22,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../NotConstructible.h"
@@ -67,7 +68,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -106,7 +107,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 5fd9f9d..04ce91f 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <unordered_map>
 
 // template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
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 c072248..7bc5944 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 @@
         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 @@
         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 @@
         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 @@
         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 c319b5c..f2c694e 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 @@
     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/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 0000000..00c4718
--- /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 a16f097..fe2b247 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"
 
+
+template <class Container>
+void do_insert_cv_test()
+{
+    typedef Container M;
+    typedef std::pair<typename M::iterator, bool> R;
+    typedef typename M::value_type VT;
+    M m;
+
+    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 = 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);
+
+    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);
+
+    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);
+
+    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);
+}
+
 int main()
 {
     {
-        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);
-
-        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);
-
-        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 = c.insert(P(5.5, 4));
-        assert(r.second);
-        assert(c.size() == 3);
-        assert(r.first->first == 5.5);
-        assert(r.first->second == 4);
+        typedef std::unordered_map<double, int> M;
+        do_insert_cv_test<M>();
     }
-#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;
-        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);
-
-        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);
-
-        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 = c.insert(P(5.5, 4));
-        assert(r.second);
-        assert(c.size() == 3);
-        assert(r.first->first == 5.5);
-        assert(r.first->second == 4);
+                            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_rvalue.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_rvalue.pass.cpp
index 1618c10..04d01eb 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 @@
         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 @@
         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 @@
         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 @@
         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 @@
         assert(false);
     }
 #endif
-#endif
 }
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 f53dc6c..faf5b04 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 @@
         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 @@
         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 @@
         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 @@
         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 eabcf2e..adc4d69 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 1056c23..eb41005 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"
 
@@ -116,7 +119,6 @@
 
 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 @@
     static_assert( noexcept(swap(c1, c2)), "");
     }
 #endif
-#endif
 }
diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/std/containers/unord/unord.multimap/allocator_mismatch.fail.cpp
similarity index 62%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/unord/unord.multimap/allocator_mismatch.fail.cpp
index e16e439..3c74095 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/allocator_mismatch.fail.cpp
@@ -7,16 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <unordered_map>
+//   The container's value type must be the same as the allocator's value type
 
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
+#include <unordered_map>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    std::unordered_multimap<int, int, std::hash<int>, std::less<int>, std::allocator<long> > m;
 }
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 0000000..7822224
--- /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/load_factor.pass.cpp b/test/std/containers/unord/unord.multimap/load_factor.pass.cpp
index f407097..52b3f03 100644
--- a/test/std/containers/unord/unord.multimap/load_factor.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/load_factor.pass.cpp
@@ -19,6 +19,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "min_allocator.h"
 
@@ -39,7 +40,7 @@
             P(80, "eighty"),
         };
         const C c(std::begin(a), std::end(a));
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
     }
     {
         typedef std::unordered_multimap<int, std::string> C;
@@ -64,7 +65,7 @@
             P(80, "eighty"),
         };
         const C c(std::begin(a), std::end(a));
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
     }
     {
         typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
diff --git a/test/std/containers/unord/unord.multimap/rehash.pass.cpp b/test/std/containers/unord/unord.multimap/rehash.pass.cpp
index 1d99208..5ef21d3 100644
--- a/test/std/containers/unord/unord.multimap/rehash.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/rehash.pass.cpp
@@ -19,10 +19,17 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "min_allocator.h"
 
 template <class C>
+void rehash_postcondition(const C& c, size_t n)
+{
+	assert(c.bucket_count() >= c.size() / c.max_load_factor() && c.bucket_count() >= n);
+}
+
+template <class C>
 void test(const C& c)
 {
     assert(c.size() == 6);
@@ -56,7 +63,7 @@
     assert(i->second == "four");
     assert(std::distance(c.begin(), c.end()) == c.size());
     assert(std::distance(c.cbegin(), c.cend()) == c.size());
-    assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+    assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
 }
 
 int main()
@@ -77,13 +84,16 @@
         test(c);
         assert(c.bucket_count() >= 7);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 7);
         test(c);
         c.max_load_factor(2);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 3);
         test(c);
         c.rehash(31);
+        rehash_postcondition(c, 31);
         assert(c.bucket_count() == 31);
         test(c);
     }
@@ -105,13 +115,16 @@
         test(c);
         assert(c.bucket_count() >= 7);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 7);
         test(c);
         c.max_load_factor(2);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 3);
         test(c);
         c.rehash(31);
+        rehash_postcondition(c, 31);
         assert(c.bucket_count() == 31);
         test(c);
     }
diff --git a/test/std/containers/unord/unord.multimap/reserve.pass.cpp b/test/std/containers/unord/unord.multimap/reserve.pass.cpp
index 801c744..388b1f6 100644
--- a/test/std/containers/unord/unord.multimap/reserve.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/reserve.pass.cpp
@@ -33,6 +33,21 @@
     assert(c.find(4)->second == "four");
 }
 
+void reserve_invariant(size_t n) // LWG #2156
+{
+    for (size_t i = 0; i < n; ++i)
+    {
+        std::unordered_multimap<size_t, size_t> c;
+        c.reserve(n);
+        size_t buckets = c.bucket_count();
+        for (size_t j = 0; j < i; ++j)
+        {
+            c.insert(std::unordered_multimap<size_t, size_t>::value_type(i,i));
+            assert(buckets == c.bucket_count());
+        }
+    }
+}
+
 int main()
 {
     {
@@ -90,4 +105,5 @@
         test(c);
     }
 #endif
+    reserve_invariant(20);
 }
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 d71838f..06adfd7 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
@@ -19,6 +19,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -77,7 +78,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
@@ -131,7 +132,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
@@ -186,7 +187,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 2a064c5..0fb508f 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
@@ -19,6 +19,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -77,7 +78,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -131,7 +132,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 48239db..8f6710a 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
@@ -19,6 +19,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -77,7 +78,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >());
         assert(c.key_eq() == test_compare<std::equal_to<int> >());
@@ -133,7 +134,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >());
         assert(c.key_eq() == test_compare<std::equal_to<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 ff00546..0962e9b 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
@@ -19,6 +19,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -78,7 +79,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >());
@@ -135,7 +136,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<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 095e9c3..324b0a7 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
@@ -20,6 +20,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -80,7 +81,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
@@ -138,7 +139,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
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 d2f698a..23ae7d1 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
@@ -20,6 +20,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -81,7 +82,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
@@ -140,7 +141,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
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 fd70ff1..b61735e 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
@@ -19,6 +19,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -119,7 +120,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
@@ -219,7 +220,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
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 d958e23..106c29c 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
@@ -21,6 +21,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -86,7 +87,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
@@ -150,7 +151,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
@@ -215,7 +216,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
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 a3fd4d1..ad33b13 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
@@ -20,6 +20,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../NotConstructible.h"
@@ -81,7 +82,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >());
         assert(c.key_eq() == test_compare<std::equal_to<int> >());
@@ -139,7 +140,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >());
         assert(c.key_eq() == test_compare<std::equal_to<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 4e7b1ac..98644c7 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
@@ -21,6 +21,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../NotConstructible.h"
@@ -83,7 +84,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >());
@@ -142,7 +143,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<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 879e681..9a79c30 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
@@ -21,6 +21,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../NotConstructible.h"
@@ -84,7 +85,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
@@ -144,7 +145,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
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 8e42ca7..a5aafb9 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
@@ -22,6 +22,7 @@
 #include <string>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../NotConstructible.h"
@@ -86,7 +87,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
@@ -147,7 +148,7 @@
         assert(i->second == "four");
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
         assert(c.hash_function() == test_hash<std::hash<int> >(8));
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
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 0000000..30f7893
--- /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_hint_rvalue.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_rvalue.pass.cpp
index 7116fa0..d6c0dbd 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 @@
         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 @@
         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 @@
         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 @@
         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 @@
         assert(false);
     }
 #endif
-#endif
 }
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 5a98467..6735b8a 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 @@
         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 @@
         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 @@
         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 @@
         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 37c8119..d7d06ad 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"
 
@@ -115,8 +118,7 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
-	typedef std::pair<const MoveOnly, MoveOnly> MapType;
+    typedef std::pair<const MoveOnly, MoveOnly> V;
     {
         typedef std::unordered_multimap<MoveOnly, MoveOnly> C;
         C c1, c2;
@@ -124,13 +126,13 @@
     }
     {
         typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                           std::equal_to<MoveOnly>, test_allocator<MapType>> C;
+                           std::equal_to<MoveOnly>, test_allocator<V>> C;
         C c1, c2;
         static_assert(noexcept(swap(c1, c2)), "");
     }
     {
         typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                          std::equal_to<MoveOnly>, other_allocator<MapType>> C;
+                          std::equal_to<MoveOnly>, other_allocator<V>> C;
         C c1, c2;
         static_assert(noexcept(swap(c1, c2)), "");
     }
@@ -148,51 +150,49 @@
 
 #if TEST_STD_VER >= 14
     { // POCS allocator, throwable swap for hash, throwable swap for comp
-    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc <MapType>> C;
+    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc <V>> C;
     C c1, c2;
     static_assert(!noexcept(swap(c1, c2)), "");
     }
     { // always equal allocator, throwable swap for hash, throwable swap for comp
-    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MapType>> C;
+    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc2<V>> C;
     C c1, c2;
     static_assert(!noexcept(swap(c1, c2)), "");
     }
     { // POCS allocator, throwable swap for hash, nothrow swap for comp
-    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MapType>> C;
+    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc <V>> C;
     C c1, c2;
     static_assert(!noexcept(swap(c1, c2)), "");
     }
     { // always equal allocator, throwable swap for hash, nothrow swap for comp
-    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MapType>> C;
+    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<V>> C;
     C c1, c2;
     static_assert(!noexcept(swap(c1, c2)), "");
     }
     { // POCS allocator, nothrow swap for hash, throwable swap for comp
-    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc <MapType>> C;
+    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc <V>> C;
     C c1, c2;
     static_assert(!noexcept(swap(c1, c2)), "");
     }
     { // always equal allocator, nothrow swap for hash, throwable swap for comp
-    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MapType>> C;
+    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc2<V>> C;
     C c1, c2;
     static_assert(!noexcept(swap(c1, c2)), "");
     }
     { // POCS allocator, nothrow swap for hash, nothrow swap for comp
-    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MapType>> C;
+    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc <V>> C;
     C c1, c2;
     static_assert( noexcept(swap(c1, c2)), "");
     }
     { // always equal allocator, nothrow swap for hash, nothrow swap for comp
-    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MapType>> C;
+    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<V>> C;
     C c1, c2;
     static_assert( noexcept(swap(c1, c2)), "");
     }
     { // NOT always equal allocator, nothrow swap for hash, nothrow swap for comp
-    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc3<MapType>> C;
+    typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc3<V>> C;
     C c1, c2;
     static_assert( noexcept(swap(c1, c2)), "");
     }
 #endif
-
-#endif
 }
diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/std/containers/unord/unord.multiset/allocator_mismatch.fail.cpp
similarity index 63%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/unord/unord.multiset/allocator_mismatch.fail.cpp
index e16e439..5836cb3 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/allocator_mismatch.fail.cpp
@@ -7,16 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <unordered_set>
+//   The container's value type must be the same as the allocator's value type
 
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
+#include <unordered_set>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    std::unordered_multiset<int, std::hash<int>, std::less<int>, std::allocator<long> > v;
 }
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 0000000..f6d8dc1
--- /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 0000000..ad7bc04
--- /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/load_factor.pass.cpp b/test/std/containers/unord/unord.multiset/load_factor.pass.cpp
index 07980c2..2a5724b 100644
--- a/test/std/containers/unord/unord.multiset/load_factor.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/load_factor.pass.cpp
@@ -18,6 +18,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "min_allocator.h"
 
@@ -38,7 +39,7 @@
             P(80)
         };
         const C c(std::begin(a), std::end(a));
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
     }
     {
         typedef std::unordered_multiset<int> C;
@@ -63,7 +64,7 @@
             P(80)
         };
         const C c(std::begin(a), std::end(a));
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
     }
     {
         typedef std::unordered_multiset<int, std::hash<int>,
diff --git a/test/std/containers/unord/unord.multiset/rehash.pass.cpp b/test/std/containers/unord/unord.multiset/rehash.pass.cpp
index bc8d461..5c7c6aa 100644
--- a/test/std/containers/unord/unord.multiset/rehash.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/rehash.pass.cpp
@@ -21,6 +21,12 @@
 #include "min_allocator.h"
 
 template <class C>
+void rehash_postcondition(const C& c, size_t n)
+{
+	assert(c.bucket_count() >= c.size() / c.max_load_factor() && c.bucket_count() >= n);
+}
+
+template <class C>
 void test(const C& c)
 {
     assert(c.size() == 6);
@@ -48,13 +54,16 @@
         test(c);
         assert(c.bucket_count() >= 7);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 7);
         test(c);
         c.max_load_factor(2);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 3);
         test(c);
         c.rehash(31);
+        rehash_postcondition(c, 31);
         assert(c.bucket_count() == 31);
         test(c);
     }
@@ -76,13 +85,16 @@
         test(c);
         assert(c.bucket_count() >= 7);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 7);
         test(c);
         c.max_load_factor(2);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 3);
         test(c);
         c.rehash(31);
+        rehash_postcondition(c, 31);
         assert(c.bucket_count() == 31);
         test(c);
     }
diff --git a/test/std/containers/unord/unord.multiset/reserve.pass.cpp b/test/std/containers/unord/unord.multiset/reserve.pass.cpp
index 0c17583..1d393a0 100644
--- a/test/std/containers/unord/unord.multiset/reserve.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/reserve.pass.cpp
@@ -30,6 +30,21 @@
     assert(c.count(4) == 1);
 }
 
+void reserve_invariant(size_t n) // LWG #2156
+{
+    for (size_t i = 0; i < n; ++i)
+    {
+        std::unordered_multiset<size_t> c;
+        c.reserve(n);
+        size_t buckets = c.bucket_count();
+        for (size_t j = 0; j < i; ++j)
+        {
+            c.insert(i);
+            assert(buckets == c.bucket_count());
+        }
+    }
+}
+
 int main()
 {
     {
@@ -87,4 +102,5 @@
         test(c);
     }
 #endif
+    reserve_invariant(20);
 }
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 9424183..a91ee1d 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
@@ -18,6 +18,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -69,7 +70,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
@@ -116,7 +117,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
@@ -164,7 +165,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 22e372b..32c876d 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
@@ -18,6 +18,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -69,7 +70,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -116,7 +117,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 a6543a0..ad42d76 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
@@ -18,6 +18,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -56,7 +57,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -89,7 +90,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 7d0f371..7cc50fa 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
@@ -19,6 +19,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -58,7 +59,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -92,7 +93,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 cd013f9..18d3c82 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
@@ -19,6 +19,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -59,7 +60,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -94,7 +95,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 4621c7f..92d9d86 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
@@ -19,6 +19,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -60,7 +61,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -96,7 +97,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 a68cfe8..687f265 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
@@ -18,6 +18,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -97,7 +98,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
@@ -173,7 +174,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
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 9eee69a..c03c605 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
@@ -18,6 +18,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -71,7 +72,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
@@ -112,7 +113,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
@@ -162,7 +163,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
@@ -203,7 +204,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
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 4f5e03e..f2d0db9 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
@@ -19,6 +19,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../test_compare.h"
@@ -59,7 +60,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -94,7 +95,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 6b83bde..dc40b36 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
@@ -20,6 +20,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../test_compare.h"
@@ -61,7 +62,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -97,7 +98,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 89e7c7f..c316b78 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
@@ -20,6 +20,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../test_compare.h"
@@ -62,7 +63,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -99,7 +100,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 b712a96..ab76248 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
@@ -21,6 +21,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../test_compare.h"
@@ -64,7 +65,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -102,7 +103,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.swap/swap_noexcept.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.swap/swap_noexcept.pass.cpp
index 63642fc..b7d61fd 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"
 
@@ -115,7 +118,6 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
     {
         typedef std::unordered_multiset<MoveOnly> C;
         C c1, c2;
@@ -193,6 +195,4 @@
     static_assert( noexcept(swap(c1, c2)), "");
     }
 #endif
-
-#endif
 }
diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/std/containers/unord/unord.set/allocator_mismatch.fail.cpp
similarity index 63%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/containers/unord/unord.set/allocator_mismatch.fail.cpp
index e16e439..b87c9a2 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/containers/unord/unord.set/allocator_mismatch.fail.cpp
@@ -7,16 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <unordered_set>
+//   The container's value type must be the same as the allocator's value type
 
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
+#include <unordered_set>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    std::unordered_set<int, std::hash<int>, std::less<int>, std::allocator<long> > v;
 }
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 0000000..c970c1d
--- /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 0000000..e85e945
--- /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/load_factor.pass.cpp b/test/std/containers/unord/unord.set/load_factor.pass.cpp
index e0ed169..3e56442 100644
--- a/test/std/containers/unord/unord.set/load_factor.pass.cpp
+++ b/test/std/containers/unord/unord.set/load_factor.pass.cpp
@@ -18,6 +18,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "min_allocator.h"
 
@@ -38,7 +39,7 @@
             P(80)
         };
         const C c(std::begin(a), std::end(a));
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
     }
     {
         typedef std::unordered_set<int> C;
@@ -63,7 +64,7 @@
             P(80)
         };
         const C c(std::begin(a), std::end(a));
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
     }
     {
         typedef std::unordered_set<int, std::hash<int>,
diff --git a/test/std/containers/unord/unord.set/rehash.pass.cpp b/test/std/containers/unord/unord.set/rehash.pass.cpp
index 30fffa5..e28c25d 100644
--- a/test/std/containers/unord/unord.set/rehash.pass.cpp
+++ b/test/std/containers/unord/unord.set/rehash.pass.cpp
@@ -21,6 +21,12 @@
 #include "min_allocator.h"
 
 template <class C>
+void rehash_postcondition(const C& c, size_t n)
+{
+	assert(c.bucket_count() >= c.size() / c.max_load_factor() && c.bucket_count() >= n);
+}
+
+template <class C>
 void test(const C& c)
 {
     assert(c.size() == 4);
@@ -48,13 +54,16 @@
         test(c);
         assert(c.bucket_count() >= 5);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 5);
         test(c);
         c.max_load_factor(2);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 3);
         test(c);
         c.rehash(31);
+        rehash_postcondition(c, 31);
         assert(c.bucket_count() == 31);
         test(c);
     }
@@ -76,13 +85,16 @@
         test(c);
         assert(c.bucket_count() >= 5);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 5);
         test(c);
         c.max_load_factor(2);
         c.rehash(3);
+        rehash_postcondition(c, 3);
         assert(c.bucket_count() == 3);
         test(c);
         c.rehash(31);
+        rehash_postcondition(c, 31);
         assert(c.bucket_count() == 31);
         test(c);
     }
diff --git a/test/std/containers/unord/unord.set/reserve.pass.cpp b/test/std/containers/unord/unord.set/reserve.pass.cpp
index 7d6656a..078b886 100644
--- a/test/std/containers/unord/unord.set/reserve.pass.cpp
+++ b/test/std/containers/unord/unord.set/reserve.pass.cpp
@@ -30,6 +30,21 @@
     assert(c.count(4) == 1);
 }
 
+void reserve_invariant(size_t n) // LWG #2156
+{
+    for (size_t i = 0; i < n; ++i)
+    {
+        std::unordered_set<size_t> c;
+        c.reserve(n);
+        size_t buckets = c.bucket_count();
+        for (size_t j = 0; j < i; ++j)
+        {
+            c.insert(i);
+            assert(buckets == c.bucket_count());
+        }
+    }
+}
+
 int main()
 {
     {
@@ -87,4 +102,5 @@
         test(c);
     }
 #endif
+    reserve_invariant(20);
 }
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 ee05acd..e1a9b27 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
@@ -18,6 +18,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -61,7 +62,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
@@ -100,7 +101,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
@@ -140,7 +141,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 8e1ecd8..b31875b 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
@@ -18,6 +18,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -61,7 +62,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -100,7 +101,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 36dab79..340fc41 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
@@ -18,6 +18,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -56,7 +57,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -89,7 +90,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 81af2b4..fa6f0bd 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
@@ -19,6 +19,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -58,7 +59,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -92,7 +93,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 f35dd1a..dc3a665 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
@@ -19,6 +19,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -59,7 +60,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -94,7 +95,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 34ff62e..1b006db 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
@@ -19,6 +19,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -60,7 +61,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -96,7 +97,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 6bda4af..f2a2a68 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
@@ -18,6 +18,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -97,7 +98,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
@@ -173,7 +174,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
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 229e799..92eb36d 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
@@ -18,6 +18,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
@@ -63,7 +64,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
@@ -104,7 +105,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
@@ -146,7 +147,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
 
         assert(c0.empty());
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 179f73d..ff50c71 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
@@ -19,6 +19,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../test_compare.h"
@@ -59,7 +60,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -94,7 +95,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 60350de..bcdcc55 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
@@ -20,6 +20,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../test_compare.h"
@@ -61,7 +62,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -97,7 +98,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 70e82d0..632265a 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
@@ -20,6 +20,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../test_compare.h"
@@ -62,7 +63,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -99,7 +100,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
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 a6fb2e6..ebe54fd 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
@@ -21,6 +21,7 @@
 #include <unordered_set>
 #include <cassert>
 #include <cfloat>
+#include <cmath>
 
 #include "test_iterators.h"
 #include "../../../test_compare.h"
@@ -64,7 +65,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #if __cplusplus >= 201103L
@@ -102,7 +103,7 @@
         assert(!c.empty());
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
-        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
 #endif
diff --git a/test/std/containers/unord/unord.set/unord.set.swap/swap_noexcept.pass.cpp b/test/std/containers/unord/unord.set/unord.set.swap/swap_noexcept.pass.cpp
index 5d74640..a9c0331 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"
 
@@ -115,7 +118,6 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
     {
         typedef std::unordered_set<MoveOnly> C;
         C c1, c2;
@@ -193,6 +195,4 @@
     static_assert( noexcept(swap(c1, c2)), "");
     }
 #endif
-
-#endif
 }
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 f2fcf49..0da4c9d 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 a799aea..ff045a9 100644
--- a/test/std/depr/depr.c.headers/inttypes_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/inttypes_h.pass.cpp
@@ -12,6 +12,250 @@
 #include <inttypes.h>
 #include <type_traits>
 
+#ifndef INT8_MIN
+#error INT8_MIN not defined
+#endif
+
+#ifndef INT16_MIN
+#error INT16_MIN not defined
+#endif
+
+#ifndef INT32_MIN
+#error INT32_MIN not defined
+#endif
+
+#ifndef INT64_MIN
+#error INT64_MIN not defined
+#endif
+
+#ifndef INT8_MAX
+#error INT8_MAX not defined
+#endif
+
+#ifndef INT16_MAX
+#error INT16_MAX not defined
+#endif
+
+#ifndef INT32_MAX
+#error INT32_MAX not defined
+#endif
+
+#ifndef INT64_MAX
+#error INT64_MAX not defined
+#endif
+
+#ifndef UINT8_MAX
+#error UINT8_MAX not defined
+#endif
+
+#ifndef UINT16_MAX
+#error UINT16_MAX not defined
+#endif
+
+#ifndef UINT32_MAX
+#error UINT32_MAX not defined
+#endif
+
+#ifndef UINT64_MAX
+#error UINT64_MAX not defined
+#endif
+
+#ifndef INT_LEAST8_MIN
+#error INT_LEAST8_MIN not defined
+#endif
+
+#ifndef INT_LEAST16_MIN
+#error INT_LEAST16_MIN not defined
+#endif
+
+#ifndef INT_LEAST32_MIN
+#error INT_LEAST32_MIN not defined
+#endif
+
+#ifndef INT_LEAST64_MIN
+#error INT_LEAST64_MIN not defined
+#endif
+
+#ifndef INT_LEAST8_MAX
+#error INT_LEAST8_MAX not defined
+#endif
+
+#ifndef INT_LEAST16_MAX
+#error INT_LEAST16_MAX not defined
+#endif
+
+#ifndef INT_LEAST32_MAX
+#error INT_LEAST32_MAX not defined
+#endif
+
+#ifndef INT_LEAST64_MAX
+#error INT_LEAST64_MAX not defined
+#endif
+
+#ifndef UINT_LEAST8_MAX
+#error UINT_LEAST8_MAX not defined
+#endif
+
+#ifndef UINT_LEAST16_MAX
+#error UINT_LEAST16_MAX not defined
+#endif
+
+#ifndef UINT_LEAST32_MAX
+#error UINT_LEAST32_MAX not defined
+#endif
+
+#ifndef UINT_LEAST64_MAX
+#error UINT_LEAST64_MAX not defined
+#endif
+
+#ifndef INT_FAST8_MIN
+#error INT_FAST8_MIN not defined
+#endif
+
+#ifndef INT_FAST16_MIN
+#error INT_FAST16_MIN not defined
+#endif
+
+#ifndef INT_FAST32_MIN
+#error INT_FAST32_MIN not defined
+#endif
+
+#ifndef INT_FAST64_MIN
+#error INT_FAST64_MIN not defined
+#endif
+
+#ifndef INT_FAST8_MAX
+#error INT_FAST8_MAX not defined
+#endif
+
+#ifndef INT_FAST16_MAX
+#error INT_FAST16_MAX not defined
+#endif
+
+#ifndef INT_FAST32_MAX
+#error INT_FAST32_MAX not defined
+#endif
+
+#ifndef INT_FAST64_MAX
+#error INT_FAST64_MAX not defined
+#endif
+
+#ifndef UINT_FAST8_MAX
+#error UINT_FAST8_MAX not defined
+#endif
+
+#ifndef UINT_FAST16_MAX
+#error UINT_FAST16_MAX not defined
+#endif
+
+#ifndef UINT_FAST32_MAX
+#error UINT_FAST32_MAX not defined
+#endif
+
+#ifndef UINT_FAST64_MAX
+#error UINT_FAST64_MAX not defined
+#endif
+
+#ifndef INTPTR_MIN
+#error INTPTR_MIN not defined
+#endif
+
+#ifndef INTPTR_MAX
+#error INTPTR_MAX not defined
+#endif
+
+#ifndef UINTPTR_MAX
+#error UINTPTR_MAX not defined
+#endif
+
+#ifndef INTMAX_MIN
+#error INTMAX_MIN not defined
+#endif
+
+#ifndef INTMAX_MAX
+#error INTMAX_MAX not defined
+#endif
+
+#ifndef UINTMAX_MAX
+#error UINTMAX_MAX not defined
+#endif
+
+#ifndef PTRDIFF_MIN
+#error PTRDIFF_MIN not defined
+#endif
+
+#ifndef PTRDIFF_MAX
+#error PTRDIFF_MAX not defined
+#endif
+
+#ifndef SIG_ATOMIC_MIN
+#error SIG_ATOMIC_MIN not defined
+#endif
+
+#ifndef SIG_ATOMIC_MAX
+#error SIG_ATOMIC_MAX not defined
+#endif
+
+#ifndef SIZE_MAX
+#error SIZE_MAX not defined
+#endif
+
+#ifndef WCHAR_MIN
+#error WCHAR_MIN not defined
+#endif
+
+#ifndef WCHAR_MAX
+#error WCHAR_MAX not defined
+#endif
+
+#ifndef WINT_MIN
+#error WINT_MIN not defined
+#endif
+
+#ifndef WINT_MAX
+#error WINT_MAX not defined
+#endif
+
+#ifndef INT8_C
+#error INT8_C not defined
+#endif
+
+#ifndef INT16_C
+#error INT16_C not defined
+#endif
+
+#ifndef INT32_C
+#error INT32_C not defined
+#endif
+
+#ifndef INT64_C
+#error INT64_C not defined
+#endif
+
+#ifndef UINT8_C
+#error UINT8_C not defined
+#endif
+
+#ifndef UINT16_C
+#error UINT16_C not defined
+#endif
+
+#ifndef UINT32_C
+#error UINT32_C not defined
+#endif
+
+#ifndef UINT64_C
+#error UINT64_C not defined
+#endif
+
+#ifndef INTMAX_C
+#error INTMAX_C not defined
+#endif
+
+#ifndef UINTMAX_C
+#error UINTMAX_C not defined
+#endif
+
 #ifndef PRId8
 #error PRId8 not defined
 #endif
@@ -631,8 +875,49 @@
 int main()
 {
     {
-      imaxdiv_t  i1 = {0};
-      ((void)i1);
+    int8_t  i1 = 0;
+    int16_t i2 = 0;
+    int32_t i3 = 0;
+    int64_t i4 = 0;
+    }
+    {
+    uint8_t  i1 = 0;
+    uint16_t i2 = 0;
+    uint32_t i3 = 0;
+    uint64_t i4 = 0;
+    }
+    {
+    int_least8_t  i1 = 0;
+    int_least16_t i2 = 0;
+    int_least32_t i3 = 0;
+    int_least64_t i4 = 0;
+    }
+    {
+    uint_least8_t  i1 = 0;
+    uint_least16_t i2 = 0;
+    uint_least32_t i3 = 0;
+    uint_least64_t i4 = 0;
+    }
+    {
+    int_fast8_t  i1 = 0;
+    int_fast16_t i2 = 0;
+    int_fast32_t i3 = 0;
+    int_fast64_t i4 = 0;
+    }
+    {
+    uint_fast8_t  i1 = 0;
+    uint_fast16_t i2 = 0;
+    uint_fast32_t i3 = 0;
+    uint_fast64_t i4 = 0;
+    }
+    {
+    intptr_t  i1 = 0;
+    uintptr_t i2 = 0;
+    intmax_t  i3 = 0;
+    uintmax_t i4 = 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 b03a61b..ed12fcf 100644
--- a/test/std/depr/depr.c.headers/math_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/math_h.pass.cpp
@@ -9,7 +9,8 @@
 
 // <math.h>
 
-// XFAIL: linux
+// 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>
@@ -17,498 +18,1168 @@
 
 #include "hexfloat.h"
 
+// convertible to int/float/double/etc
+template <class T, int N=0>
+struct Value {
+    operator T () { return T(N); }
+};
+
+// See PR21083
+// Ambiguous is a user-defined type that defines its own overloads of cmath
+// functions. When the std overloads are candidates too (by using or adl),
+// they should not interfere.
+struct Ambiguous : std::true_type { // ADL
+    operator float () { return 0.f; }
+    operator double () { return 0.; }
+};
+Ambiguous abs(Ambiguous){ return Ambiguous(); }
+Ambiguous acos(Ambiguous){ return Ambiguous(); }
+Ambiguous asin(Ambiguous){ return Ambiguous(); }
+Ambiguous atan(Ambiguous){ return Ambiguous(); }
+Ambiguous atan2(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous ceil(Ambiguous){ return Ambiguous(); }
+Ambiguous cos(Ambiguous){ return Ambiguous(); }
+Ambiguous cosh(Ambiguous){ return Ambiguous(); }
+Ambiguous exp(Ambiguous){ return Ambiguous(); }
+Ambiguous fabs(Ambiguous){ return Ambiguous(); }
+Ambiguous floor(Ambiguous){ return Ambiguous(); }
+Ambiguous fmod(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous frexp(Ambiguous, int*){ return Ambiguous(); }
+Ambiguous ldexp(Ambiguous, int){ return Ambiguous(); }
+Ambiguous log(Ambiguous){ return Ambiguous(); }
+Ambiguous log10(Ambiguous){ return Ambiguous(); }
+Ambiguous modf(Ambiguous, Ambiguous*){ return Ambiguous(); }
+Ambiguous pow(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous sin(Ambiguous){ return Ambiguous(); }
+Ambiguous sinh(Ambiguous){ return Ambiguous(); }
+Ambiguous sqrt(Ambiguous){ return Ambiguous(); }
+Ambiguous tan(Ambiguous){ return Ambiguous(); }
+Ambiguous tanh(Ambiguous){ return Ambiguous(); }
+Ambiguous signbit(Ambiguous){ return Ambiguous(); }
+Ambiguous fpclassify(Ambiguous){ return Ambiguous(); }
+Ambiguous isfinite(Ambiguous){ return Ambiguous(); }
+Ambiguous isnormal(Ambiguous){ return Ambiguous(); }
+Ambiguous isgreater(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous isgreaterequal(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous isless(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous islessequal(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous islessgreater(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous isunordered(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous acosh(Ambiguous){ return Ambiguous(); }
+Ambiguous asinh(Ambiguous){ return Ambiguous(); }
+Ambiguous atanh(Ambiguous){ return Ambiguous(); }
+Ambiguous cbrt(Ambiguous){ return Ambiguous(); }
+Ambiguous copysign(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous erf(Ambiguous){ return Ambiguous(); }
+Ambiguous erfc(Ambiguous){ return Ambiguous(); }
+Ambiguous exp2(Ambiguous){ return Ambiguous(); }
+Ambiguous expm1(Ambiguous){ return Ambiguous(); }
+Ambiguous fdim(Ambiguous, Ambiguous){ return Ambiguous(); }
+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 ilogb(Ambiguous){ return Ambiguous(); }
+Ambiguous lgamma(Ambiguous){ return Ambiguous(); }
+Ambiguous llrint(Ambiguous){ return Ambiguous(); }
+Ambiguous llround(Ambiguous){ return Ambiguous(); }
+Ambiguous log1p(Ambiguous){ return Ambiguous(); }
+Ambiguous log2(Ambiguous){ return Ambiguous(); }
+Ambiguous logb(Ambiguous){ return Ambiguous(); }
+Ambiguous lrint(Ambiguous){ return Ambiguous(); }
+Ambiguous lround(Ambiguous){ return Ambiguous(); }
+Ambiguous nearbyint(Ambiguous){ return Ambiguous(); }
+Ambiguous nextafter(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous nexttoward(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous remainder(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous remquo(Ambiguous, Ambiguous, int*){ return Ambiguous(); }
+Ambiguous rint(Ambiguous){ return Ambiguous(); }
+Ambiguous round(Ambiguous){ return Ambiguous(); }
+Ambiguous scalbln(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous scalbn(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous tgamma(Ambiguous){ return Ambiguous(); }
+Ambiguous trunc(Ambiguous){ return Ambiguous(); }
+
+void test_abs()
+{
+    static_assert((std::is_same<decltype(abs((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(abs((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(abs((long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(abs(Ambiguous())), Ambiguous>::value), "");
+    assert(abs(-1.) == 1);
+}
+
 void test_acos()
 {
+    static_assert((std::is_same<decltype(acos((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(acos((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acos((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acos((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acos((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acos((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acos((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acos((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acos((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(acos((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acos((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(acosf(0)), float>::value), "");
     static_assert((std::is_same<decltype(acosl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(acos(Ambiguous())), Ambiguous>::value), "");
     assert(acos(1) == 0);
 }
 
 void test_asin()
 {
+    static_assert((std::is_same<decltype(asin((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(asin((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asin((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asin((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asin((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asin((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asin((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asin((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asin((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(asin((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asin((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(asinf(0)), float>::value), "");
     static_assert((std::is_same<decltype(asinl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(asin(Ambiguous())), Ambiguous>::value), "");
     assert(asin(0) == 0);
 }
 
 void test_atan()
 {
+    static_assert((std::is_same<decltype(atan((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(atan((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(atan((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(atanf(0)), float>::value), "");
     static_assert((std::is_same<decltype(atanl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(atan(Ambiguous())), Ambiguous>::value), "");
     assert(atan(0) == 0);
 }
 
 void test_atan2()
 {
+    static_assert((std::is_same<decltype(atan2((float)0, (float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(atan2((bool)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan2((unsigned short)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan2((int)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(atan2((float)0, (unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan2((double)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan2((long double)0, (unsigned long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(atan2((int)0, (long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan2((int)0, (unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(atan2((double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan2((long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(atan2((float)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan2((float)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(atan2((double)0, (long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(atan2f(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(atan2l(0,0)), long double>::value), "");
+    static_assert((std::is_same<decltype(atan2((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan2(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(atan2(0,1) == 0);
 }
 
 void test_ceil()
 {
+    static_assert((std::is_same<decltype(ceil((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(ceil((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(ceil((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(ceil((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(ceil((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(ceil((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(ceil((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(ceil((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(ceil((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(ceil((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(ceil((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(ceilf(0)), float>::value), "");
     static_assert((std::is_same<decltype(ceill(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(ceil(Ambiguous())), Ambiguous>::value), "");
     assert(ceil(0) == 0);
 }
 
 void test_cos()
 {
+    static_assert((std::is_same<decltype(cos((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(cos((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cos((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cos((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cos((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cos((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cos((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cos((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cos((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(cos((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cos((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(cosf(0)), float>::value), "");
     static_assert((std::is_same<decltype(cosl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(cos(Ambiguous())), Ambiguous>::value), "");
     assert(cos(0) == 1);
 }
 
 void test_cosh()
 {
+    static_assert((std::is_same<decltype(cosh((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(cosh((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cosh((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cosh((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cosh((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cosh((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cosh((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cosh((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cosh((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(cosh((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cosh((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(coshf(0)), float>::value), "");
     static_assert((std::is_same<decltype(coshl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(cosh(Ambiguous())), Ambiguous>::value), "");
     assert(cosh(0) == 1);
 }
 
 void test_exp()
 {
+    static_assert((std::is_same<decltype(exp((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(exp((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(exp((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(expf(0)), float>::value), "");
     static_assert((std::is_same<decltype(expl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(exp(Ambiguous())), Ambiguous>::value), "");
     assert(exp(0) == 1);
 }
 
 void test_fabs()
 {
+    static_assert((std::is_same<decltype(fabs((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(fabs((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fabs((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fabs((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fabs((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fabs((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fabs((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fabs((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fabs((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(fabs((double)0)), double>::value), "");
-    static_assert((std::is_same<decltype(fabsf(0.f)), float>::value), "");
-    static_assert((std::is_same<decltype(fabsl(0.L)), long double>::value), "");
-    assert(fabs(-1.f) == 1);
+    static_assert((std::is_same<decltype(fabs((long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fabsf(0.0f)), float>::value), "");
+    static_assert((std::is_same<decltype(fabsl(0.0L)), long double>::value), "");
+    static_assert((std::is_same<decltype(fabs(Ambiguous())), Ambiguous>::value), "");
+    assert(fabs(-1) == 1);
 }
 
 void test_floor()
 {
+    static_assert((std::is_same<decltype(floor((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(floor((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(floor((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(floor((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(floor((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(floor((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(floor((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(floor((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(floor((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(floor((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(floor((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(floorf(0)), float>::value), "");
     static_assert((std::is_same<decltype(floorl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(floor(Ambiguous())), Ambiguous>::value), "");
     assert(floor(1) == 1);
 }
 
 void test_fmod()
 {
+    static_assert((std::is_same<decltype(fmod((float)0, (float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(fmod((bool)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmod((unsigned short)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmod((int)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmod((float)0, (unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmod((double)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmod((long double)0, (unsigned long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmod((int)0, (long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmod((int)0, (unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(fmod((double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmod((long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmod((float)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmod((float)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmod((double)0, (long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(fmodf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(fmodl(0,0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmod((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmod(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(fmod(1.5,1) == .5);
 }
 
 void test_frexp()
 {
     int ip;
+    static_assert((std::is_same<decltype(frexp((float)0, &ip)), float>::value), "");
+    static_assert((std::is_same<decltype(frexp((bool)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(frexp((unsigned short)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(frexp((int)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(frexp((unsigned int)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(frexp((long)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(frexp((unsigned long)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(frexp((long long)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(frexp((unsigned long long)0, &ip)), double>::value), "");
     static_assert((std::is_same<decltype(frexp((double)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(frexp((long double)0, &ip)), long double>::value), "");
     static_assert((std::is_same<decltype(frexpf(0, &ip)), float>::value), "");
     static_assert((std::is_same<decltype(frexpl(0, &ip)), long double>::value), "");
+    static_assert((std::is_same<decltype(frexp(Ambiguous(), &ip)), Ambiguous>::value), "");
     assert(frexp(0, &ip) == 0);
 }
 
 void test_ldexp()
 {
     int ip = 1;
+    static_assert((std::is_same<decltype(ldexp((float)0, ip)), float>::value), "");
+    static_assert((std::is_same<decltype(ldexp((bool)0, ip)), double>::value), "");
+    static_assert((std::is_same<decltype(ldexp((unsigned short)0, ip)), double>::value), "");
+    static_assert((std::is_same<decltype(ldexp((int)0, ip)), double>::value), "");
+    static_assert((std::is_same<decltype(ldexp((unsigned int)0, ip)), double>::value), "");
+    static_assert((std::is_same<decltype(ldexp((long)0, ip)), double>::value), "");
+    static_assert((std::is_same<decltype(ldexp((unsigned long)0, ip)), double>::value), "");
+    static_assert((std::is_same<decltype(ldexp((long long)0, ip)), double>::value), "");
+    static_assert((std::is_same<decltype(ldexp((unsigned long long)0, ip)), double>::value), "");
     static_assert((std::is_same<decltype(ldexp((double)0, ip)), double>::value), "");
+    static_assert((std::is_same<decltype(ldexp((long double)0, ip)), long double>::value), "");
     static_assert((std::is_same<decltype(ldexpf(0, ip)), float>::value), "");
     static_assert((std::is_same<decltype(ldexpl(0, ip)), long double>::value), "");
+    static_assert((std::is_same<decltype(ldexp(Ambiguous(), ip)), Ambiguous>::value), "");
     assert(ldexp(1, ip) == 2);
 }
 
 void test_log()
 {
+    static_assert((std::is_same<decltype(log((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(log((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(log((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(logf(0)), float>::value), "");
     static_assert((std::is_same<decltype(logl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(log(Ambiguous())), Ambiguous>::value), "");
     assert(log(1) == 0);
 }
 
 void test_log10()
 {
+    static_assert((std::is_same<decltype(log10((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(log10((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log10((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log10((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log10((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log10((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log10((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log10((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log10((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(log10((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log10((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(log10f(0)), float>::value), "");
     static_assert((std::is_same<decltype(log10l(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(log10(Ambiguous())), Ambiguous>::value), "");
     assert(log10(1) == 0);
 }
 
 void test_modf()
 {
+    static_assert((std::is_same<decltype(modf((float)0, (float*)0)), float>::value), "");
     static_assert((std::is_same<decltype(modf((double)0, (double*)0)), double>::value), "");
+    static_assert((std::is_same<decltype(modf((long double)0, (long double*)0)), long double>::value), "");
     static_assert((std::is_same<decltype(modff(0, (float*)0)), float>::value), "");
     static_assert((std::is_same<decltype(modfl(0, (long double*)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(modf(Ambiguous(), (Ambiguous*)0)), Ambiguous>::value), "");
     double i;
     assert(modf(1., &i) == 0);
 }
 
 void test_pow()
 {
+    static_assert((std::is_same<decltype(pow((float)0, (float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(pow((bool)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(pow((unsigned short)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(pow((int)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(pow((float)0, (unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(pow((double)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(pow((long double)0, (unsigned long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(pow((int)0, (long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(pow((int)0, (unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(pow((double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(pow((long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(pow((float)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(pow((float)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(pow((double)0, (long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(powf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(powl(0,0)), long double>::value), "");
+    static_assert((std::is_same<decltype(pow((int)0, (int)0)), double>::value), "");
+//     static_assert((std::is_same<decltype(pow(Value<int>(), (int)0)), double>::value), "");
+//     static_assert((std::is_same<decltype(pow(Value<long double>(), (float)0)), long double>::value), "");
+//     static_assert((std::is_same<decltype(pow((float) 0, Value<float>())), float>::value), "");
+    static_assert((std::is_same<decltype(pow(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(pow(1,1) == 1);
+//     assert(pow(Value<int,1>(), Value<float,1>())  == 1);
+//     assert(pow(1.0f, Value<double,1>()) == 1);
+//     assert(pow(1.0, Value<int,1>()) == 1);
+//     assert(pow(Value<long double,1>(), 1LL) == 1);
 }
 
 void test_sin()
 {
+    static_assert((std::is_same<decltype(sin((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(sin((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sin((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sin((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sin((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sin((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sin((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sin((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sin((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(sin((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sin((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(sinf(0)), float>::value), "");
     static_assert((std::is_same<decltype(sinl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(sin(Ambiguous())), Ambiguous>::value), "");
     assert(sin(0) == 0);
 }
 
 void test_sinh()
 {
+    static_assert((std::is_same<decltype(sinh((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(sinh((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sinh((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sinh((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sinh((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sinh((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sinh((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sinh((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sinh((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(sinh((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sinh((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(sinhf(0)), float>::value), "");
     static_assert((std::is_same<decltype(sinhl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(sinh(Ambiguous())), Ambiguous>::value), "");
     assert(sinh(0) == 0);
 }
 
 void test_sqrt()
 {
+    static_assert((std::is_same<decltype(sqrt((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(sqrt((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sqrt((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sqrt((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sqrt((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sqrt((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sqrt((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sqrt((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sqrt((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(sqrt((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(sqrt((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(sqrtf(0)), float>::value), "");
     static_assert((std::is_same<decltype(sqrtl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(sqrt(Ambiguous())), Ambiguous>::value), "");
     assert(sqrt(4) == 2);
 }
 
 void test_tan()
 {
+    static_assert((std::is_same<decltype(tan((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(tan((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tan((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tan((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tan((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tan((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tan((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tan((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tan((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(tan((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tan((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(tanf(0)), float>::value), "");
     static_assert((std::is_same<decltype(tanl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(tan(Ambiguous())), Ambiguous>::value), "");
     assert(tan(0) == 0);
 }
 
 void test_tanh()
 {
+    static_assert((std::is_same<decltype(tanh((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(tanh((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tanh((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tanh((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tanh((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tanh((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tanh((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tanh((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tanh((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(tanh((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tanh((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(tanhf(0)), float>::value), "");
     static_assert((std::is_same<decltype(tanhl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(tanh(Ambiguous())), Ambiguous>::value), "");
     assert(tanh(0) == 0);
 }
 
 void test_signbit()
 {
+#ifdef signbit
+#error signbit defined
+#endif
     static_assert((std::is_same<decltype(signbit((float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(signbit((double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(signbit(0)), bool>::value), "");
     static_assert((std::is_same<decltype(signbit((long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(signbit(Ambiguous())), Ambiguous>::value), "");
     assert(signbit(-1.0) == true);
 }
 
 void test_fpclassify()
 {
+#ifdef fpclassify
+#error fpclassify defined
+#endif
     static_assert((std::is_same<decltype(fpclassify((float)0)), int>::value), "");
     static_assert((std::is_same<decltype(fpclassify((double)0)), int>::value), "");
+    static_assert((std::is_same<decltype(fpclassify(0)), int>::value), "");
     static_assert((std::is_same<decltype(fpclassify((long double)0)), int>::value), "");
+    static_assert((std::is_same<decltype(fpclassify(Ambiguous())), Ambiguous>::value), "");
     assert(fpclassify(-1.0) == FP_NORMAL);
 }
 
 void test_isfinite()
 {
+#ifdef isfinite
+#error isfinite defined
+#endif
     static_assert((std::is_same<decltype(isfinite((float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isfinite((double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isfinite(0)), bool>::value), "");
     static_assert((std::is_same<decltype(isfinite((long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isfinite(Ambiguous())), Ambiguous>::value), "");
     assert(isfinite(-1.0) == true);
 }
 
-void test_isinf()
-{
-    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((long double)0)), bool>::value), "");
-    assert(isinf(-1.0) == false);
-}
-
-void test_isnan()
-{
-    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((long double)0)), bool>::value), "");
-    assert(isnan(-1.0) == false);
-}
-
 void test_isnormal()
 {
+#ifdef isnormal
+#error isnormal defined
+#endif
     static_assert((std::is_same<decltype(isnormal((float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isnormal((double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isnormal(0)), bool>::value), "");
     static_assert((std::is_same<decltype(isnormal((long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isnormal(Ambiguous())), Ambiguous>::value), "");
     assert(isnormal(-1.0) == true);
 }
 
 void test_isgreater()
 {
+#ifdef isgreater
+#error isgreater defined
+#endif
     static_assert((std::is_same<decltype(isgreater((float)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreater((float)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreater((float)0, (long double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreater((double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreater((double)0, (double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isgreater(0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreater((double)0, (long double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreater((long double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreater((long double)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreater((long double)0, (long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isgreater(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(isgreater(-1.0, 0.F) == false);
 }
 
 void test_isgreaterequal()
 {
+#ifdef isgreaterequal
+#error isgreaterequal defined
+#endif
     static_assert((std::is_same<decltype(isgreaterequal((float)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreaterequal((float)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreaterequal((float)0, (long double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreaterequal((double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreaterequal((double)0, (double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isgreaterequal(0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreaterequal((double)0, (long double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreaterequal((long double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreaterequal((long double)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isgreaterequal((long double)0, (long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isgreaterequal(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(isgreaterequal(-1.0, 0.F) == false);
 }
 
 void test_isless()
 {
+#ifdef isless
+#error isless defined
+#endif
     static_assert((std::is_same<decltype(isless((float)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isless((float)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isless((float)0, (long double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isless((double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isless((double)0, (double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isless(0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isless((double)0, (long double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isless((long double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isless((long double)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isless((long double)0, (long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isless(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(isless(-1.0, 0.F) == true);
 }
 
 void test_islessequal()
 {
+#ifdef islessequal
+#error islessequal defined
+#endif
     static_assert((std::is_same<decltype(islessequal((float)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessequal((float)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessequal((float)0, (long double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessequal((double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessequal((double)0, (double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(islessequal(0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessequal((double)0, (long double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessequal((long double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessequal((long double)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessequal((long double)0, (long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(islessequal(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(islessequal(-1.0, 0.F) == true);
 }
 
 void test_islessgreater()
 {
+#ifdef islessgreater
+#error islessgreater defined
+#endif
     static_assert((std::is_same<decltype(islessgreater((float)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessgreater((float)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessgreater((float)0, (long double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessgreater((double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessgreater((double)0, (double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(islessgreater(0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessgreater((double)0, (long double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessgreater((long double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessgreater((long double)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(islessgreater((long double)0, (long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(islessgreater(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(islessgreater(-1.0, 0.F) == true);
 }
 
 void test_isunordered()
 {
+#ifdef isunordered
+#error isunordered defined
+#endif
     static_assert((std::is_same<decltype(isunordered((float)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isunordered((float)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isunordered((float)0, (long double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isunordered((double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isunordered((double)0, (double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isunordered(0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isunordered((double)0, (long double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isunordered((long double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isunordered((long double)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(isunordered((long double)0, (long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isunordered(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(isunordered(-1.0, 0.F) == false);
 }
 
 void test_acosh()
 {
+    static_assert((std::is_same<decltype(acosh((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(acosh((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acosh((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acosh((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acosh((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acosh((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acosh((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acosh((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acosh((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(acosh((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(acosh((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(acoshf(0)), float>::value), "");
     static_assert((std::is_same<decltype(acoshl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(acosh(Ambiguous())), Ambiguous>::value), "");
     assert(acosh(1) == 0);
 }
 
 void test_asinh()
 {
+    static_assert((std::is_same<decltype(asinh((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(asinh((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asinh((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asinh((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asinh((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asinh((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asinh((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asinh((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asinh((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(asinh((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(asinh((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(asinhf(0)), float>::value), "");
     static_assert((std::is_same<decltype(asinhl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(asinh(Ambiguous())), Ambiguous>::value), "");
     assert(asinh(0) == 0);
 }
 
 void test_atanh()
 {
+    static_assert((std::is_same<decltype(atanh((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(atanh((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atanh((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atanh((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atanh((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atanh((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atanh((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atanh((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atanh((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(atanh((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atanh((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(atanhf(0)), float>::value), "");
     static_assert((std::is_same<decltype(atanhl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(atanh(Ambiguous())), Ambiguous>::value), "");
     assert(atanh(0) == 0);
 }
 
 void test_cbrt()
 {
+    static_assert((std::is_same<decltype(cbrt((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(cbrt((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cbrt((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cbrt((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cbrt((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cbrt((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cbrt((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cbrt((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cbrt((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(cbrt((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(cbrt((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(cbrtf(0)), float>::value), "");
     static_assert((std::is_same<decltype(cbrtl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(cbrt(Ambiguous())), Ambiguous>::value), "");
     assert(cbrt(1) == 1);
 }
 
 void test_copysign()
 {
+    static_assert((std::is_same<decltype(copysign((float)0, (float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(copysign((bool)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(copysign((unsigned short)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(copysign((int)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(copysign((float)0, (unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(copysign((double)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(copysign((long double)0, (unsigned long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(copysign((int)0, (long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(copysign((int)0, (unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(copysign((double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(copysign((long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(copysign((float)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(copysign((float)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(copysign((double)0, (long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(copysignf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(copysignl(0,0)), long double>::value), "");
+    static_assert((std::is_same<decltype(copysign((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(copysign(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(copysign(1,1) == 1);
 }
 
 void test_erf()
 {
+    static_assert((std::is_same<decltype(erf((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(erf((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erf((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erf((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erf((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erf((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erf((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erf((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erf((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(erf((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erf((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(erff(0)), float>::value), "");
     static_assert((std::is_same<decltype(erfl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(erf(Ambiguous())), Ambiguous>::value), "");
     assert(erf(0) == 0);
 }
 
 void test_erfc()
 {
+    static_assert((std::is_same<decltype(erfc((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(erfc((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erfc((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erfc((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erfc((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erfc((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erfc((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erfc((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erfc((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(erfc((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(erfc((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(erfcf(0)), float>::value), "");
     static_assert((std::is_same<decltype(erfcl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(erfc(Ambiguous())), Ambiguous>::value), "");
     assert(erfc(0) == 1);
 }
 
 void test_exp2()
 {
+    static_assert((std::is_same<decltype(exp2((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(exp2((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp2((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp2((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp2((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp2((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp2((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp2((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp2((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(exp2((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(exp2((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(exp2f(0)), float>::value), "");
     static_assert((std::is_same<decltype(exp2l(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(exp2(Ambiguous())), Ambiguous>::value), "");
     assert(exp2(1) == 2);
 }
 
 void test_expm1()
 {
+    static_assert((std::is_same<decltype(expm1((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(expm1((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(expm1((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(expm1((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(expm1((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(expm1((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(expm1((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(expm1((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(expm1((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(expm1((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(expm1((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(expm1f(0)), float>::value), "");
     static_assert((std::is_same<decltype(expm1l(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(expm1(Ambiguous())), Ambiguous>::value), "");
     assert(expm1(0) == 0);
 }
 
 void test_fdim()
 {
+    static_assert((std::is_same<decltype(fdim((float)0, (float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(fdim((bool)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fdim((unsigned short)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fdim((int)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fdim((float)0, (unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fdim((double)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fdim((long double)0, (unsigned long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fdim((int)0, (long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fdim((int)0, (unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(fdim((double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fdim((long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fdim((float)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fdim((float)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fdim((double)0, (long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(fdimf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(fdiml(0,0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fdim((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fdim(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(fdim(1,0) == 1);
 }
 
 void test_fma()
 {
+    static_assert((std::is_same<decltype(fma((bool)0, (float)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((char)0, (float)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((unsigned)0, (float)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((float)0, (int)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((float)0, (long)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((float)0, (float)0, (unsigned long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((float)0, (float)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((float)0, (float)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fma((float)0, (float)0, (float)0)), float>::value), "");
+
+    static_assert((std::is_same<decltype(fma((bool)0, (double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((char)0, (double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((unsigned)0, (double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((double)0, (int)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((double)0, (long)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((double)0, (double)0, (unsigned long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((double)0, (double)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fma((double)0, (double)0, (long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(fma((double)0, (double)0,  (double)0)), double>::value), "");
+
+    static_assert((std::is_same<decltype(fma((bool)0, (long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fma((char)0, (long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fma((unsigned)0, (long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fma((long double)0, (int)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fma((long double)0, (long)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fma((long double)0, (long double)0, (unsigned long long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fma((long double)0, (long double)0, (float)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fma((double)0, (long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fma((long double)0, (long double)0, (long double)0)), long double>::value), "");
+
     static_assert((std::is_same<decltype(fmaf(0,0,0)), float>::value), "");
     static_assert((std::is_same<decltype(fmal(0,0,0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fma(Ambiguous(), Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(fma(1,1,1) == 2);
 }
 
 void test_fmax()
 {
+    static_assert((std::is_same<decltype(fmax((float)0, (float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(fmax((bool)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmax((unsigned short)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmax((int)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmax((float)0, (unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmax((double)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmax((long double)0, (unsigned long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmax((int)0, (long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmax((int)0, (unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(fmax((double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmax((long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmax((float)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmax((float)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmax((double)0, (long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(fmaxf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(fmaxl(0,0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmax((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmax(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(fmax(1,0) == 1);
 }
 
 void test_fmin()
 {
+    static_assert((std::is_same<decltype(fmin((float)0, (float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(fmin((bool)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmin((unsigned short)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmin((int)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmin((float)0, (unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmin((double)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmin((long double)0, (unsigned long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmin((int)0, (long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmin((int)0, (unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(fmin((double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmin((long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmin((float)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmin((float)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmin((double)0, (long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(fminf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(fminl(0,0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fmin((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmin(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(fmin(1,0) == 0);
 }
 
 void test_hypot()
 {
+    static_assert((std::is_same<decltype(hypot((float)0, (float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(hypot((bool)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(hypot((unsigned short)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(hypot((int)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(hypot((float)0, (unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(hypot((double)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(hypot((long double)0, (unsigned long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(hypot((int)0, (long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(hypot((int)0, (unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(hypot((double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(hypot((long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(hypot((float)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(hypot((float)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(hypot((double)0, (long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(hypotf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(hypotl(0,0)), long double>::value), "");
+    static_assert((std::is_same<decltype(hypot((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(hypot(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(hypot(3,4) == 5);
 }
 
 void test_ilogb()
 {
+    static_assert((std::is_same<decltype(ilogb((float)0)), int>::value), "");
+    static_assert((std::is_same<decltype(ilogb((bool)0)), int>::value), "");
+    static_assert((std::is_same<decltype(ilogb((unsigned short)0)), int>::value), "");
+    static_assert((std::is_same<decltype(ilogb((int)0)), int>::value), "");
+    static_assert((std::is_same<decltype(ilogb((unsigned int)0)), int>::value), "");
+    static_assert((std::is_same<decltype(ilogb((long)0)), int>::value), "");
+    static_assert((std::is_same<decltype(ilogb((unsigned long)0)), int>::value), "");
+    static_assert((std::is_same<decltype(ilogb((long long)0)), int>::value), "");
+    static_assert((std::is_same<decltype(ilogb((unsigned long long)0)), int>::value), "");
     static_assert((std::is_same<decltype(ilogb((double)0)), int>::value), "");
+    static_assert((std::is_same<decltype(ilogb((long double)0)), int>::value), "");
     static_assert((std::is_same<decltype(ilogbf(0)), int>::value), "");
     static_assert((std::is_same<decltype(ilogbl(0)), int>::value), "");
+    static_assert((std::is_same<decltype(ilogb(Ambiguous())), Ambiguous>::value), "");
     assert(ilogb(1) == 0);
 }
 
 void test_lgamma()
 {
+    static_assert((std::is_same<decltype(lgamma((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(lgamma((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(lgamma((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(lgamma((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(lgamma((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(lgamma((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(lgamma((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(lgamma((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(lgamma((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(lgamma((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(lgamma((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(lgammaf(0)), float>::value), "");
     static_assert((std::is_same<decltype(lgammal(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(lgamma(Ambiguous())), Ambiguous>::value), "");
     assert(lgamma(1) == 0);
 }
 
 void test_llrint()
 {
+    static_assert((std::is_same<decltype(llrint((float)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llrint((bool)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llrint((unsigned short)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llrint((int)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llrint((unsigned int)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llrint((long)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llrint((unsigned long)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llrint((long long)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llrint((unsigned long long)0)), long long>::value), "");
     static_assert((std::is_same<decltype(llrint((double)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llrint((long double)0)), long long>::value), "");
     static_assert((std::is_same<decltype(llrintf(0)), long long>::value), "");
     static_assert((std::is_same<decltype(llrintl(0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llrint(Ambiguous())), Ambiguous>::value), "");
     assert(llrint(1) == 1LL);
 }
 
 void test_llround()
 {
+    static_assert((std::is_same<decltype(llround((float)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llround((bool)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llround((unsigned short)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llround((int)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llround((unsigned int)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llround((long)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llround((unsigned long)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llround((long long)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llround((unsigned long long)0)), long long>::value), "");
     static_assert((std::is_same<decltype(llround((double)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llround((long double)0)), long long>::value), "");
     static_assert((std::is_same<decltype(llroundf(0)), long long>::value), "");
     static_assert((std::is_same<decltype(llroundl(0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llround(Ambiguous())), Ambiguous>::value), "");
     assert(llround(1) == 1LL);
 }
 
 void test_log1p()
 {
+    static_assert((std::is_same<decltype(log1p((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(log1p((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log1p((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log1p((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log1p((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log1p((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log1p((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log1p((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log1p((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(log1p((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log1p((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(log1pf(0)), float>::value), "");
     static_assert((std::is_same<decltype(log1pl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(log1p(Ambiguous())), Ambiguous>::value), "");
     assert(log1p(0) == 0);
 }
 
 void test_log2()
 {
+    static_assert((std::is_same<decltype(log2((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(log2((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log2((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log2((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log2((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log2((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log2((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log2((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log2((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(log2((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(log2((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(log2f(0)), float>::value), "");
     static_assert((std::is_same<decltype(log2l(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(log2(Ambiguous())), Ambiguous>::value), "");
     assert(log2(1) == 0);
 }
 
 void test_logb()
 {
+    static_assert((std::is_same<decltype(logb((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(logb((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(logb((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(logb((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(logb((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(logb((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(logb((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(logb((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(logb((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(logb((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(logb((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(logbf(0)), float>::value), "");
     static_assert((std::is_same<decltype(logbl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(logb(Ambiguous())), Ambiguous>::value), "");
     assert(logb(1) == 0);
 }
 
 void test_lrint()
 {
+    static_assert((std::is_same<decltype(lrint((float)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lrint((bool)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lrint((unsigned short)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lrint((int)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lrint((unsigned int)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lrint((long)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lrint((unsigned long)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lrint((long long)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lrint((unsigned long long)0)), long>::value), "");
     static_assert((std::is_same<decltype(lrint((double)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lrint((long double)0)), long>::value), "");
     static_assert((std::is_same<decltype(lrintf(0)), long>::value), "");
     static_assert((std::is_same<decltype(lrintl(0)), long>::value), "");
+    static_assert((std::is_same<decltype(lrint(Ambiguous())), Ambiguous>::value), "");
     assert(lrint(1) == 1L);
 }
 
 void test_lround()
 {
+    static_assert((std::is_same<decltype(lround((float)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lround((bool)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lround((unsigned short)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lround((int)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lround((unsigned int)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lround((long)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lround((unsigned long)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lround((long long)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lround((unsigned long long)0)), long>::value), "");
     static_assert((std::is_same<decltype(lround((double)0)), long>::value), "");
+    static_assert((std::is_same<decltype(lround((long double)0)), long>::value), "");
     static_assert((std::is_same<decltype(lroundf(0)), long>::value), "");
     static_assert((std::is_same<decltype(lroundl(0)), long>::value), "");
+    static_assert((std::is_same<decltype(lround(Ambiguous())), Ambiguous>::value), "");
     assert(lround(1) == 1L);
 }
 
@@ -521,96 +1192,229 @@
 
 void test_nearbyint()
 {
+    static_assert((std::is_same<decltype(nearbyint((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(nearbyint((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nearbyint((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nearbyint((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nearbyint((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nearbyint((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nearbyint((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nearbyint((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nearbyint((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(nearbyint((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nearbyint((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(nearbyintf(0)), float>::value), "");
     static_assert((std::is_same<decltype(nearbyintl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(nearbyint(Ambiguous())), Ambiguous>::value), "");
     assert(nearbyint(1) == 1);
 }
 
 void test_nextafter()
 {
+    static_assert((std::is_same<decltype(nextafter((float)0, (float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(nextafter((bool)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nextafter((unsigned short)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nextafter((int)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(nextafter((float)0, (unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nextafter((double)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nextafter((long double)0, (unsigned long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(nextafter((int)0, (long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nextafter((int)0, (unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(nextafter((double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nextafter((long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(nextafter((float)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nextafter((float)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(nextafter((double)0, (long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(nextafterf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(nextafterl(0,0)), long double>::value), "");
+    static_assert((std::is_same<decltype(nextafter((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nextafter(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(nextafter(0,1) == hexfloat<double>(0x1, 0, -1074));
 }
 
 void test_nexttoward()
 {
+    static_assert((std::is_same<decltype(nexttoward((float)0, (long double)0)), float>::value), "");
+    static_assert((std::is_same<decltype(nexttoward((bool)0, (long double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nexttoward((unsigned short)0, (long double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nexttoward((int)0, (long double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nexttoward((unsigned int)0, (long double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nexttoward((long)0, (long double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nexttoward((unsigned long)0, (long double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nexttoward((long long)0, (long double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nexttoward((unsigned long long)0, (long double)0)), double>::value), "");
     static_assert((std::is_same<decltype(nexttoward((double)0, (long double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nexttoward((long double)0, (long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(nexttowardf(0, (long double)0)), float>::value), "");
     static_assert((std::is_same<decltype(nexttowardl(0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(nexttoward(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(nexttoward(0, 1) == hexfloat<double>(0x1, 0, -1074));
 }
 
 void test_remainder()
 {
+    static_assert((std::is_same<decltype(remainder((float)0, (float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(remainder((bool)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(remainder((unsigned short)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(remainder((int)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(remainder((float)0, (unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(remainder((double)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(remainder((long double)0, (unsigned long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(remainder((int)0, (long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(remainder((int)0, (unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(remainder((double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(remainder((long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(remainder((float)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(remainder((float)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(remainder((double)0, (long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(remainderf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(remainderl(0,0)), long double>::value), "");
     static_assert((std::is_same<decltype(remainder((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(remainder(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(remainder(0.5,1) == 0.5);
 }
 
 void test_remquo()
 {
     int ip;
+    static_assert((std::is_same<decltype(remquo((float)0, (float)0, &ip)), float>::value), "");
+    static_assert((std::is_same<decltype(remquo((bool)0, (float)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(remquo((unsigned short)0, (double)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(remquo((int)0, (long double)0, &ip)), long double>::value), "");
+    static_assert((std::is_same<decltype(remquo((float)0, (unsigned int)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(remquo((double)0, (long)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(remquo((long double)0, (unsigned long)0, &ip)), long double>::value), "");
+    static_assert((std::is_same<decltype(remquo((int)0, (long long)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(remquo((int)0, (unsigned long long)0, &ip)), double>::value), "");
     static_assert((std::is_same<decltype(remquo((double)0, (double)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(remquo((long double)0, (long double)0, &ip)), long double>::value), "");
+    static_assert((std::is_same<decltype(remquo((float)0, (double)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(remquo((float)0, (long double)0, &ip)), long double>::value), "");
+    static_assert((std::is_same<decltype(remquo((double)0, (long double)0, &ip)), long double>::value), "");
     static_assert((std::is_same<decltype(remquof(0,0, &ip)), float>::value), "");
     static_assert((std::is_same<decltype(remquol(0,0, &ip)), long double>::value), "");
+    static_assert((std::is_same<decltype(remquo((int)0, (int)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(remquo(Ambiguous(), Ambiguous(), &ip)), Ambiguous>::value), "");
     assert(remquo(0.5,1, &ip) == 0.5);
 }
 
 void test_rint()
 {
+    static_assert((std::is_same<decltype(rint((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(rint((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(rint((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(rint((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(rint((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(rint((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(rint((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(rint((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(rint((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(rint((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(rint((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(rintf(0)), float>::value), "");
     static_assert((std::is_same<decltype(rintl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(rint(Ambiguous())), Ambiguous>::value), "");
     assert(rint(1) == 1);
 }
 
 void test_round()
 {
+    static_assert((std::is_same<decltype(round((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(round((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(round((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(round((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(round((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(round((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(round((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(round((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(round((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(round((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(round((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(roundf(0)), float>::value), "");
     static_assert((std::is_same<decltype(roundl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(round(Ambiguous())), Ambiguous>::value), "");
     assert(round(1) == 1);
 }
 
 void test_scalbln()
 {
+    static_assert((std::is_same<decltype(scalbln((float)0, (long)0)), float>::value), "");
+    static_assert((std::is_same<decltype(scalbln((bool)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbln((unsigned short)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbln((int)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbln((unsigned int)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbln((long)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbln((unsigned long)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbln((long long)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbln((unsigned long long)0, (long)0)), double>::value), "");
     static_assert((std::is_same<decltype(scalbln((double)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbln((long double)0, (long)0)), long double>::value), "");
     static_assert((std::is_same<decltype(scalblnf(0, (long)0)), float>::value), "");
     static_assert((std::is_same<decltype(scalblnl(0, (long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(scalbln(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(scalbln(1, 1) == 2);
 }
 
 void test_scalbn()
 {
+    static_assert((std::is_same<decltype(scalbn((float)0, (int)0)), float>::value), "");
+    static_assert((std::is_same<decltype(scalbn((bool)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbn((unsigned short)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbn((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbn((unsigned int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbn((long)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbn((unsigned long)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbn((long long)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbn((unsigned long long)0, (int)0)), double>::value), "");
     static_assert((std::is_same<decltype(scalbn((double)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(scalbn((long double)0, (int)0)), long double>::value), "");
     static_assert((std::is_same<decltype(scalbnf(0, (int)0)), float>::value), "");
     static_assert((std::is_same<decltype(scalbnl(0, (int)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(scalbn(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(scalbn(1, 1) == 2);
 }
 
 void test_tgamma()
 {
+    static_assert((std::is_same<decltype(tgamma((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(tgamma((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tgamma((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tgamma((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tgamma((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tgamma((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tgamma((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tgamma((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tgamma((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(tgamma((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(tgamma((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(tgammaf(0)), float>::value), "");
     static_assert((std::is_same<decltype(tgammal(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(tgamma(Ambiguous())), Ambiguous>::value), "");
     assert(tgamma(1) == 1);
 }
 
 void test_trunc()
 {
+    static_assert((std::is_same<decltype(trunc((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(trunc((bool)0)), double>::value), "");
+    static_assert((std::is_same<decltype(trunc((unsigned short)0)), double>::value), "");
+    static_assert((std::is_same<decltype(trunc((int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(trunc((unsigned int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(trunc((long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(trunc((unsigned long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(trunc((long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(trunc((unsigned long long)0)), double>::value), "");
     static_assert((std::is_same<decltype(trunc((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(trunc((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(truncf(0)), float>::value), "");
     static_assert((std::is_same<decltype(truncl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(trunc(Ambiguous())), Ambiguous>::value), "");
     assert(trunc(1) == 1);
 }
 
 int main()
 {
+    test_abs();
     test_acos();
     test_asin();
     test_atan();
@@ -636,8 +1440,6 @@
     test_signbit();
     test_fpclassify();
     test_isfinite();
-    test_isinf();
-    test_isnan();
     test_isnormal();
     test_isgreater();
     test_isgreaterequal();
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
new file mode 100644
index 0000000..cc7eaac
--- /dev/null
+++ b/test/std/depr/depr.c.headers/math_h_isinf.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <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
new file mode 100644
index 0000000..118f96b
--- /dev/null
+++ b/test/std/depr/depr.c.headers/math_h_isnan.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <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 36f4253..9663d88 100644
--- a/test/std/depr/depr.c.headers/setjmp_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/setjmp_h.pass.cpp
@@ -12,9 +12,14 @@
 #include <setjmp.h>
 #include <type_traits>
 
+#ifndef setjmp
+#error setjmp not defined
+#endif
+
 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/stddef_h.pass.cpp b/test/std/depr/depr.c.headers/stddef_h.pass.cpp
index 140c91b..0c08c78 100644
--- a/test/std/depr/depr.c.headers/stddef_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/stddef_h.pass.cpp
@@ -10,6 +10,7 @@
 // <stddef.h>
 
 #include <stddef.h>
+#include <cassert>
 #include <type_traits>
 
 #ifndef NULL
@@ -22,6 +23,9 @@
 
 int main()
 {
+    void *p = NULL;
+    assert(!p);
+
     static_assert(sizeof(size_t) == sizeof(void*),
                   "sizeof(size_t) == sizeof(void*)");
     static_assert(std::is_unsigned<size_t>::value,
@@ -34,4 +38,22 @@
                   "std::is_signed<ptrdiff_t>::value");
     static_assert(std::is_integral<ptrdiff_t>::value,
                   "std::is_integral<ptrdiff_t>::value");
+    static_assert((std::is_same<decltype(nullptr), nullptr_t>::value),
+                  "decltype(nullptr) == nullptr_t");
+    static_assert(sizeof(nullptr_t) == sizeof(void*),
+                  "sizeof(nullptr_t) == sizeof(void*)");
+    static_assert(std::is_pod<max_align_t>::value,
+                  "std::is_pod<max_align_t>::value");
+    static_assert((std::alignment_of<max_align_t>::value >=
+                  std::alignment_of<long long>::value),
+                  "std::alignment_of<max_align_t>::value >= "
+                  "std::alignment_of<long long>::value");
+    static_assert(std::alignment_of<max_align_t>::value >=
+                  std::alignment_of<long double>::value,
+                  "std::alignment_of<max_align_t>::value >= "
+                  "std::alignment_of<long double>::value");
+    static_assert(std::alignment_of<max_align_t>::value >=
+                  std::alignment_of<void*>::value,
+                  "std::alignment_of<max_align_t>::value >= "
+                  "std::alignment_of<void*>::value");
 }
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 3861ee5..92bb04e 100644
--- a/test/std/depr/depr.c.headers/stdint_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/stdint_h.pass.cpp
@@ -223,10 +223,10 @@
     assert(UINTMAX_MAX == std::numeric_limits<uintmax_t>::max());
 
     // PTRDIFF_MIN
-    assert(PTRDIFF_MIN == std::numeric_limits<ptrdiff_t>::min());
+    assert(PTRDIFF_MIN == std::numeric_limits<std::ptrdiff_t>::min());
 
     // PTRDIFF_MAX
-    assert(PTRDIFF_MAX == std::numeric_limits<ptrdiff_t>::max());
+    assert(PTRDIFF_MAX == std::numeric_limits<std::ptrdiff_t>::max());
 
     // SIG_ATOMIC_MIN
     assert(SIG_ATOMIC_MIN == std::numeric_limits<sig_atomic_t>::min());
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 ba6714d..85f9d29 100644
--- a/test/std/depr/depr.c.headers/stdio_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/stdio_h.pass.cpp
@@ -13,6 +13,26 @@
 #include <type_traits>
 #include "test_macros.h"
 
+#ifdef getc
+#error getc is defined
+#endif
+
+#ifdef putc
+#error putc is defined
+#endif
+
+#ifdef clearerr
+#error clearerr is defined
+#endif
+
+#ifdef feof
+#error feof is defined
+#endif
+
+#ifdef ferror
+#error ferror is defined
+#endif
+
 #ifndef BUFSIZ
 #error BUFSIZ not defined
 #endif
@@ -79,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/stdlib_h.pass.cpp b/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
index d1cc443..96d1143 100644
--- a/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
@@ -12,6 +12,36 @@
 #include <stdlib.h>
 #include <type_traits>
 
+// As of 1/10/2015 clang emits a -Wnonnull warnings even if the warning occurs
+// in an unevaluated context. For this reason we manually suppress the warning.
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wnonnull"
+#endif
+
+#ifdef abs
+#error abs is defined
+#endif
+
+#ifdef labs
+#error labs is defined
+#endif
+
+#ifdef llabs
+#error llabs is defined
+#endif
+
+#ifdef div
+#error div is defined
+#endif
+
+#ifdef ldiv
+#error ldiv is defined
+#endif
+
+#ifdef lldiv
+#error lldiv is defined
+#endif
+
 #ifndef EXIT_FAILURE
 #error EXIT_FAILURE not defined
 #endif
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 afc784f..db0308b 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 @@
     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 0d229af..a263938 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 @@
     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 8d1c3b7..d7d9bfc 100644
--- a/test/std/depr/depr.c.headers/wchar_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/wchar_h.pass.cpp
@@ -10,6 +10,7 @@
 // <wchar.h>
 
 #include <wchar.h>
+#include <stdarg.h>
 #include <type_traits>
 
 #ifndef NULL
@@ -28,22 +29,18 @@
 #error WEOF not defined
 #endif
 
-#if defined(__clang__)
-#pragma clang diagnostic ignored "-Wmissing-braces"
-#endif
-
 int main()
 {
-    mbstate_t mb = {0};
+// 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
+//    characters and wide characters
+    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;
     static_assert((std::is_same<decltype(fwprintf(fp, L"")), int>::value), "");
@@ -54,19 +51,13 @@
     static_assert((std::is_same<decltype(vfwscanf(fp, L"", va)), int>::value), "");
     static_assert((std::is_same<decltype(vswprintf(ws, s, L"", va)), int>::value), "");
     static_assert((std::is_same<decltype(vswscanf(L"", L"", va)), int>::value), "");
-    static_assert((std::is_same<decltype(vwprintf(L"", va)), int>::value), "");
-    static_assert((std::is_same<decltype(vwscanf(L"", va)), int>::value), "");
-    static_assert((std::is_same<decltype(wprintf(L"")), int>::value), "");
-    static_assert((std::is_same<decltype(wscanf(L"")), int>::value), "");
     static_assert((std::is_same<decltype(fgetwc(fp)), wint_t>::value), "");
     static_assert((std::is_same<decltype(fgetws(ws, 0, fp)), wchar_t*>::value), "");
     static_assert((std::is_same<decltype(fputwc(L' ', fp)), wint_t>::value), "");
     static_assert((std::is_same<decltype(fputws(L"", fp)), int>::value), "");
     static_assert((std::is_same<decltype(fwide(fp, 0)), int>::value), "");
     static_assert((std::is_same<decltype(getwc(fp)), wint_t>::value), "");
-    static_assert((std::is_same<decltype(getwchar()), wint_t>::value), "");
     static_assert((std::is_same<decltype(putwc(L' ', fp)), wint_t>::value), "");
-    static_assert((std::is_same<decltype(putwchar(L' ')), wint_t>::value), "");
     static_assert((std::is_same<decltype(ungetwc(L' ', fp)), wint_t>::value), "");
     static_assert((std::is_same<decltype(wcstod(L"", (wchar_t**)0)), double>::value), "");
     static_assert((std::is_same<decltype(wcstof(L"", (wchar_t**)0)), float>::value), "");
@@ -105,4 +96,27 @@
     static_assert((std::is_same<decltype(wcrtomb(ns, L' ', &mb)), size_t>::value), "");
     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), "");
+
+    // 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), "");
+    static_assert((std::is_same<decltype(wcsstr((const wchar_t*)0, L"")), const wchar_t*>::value), "");
+    static_assert((std::is_same<decltype(wmemchr((const wchar_t*)0, L' ', s)), const wchar_t*>::value), "");
+#endif
+
+#ifndef _LIBCPP_HAS_NO_STDIN
+    static_assert((std::is_same<decltype(getwchar()), wint_t>::value), "");
+    static_assert((std::is_same<decltype(vwscanf(L"", va)), int>::value), "");
+    static_assert((std::is_same<decltype(wscanf(L"")), int>::value), "");
+#endif
+
+#ifndef _LIBCPP_HAS_NO_STDOUT
+    static_assert((std::is_same<decltype(putwchar(L' ')), wint_t>::value), "");
+    static_assert((std::is_same<decltype(vwprintf(L"", va)), int>::value), "");
+    static_assert((std::is_same<decltype(wprintf(L"")), int>::value), "");
+#endif
 }
diff --git a/test/std/depr/depr.ios.members/io_state.pass.cpp b/test/std/depr/depr.ios.members/io_state.pass.cpp
index 15bfbf1..6b362d0 100644
--- a/test/std/depr/depr.ios.members/io_state.pass.cpp
+++ b/test/std/depr/depr.ios.members/io_state.pass.cpp
@@ -15,11 +15,16 @@
 //     typedef T1 io_state;
 // };
 
+//  These members were removed for C++17
+
+#include "test_macros.h"
 #include <strstream>
 #include <cassert>
 
 int main()
 {
+#if TEST_STD_VER <= 14
     std::strstream::io_state b = std::strstream::eofbit;
     assert(b == std::ios::eofbit);
+#endif
 }
diff --git a/test/std/depr/depr.ios.members/open_mode.pass.cpp b/test/std/depr/depr.ios.members/open_mode.pass.cpp
index 12a8e94..cf91e7c 100644
--- a/test/std/depr/depr.ios.members/open_mode.pass.cpp
+++ b/test/std/depr/depr.ios.members/open_mode.pass.cpp
@@ -15,11 +15,16 @@
 //     typedef T2 open_mode;
 // };
 
+//  These members were removed for C++17
+
+#include "test_macros.h"
 #include <strstream>
 #include <cassert>
 
 int main()
 {
+#if TEST_STD_VER <= 14
     std::strstream::open_mode b = std::strstream::app;
     assert(b == std::ios::app);
+#endif
 }
diff --git a/test/std/depr/depr.ios.members/seek_dir.pass.cpp b/test/std/depr/depr.ios.members/seek_dir.pass.cpp
index 891a7a3..0dd70c1 100644
--- a/test/std/depr/depr.ios.members/seek_dir.pass.cpp
+++ b/test/std/depr/depr.ios.members/seek_dir.pass.cpp
@@ -15,11 +15,16 @@
 //     typedef T3 seek_dir;
 // };
 
+//  These members were removed for C++17
+
+#include "test_macros.h"
 #include <strstream>
 #include <cassert>
 
 int main()
 {
+#if TEST_STD_VER <= 14
     std::strstream::seek_dir b = std::strstream::cur;
     assert(b == std::ios::cur);
+#endif
 }
diff --git a/test/std/depr/depr.ios.members/streamoff.pass.cpp b/test/std/depr/depr.ios.members/streamoff.pass.cpp
index 4ccfd1f..0c237b3 100644
--- a/test/std/depr/depr.ios.members/streamoff.pass.cpp
+++ b/test/std/depr/depr.ios.members/streamoff.pass.cpp
@@ -15,11 +15,16 @@
 //     typedef OFF_T streamoff;
 // };
 
+//  These members were removed for C++17
+
+#include "test_macros.h"
 #include <ios>
 #include <type_traits>
 
 int main()
 {
+#if TEST_STD_VER <= 14
     static_assert((std::is_integral<std::ios_base::streamoff>::value), "");
     static_assert((std::is_signed<std::ios_base::streamoff>::value), "");
+#endif
 }
diff --git a/test/std/depr/depr.ios.members/streampos.pass.cpp b/test/std/depr/depr.ios.members/streampos.pass.cpp
index 315118c..863905f 100644
--- a/test/std/depr/depr.ios.members/streampos.pass.cpp
+++ b/test/std/depr/depr.ios.members/streampos.pass.cpp
@@ -15,10 +15,15 @@
 //     typedef POS_T streampos;
 // };
 
+//  These members were removed for C++17
+
+#include "test_macros.h"
 #include <ios>
 #include <type_traits>
 
 int main()
 {
+#if TEST_STD_VER <= 14
     static_assert((std::is_same<std::ios_base::streampos, std::streampos>::value), "");
+#endif
 }
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 9911df7..078d891 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 a800950..8b4ae72 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 edd6c1f..23068f5 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 5d01715..ff797e0 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 1ad0bfa..b6519de 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 5ea4988..29debf1 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 2a4c0ec..1dc03b8 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 2ec5e7f..6298fca 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 12a1fb8..e466d50 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/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 0573ef8..6e19d54 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
@@ -26,7 +26,7 @@
 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
diff --git a/test/std/experimental/algorithms/alg.search/search.pass.cpp b/test/std/experimental/algorithms/alg.search/search.pass.cpp
index e27f0e4..579c13d 100644
--- a/test/std/experimental/algorithms/alg.search/search.pass.cpp
+++ b/test/std/experimental/algorithms/alg.search/search.pass.cpp
@@ -7,13 +7,15 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: c++98, c++03, c++11
+
 // <algorithm>
 
 //   template<class ForwardIterator, class Searcher>
 //   ForwardIterator search(ForwardIterator first, ForwardIterator last,
 //                          const Searcher& searcher);
 //
-//		returns searcher.operator(first, last)
+//		returns searcher.operator(first, last).first
 //
 
 #include <experimental/algorithm>
@@ -25,19 +27,20 @@
 
 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);
     }
 };
 
 
 int main() {
     typedef int * RI;
-    static_assert(std::is_same<RI, decltype(std::experimental::search(RI(), RI(), MySearcher()))>::value, "" );
+    static_assert((std::is_same<RI, decltype(std::experimental::search(RI(), RI(), MySearcher()))>::value), "" );
 
-    RI it{nullptr};
+    RI it(nullptr);
     assert(it == std::experimental::search(it, it, MySearcher()));
     assert(searcher_called == 1);
 }
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
new file mode 100644
index 0000000..4ef70c7
--- /dev/null
+++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/default.pass.cpp
@@ -0,0 +1,128 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <functional>
+
+// boyer_moore searcher
+// template<class RandomAccessIterator1,
+//          class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,
+//          class BinaryPredicate = equal_to<>>
+// class boyer_moore_searcher {
+// public:
+//   boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last,
+//                        Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
+// 
+//   template<class RandomAccessIterator2>
+//   pair<RandomAccessIterator2, RandomAccessIterator2>
+//   operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
+// 
+// private:
+//   RandomAccessIterator1 pat_first_; // exposition only
+//   RandomAccessIterator1 pat_last_;  // exposition only
+//   Hash                  hash_;      // exposition only
+//   BinaryPredicate       pred_;      // exposition only
+// };
+
+
+#include <experimental/algorithm>
+#include <experimental/functional>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <typename Iter1, typename Iter2>
+void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result) {
+    std::experimental::boyer_moore_searcher<Iter2> s{b2, e2};
+    assert(result == std::experimental::search(b1, e1, s));
+}
+
+template <class Iter1, class Iter2>
+void
+test()
+{
+    int ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2));
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1));
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1));
+    int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    int ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1));
+    int id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1));
+    int ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4));
+    int ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8));
+    int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    int ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3));
+    int ij[] = {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
+    const unsigned sj = sizeof(ij)/sizeof(ij[0]);
+    int ik[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
+    const unsigned sk = sizeof(ik)/sizeof(ik[0]);
+    do_search(Iter1(ij), Iter1(ij+sj), Iter2(ik), Iter2(ik+sk), Iter1(ij+6));
+}
+
+template <class Iter1, class Iter2>
+void
+test2()
+{
+    char ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2));
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1));
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1));
+    char ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    char ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1));
+    char id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1));
+    char ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4));
+    char ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8));
+    char ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    char ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3));
+    char ij[] = {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
+    const unsigned sj = sizeof(ij)/sizeof(ij[0]);
+    char ik[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
+    const unsigned sk = sizeof(ik)/sizeof(ik[0]);
+    do_search(Iter1(ij), Iter1(ij+sj), Iter2(ik), Iter2(ik+sk), Iter1(ij+6));
+}
+
+int main() {
+    test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
+    test2<random_access_iterator<const char*>, random_access_iterator<const char*> >();
+}
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
new file mode 100644
index 0000000..1162ef6
--- /dev/null
+++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pass.cpp
@@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <functional>
+
+// boyer_moore searcher
+// template<class RandomAccessIterator1,
+//          class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,
+//          class BinaryPredicate = equal_to<>>
+// class boyer_moore_searcher {
+// public:
+//   boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last,
+//                        Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
+// 
+//   template<class RandomAccessIterator2>
+//   pair<RandomAccessIterator2, RandomAccessIterator2>
+//   operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
+// 
+// private:
+//   RandomAccessIterator1 pat_first_; // exposition only
+//   RandomAccessIterator1 pat_last_;  // exposition only
+//   Hash                  hash_;      // exposition only
+//   BinaryPredicate       pred_;      // exposition only
+// };
+
+
+#include <experimental/algorithm>
+#include <experimental/functional>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <typename T> struct MyHash {
+	size_t operator () (T t) const { return static_cast<size_t>(t); }
+};
+
+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, 
+                 MyHash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>>
+          s{b2, e2};
+    assert(result == std::experimental::search(b1, e1, s));
+}
+
+template <class Iter1, class Iter2>
+void
+test()
+{
+    int ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia),      sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia),      sa*sa);
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1),    sa);
+    int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    int ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+    int id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+    int ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+    int ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+    int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    int ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3),  sh*3);
+}
+
+template <class Iter1, class Iter2>
+void
+test2()
+{
+    char ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia),      sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia),      sa*sa);
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1),    sa);
+    char ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    char ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+    char id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+    char ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+    char ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+    char ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    char ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3),  sh*3);
+}
+
+int main() {
+    test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
+    test2<random_access_iterator<const char*>, random_access_iterator<const char*> >();
+}
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
new file mode 100644
index 0000000..629a038
--- /dev/null
+++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/hash.pred.pass.cpp
@@ -0,0 +1,135 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <functional>
+
+// boyer_moore searcher
+// template<class RandomAccessIterator1,
+//          class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,
+//          class BinaryPredicate = equal_to<>>
+// class boyer_moore_searcher {
+// public:
+//   boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last,
+//                        Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
+// 
+//   template<class RandomAccessIterator2>
+//   pair<RandomAccessIterator2, RandomAccessIterator2>
+//   operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
+// 
+// private:
+//   RandomAccessIterator1 pat_first_; // exposition only
+//   RandomAccessIterator1 pat_last_;  // exposition only
+//   Hash                  hash_;      // exposition only
+//   BinaryPredicate       pred_;      // exposition only
+// };
+
+
+#include <experimental/algorithm>
+#include <experimental/functional>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <typename T> struct MyHash {
+	size_t operator () (T t) const { return static_cast<size_t>(t); }
+};
+
+struct count_equal
+{
+    static unsigned count;
+    template <class T>
+    bool operator()(const T& x, const T& y) const
+        {++count; return x == y;}
+};
+
+unsigned count_equal::count = 0;
+
+template <typename Iter1, typename Iter2>
+void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) {
+    std::experimental::boyer_moore_searcher<Iter2, 
+                 MyHash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>,
+                 count_equal>
+          s{b2, e2};
+    assert(result == std::experimental::search(b1, e1, s));
+}
+
+template <class Iter1, class Iter2>
+void
+test()
+{
+    int ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia),      sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia),      sa*sa);
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1),    sa);
+    int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    int ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+    int id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+    int ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+    int ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+    int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    int ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3),  sh*3);
+}
+
+template <class Iter1, class Iter2>
+void
+test2()
+{
+    char ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia),      sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia),      sa*sa);
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1),    sa);
+    char ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    char ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+    char id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+    char ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+    char ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+    char ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    char ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3),  sh*3);
+}
+
+int main() {
+    test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
+    test2<random_access_iterator<const char*>, random_access_iterator<const char*> >();
+}
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
new file mode 100644
index 0000000..9d29cb6
--- /dev/null
+++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore/pred.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, c++11
+
+// <functional>
+
+// boyer_moore searcher
+// template<class RandomAccessIterator1,
+//          class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,
+//          class BinaryPredicate = equal_to<>>
+// class boyer_moore_searcher {
+// public:
+//   boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last,
+//                        Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
+// 
+//   template<class RandomAccessIterator2>
+//   pair<RandomAccessIterator2, RandomAccessIterator2>
+//   operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
+// 
+// private:
+//   RandomAccessIterator1 pat_first_; // exposition only
+//   RandomAccessIterator1 pat_last_;  // exposition only
+//   Hash                  hash_;      // exposition only
+//   BinaryPredicate       pred_;      // exposition only
+// };
+
+
+#include <experimental/algorithm>
+#include <experimental/functional>
+#include <cassert>
+
+#include "test_iterators.h"
+
+struct count_equal
+{
+    static unsigned count;
+    template <class T>
+    bool operator()(const T& x, const T& y) const
+        {++count; return x == y;}
+};
+
+unsigned count_equal::count = 0;
+
+template <typename Iter1, typename Iter2>
+void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) {
+    std::experimental::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));
+//    assert(count_equal::count <= max_count);
+}
+
+template <class Iter1, class Iter2>
+void
+test()
+{
+    int ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia),      sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia),      sa*sa);
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1),    sa);
+    int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    int ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+    int id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+    int ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+    int ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+    int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    int ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3),  sh*3);
+}
+
+template <class Iter1, class Iter2>
+void
+test2()
+{
+    char ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia),      sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia),      sa*sa);
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1),    sa);
+    char ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    char ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+    char id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+    char ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+    char ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+    char ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    char ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3),  sh*3);
+}
+
+int main() {
+    test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
+    test2<random_access_iterator<const char*>, random_access_iterator<const char*> >();
+}
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
new file mode 100644
index 0000000..e4d1883
--- /dev/null
+++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/default.pass.cpp
@@ -0,0 +1,128 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <functional>
+
+// boyer_moore_horspool searcher
+// template<class RandomAccessIterator1,
+//          class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,
+//          class BinaryPredicate = equal_to<>>
+// class boyer_moore_horspool_searcher {
+// public:
+//   boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last,
+//                                 Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
+// 
+//   template<class RandomAccessIterator2>
+//   pair<RandomAccessIterator2, RandomAccessIterator2>
+//   operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
+// 
+// private:
+//   RandomAccessIterator1 pat_first_; // exposition only
+//   RandomAccessIterator1 pat_last_;  // exposition only
+//   Hash                  hash_;      // exposition only
+//   BinaryPredicate       pred_;      // exposition only
+// };
+
+
+#include <experimental/algorithm>
+#include <experimental/functional>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <typename Iter1, typename Iter2>
+void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result) {
+    std::experimental::boyer_moore_horspool_searcher<Iter2> s{b2, e2};
+    assert(result == std::experimental::search(b1, e1, s));
+}
+
+template <class Iter1, class Iter2>
+void
+test()
+{
+    int ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2));
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1));
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1));
+    int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    int ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1));
+    int id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1));
+    int ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4));
+    int ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8));
+    int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    int ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3));
+    int ij[] = {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
+    const unsigned sj = sizeof(ij)/sizeof(ij[0]);
+    int ik[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
+    const unsigned sk = sizeof(ik)/sizeof(ik[0]);
+    do_search(Iter1(ij), Iter1(ij+sj), Iter2(ik), Iter2(ik+sk), Iter1(ij+6));
+}
+
+template <class Iter1, class Iter2>
+void
+test2()
+{
+    char ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2));
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3));
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia));
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1));
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1));
+    char ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    char ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1));
+    char id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1));
+    char ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4));
+    char ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8));
+    char ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    char ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3));
+    char ij[] = {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
+    const unsigned sj = sizeof(ij)/sizeof(ij[0]);
+    char ik[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
+    const unsigned sk = sizeof(ik)/sizeof(ik[0]);
+    do_search(Iter1(ij), Iter1(ij+sj), Iter2(ik), Iter2(ik+sk), Iter1(ij+6));
+}
+
+int main() {
+    test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
+    test2<random_access_iterator<const char*>, random_access_iterator<const char*> >();
+}
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
new file mode 100644
index 0000000..be116ec
--- /dev/null
+++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pass.cpp
@@ -0,0 +1,123 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <functional>
+
+// boyer_moore_horspool searcher
+// template<class RandomAccessIterator1,
+//          class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,
+//          class BinaryPredicate = equal_to<>>
+// class boyer_moore_horspool_searcher {
+// public:
+//   boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last,
+//                                 Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
+// 
+//   template<class RandomAccessIterator2>
+//   pair<RandomAccessIterator2, RandomAccessIterator2>
+//   operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
+// 
+// private:
+//   RandomAccessIterator1 pat_first_; // exposition only
+//   RandomAccessIterator1 pat_last_;  // exposition only
+//   Hash                  hash_;      // exposition only
+//   BinaryPredicate       pred_;      // exposition only
+// };
+
+#include <experimental/algorithm>
+#include <experimental/functional>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <typename T> struct MyHash {
+	size_t operator () (T t) const { return static_cast<size_t>(t); }
+};
+
+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, 
+                 MyHash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>>
+          s{b2, e2};
+    assert(result == std::experimental::search(b1, e1, s));
+}
+
+template <class Iter1, class Iter2>
+void
+test()
+{
+    int ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia),      sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia),      sa*sa);
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1),    sa);
+    int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    int ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+    int id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+    int ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+    int ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+    int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    int ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3),  sh*3);
+}
+
+template <class Iter1, class Iter2>
+void
+test2()
+{
+    char ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia),      sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia),      sa*sa);
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1),    sa);
+    char ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    char ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+    char id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+    char ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+    char ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+    char ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    char ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3),  sh*3);
+}
+
+int main() {
+    test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
+    test2<random_access_iterator<const char*>, random_access_iterator<const char*> >();
+}
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
new file mode 100644
index 0000000..d63acf0
--- /dev/null
+++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/hash.pred.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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <functional>
+
+// boyer_moore_horspool searcher
+// template<class RandomAccessIterator1,
+//          class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,
+//          class BinaryPredicate = equal_to<>>
+// class boyer_moore_horspool_searcher {
+// public:
+//   boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last,
+//                                 Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
+// 
+//   template<class RandomAccessIterator2>
+//   pair<RandomAccessIterator2, RandomAccessIterator2>
+//   operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
+// 
+// private:
+//   RandomAccessIterator1 pat_first_; // exposition only
+//   RandomAccessIterator1 pat_last_;  // exposition only
+//   Hash                  hash_;      // exposition only
+//   BinaryPredicate       pred_;      // exposition only
+// };
+
+#include <experimental/algorithm>
+#include <experimental/functional>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <typename T> struct MyHash {
+	size_t operator () (T t) const { return static_cast<size_t>(t); }
+};
+
+struct count_equal
+{
+    static unsigned count;
+    template <class T>
+    bool operator()(const T& x, const T& y) const
+        {++count; return x == y;}
+};
+
+unsigned count_equal::count = 0;
+
+template <typename Iter1, typename Iter2>
+void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) {
+    std::experimental::boyer_moore_horspool_searcher<Iter2, 
+                 MyHash<typename std::remove_cv<typename std::iterator_traits<Iter2>::value_type>::type>,
+                 count_equal>
+          s{b2, e2};
+    assert(result == std::experimental::search(b1, e1, s));
+}
+
+template <class Iter1, class Iter2>
+void
+test()
+{
+    int ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia),      sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia),      sa*sa);
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1),    sa);
+    int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    int ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+    int id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+    int ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+    int ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+    int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    int ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3),  sh*3);
+}
+
+template <class Iter1, class Iter2>
+void
+test2()
+{
+    char ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia),      sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia),      sa*sa);
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1),    sa);
+    char ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    char ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+    char id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+    char ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+    char ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+    char ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    char ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3),  sh*3);
+}
+
+int main() {
+    test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
+    test2<random_access_iterator<const char*>, random_access_iterator<const char*> >();
+}
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
new file mode 100644
index 0000000..3cd41c7
--- /dev/null
+++ b/test/std/experimental/func/func.searchers/func.searchers.boyer_moore_horspool/pred.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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <functional>
+
+// boyer_moore_horspool searcher
+// template<class RandomAccessIterator1,
+//          class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,
+//          class BinaryPredicate = equal_to<>>
+// class boyer_moore_horspool_searcher {
+// public:
+//   boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last,
+//                                 Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
+// 
+//   template<class RandomAccessIterator2>
+//   pair<RandomAccessIterator2, RandomAccessIterator2>
+//   operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
+// 
+// private:
+//   RandomAccessIterator1 pat_first_; // exposition only
+//   RandomAccessIterator1 pat_last_;  // exposition only
+//   Hash                  hash_;      // exposition only
+//   BinaryPredicate       pred_;      // exposition only
+// };
+
+#include <experimental/algorithm>
+#include <experimental/functional>
+#include <cassert>
+
+#include "test_iterators.h"
+
+struct count_equal
+{
+    static unsigned count;
+    template <class T>
+    bool operator()(const T& x, const T& y) const
+        {++count; return x == y;}
+};
+
+unsigned count_equal::count = 0;
+
+template <typename Iter1, typename Iter2>
+void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) {
+    std::experimental::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));
+//    assert(count_equal::count <= max_count);
+}
+
+template <class Iter1, class Iter2>
+void
+test()
+{
+    int ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia),      sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia),      sa*sa);
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1),    sa);
+    int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    int ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+    int id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+    int ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+    int ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+    int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    int ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3),  sh*3);
+}
+
+template <class Iter1, class Iter2>
+void
+test2()
+{
+    char ia[] = {0, 1, 2, 3, 4, 5};
+    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia),    Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+1),  Iter1(ia),      sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+1),    Iter2(ia+2),  Iter1(ia+1),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+2),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+2),    Iter2(ia+3),  Iter1(ia+2),    sa);
+    do_search(Iter1(ia), Iter1(ia),      Iter2(ia+2),    Iter2(ia+3),  Iter1(ia),      0);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+    do_search(Iter1(ia), Iter1(ia+sa),   Iter2(ia),      Iter2(ia+sa), Iter1(ia),      sa*sa);
+    do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia),      Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+    do_search(Iter1(ia), Iter1(ia+1),    Iter2(ia),      Iter2(ia+sa), Iter1(ia+1),    sa);
+    char ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    char ic[] = {1};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+    char id[] = {1, 2};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+    char ie[] = {1, 2, 3};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+    char ig[] = {1, 2, 3, 4};
+    do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+    char ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+    const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+    char ii[] = {1, 1, 2};
+    do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3),  sh*3);
+}
+
+int main() {
+    test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
+    test2<random_access_iterator<const char*>, random_access_iterator<const char*> >();
+}
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 446dcbd..a2dbceb 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
@@ -20,7 +20,8 @@
 //         : __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_);
 //         }
 // 
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 b65c500..e951b46 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
@@ -20,7 +20,8 @@
 //         : __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_);
 //         }
 // 
diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/std/experimental/iterator/nothing_to_do.pass.cpp
similarity index 62%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/experimental/iterator/nothing_to_do.pass.cpp
index e16e439..892d689 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/experimental/iterator/nothing_to_do.pass.cpp
@@ -7,16 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+#include <experimental/iterator>
 
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
-
-int main()
-{
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
-}
+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 0000000..5c8e4ff
--- /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 0000000..a8c1b28
--- /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 0000000..acdcd8b
--- /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 0000000..e3872c3
--- /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 0000000..87b493e
--- /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 0000000..794346d
--- /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 0000000..77ffb51
--- /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 0000000..ba3710d
--- /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 0000000..1007556
--- /dev/null
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.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() 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 0000000..19d9646
--- /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 0000000..aadfbcc
--- /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 0000000..d5a3d01
--- /dev/null
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp
@@ -0,0 +1,133 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler 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 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 0000000..e837576
--- /dev/null
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.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/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 0000000..1a6ce87
--- /dev/null
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp
@@ -0,0 +1,111 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler 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>::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 0000000..9ce0404
--- /dev/null
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.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.
+//
+//===----------------------------------------------------------------------===//
+
+// 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 0000000..6fbe1a3
--- /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,111 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler 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 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 0000000..67d16bd
--- /dev/null
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.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/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 0000000..d4c8e03
--- /dev/null
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.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/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 0000000..206bfb0
--- /dev/null
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp
@@ -0,0 +1,129 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler 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<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 0000000..9f515e9
--- /dev/null
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp
@@ -0,0 +1,189 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++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 0000000..b631f6e
--- /dev/null
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.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/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 0000000..f117bf0
--- /dev/null
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.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/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 0000000..5f5411b
--- /dev/null
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// 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 0000000..92933ce
--- /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,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.
+//
+//===----------------------------------------------------------------------===//
+
+// 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/containers/sequences/vector/const_value_type.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp
similarity index 62%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp
index e16e439..86bf8cc 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp
@@ -7,16 +7,4 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
-
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
-
-int main()
-{
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
-}
+int main () {}
diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp
similarity index 62%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp
index e16e439..86bf8cc 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp
@@ -7,16 +7,4 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
-
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
-
-int main()
-{
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
-}
+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 0000000..4de30bc
--- /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 0000000..f3ecc98
--- /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 0000000..4abc69f
--- /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 0000000..875c3e0
--- /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 = 0; 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 0000000..ff4b317
--- /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 0000000..898543f
--- /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 0000000..b41fbf7
--- /dev/null
+++ b/test/std/experimental/memory/memory.resource.aliases/header_deque_synop.pass.cpp
@@ -0,0 +1,36 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// 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 0000000..ab588b8
--- /dev/null
+++ b/test/std/experimental/memory/memory.resource.aliases/header_forward_list_synop.pass.cpp
@@ -0,0 +1,36 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// 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 0000000..9c2c917
--- /dev/null
+++ b/test/std/experimental/memory/memory.resource.aliases/header_list_synop.pass.cpp
@@ -0,0 +1,36 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// 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 0000000..37e9cf6
--- /dev/null
+++ b/test/std/experimental/memory/memory.resource.aliases/header_map_synop.pass.cpp
@@ -0,0 +1,68 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// 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 0000000..706a763
--- /dev/null
+++ b/test/std/experimental/memory/memory.resource.aliases/header_regex_synop.pass.cpp
@@ -0,0 +1,56 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// 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 0000000..6823006
--- /dev/null
+++ b/test/std/experimental/memory/memory.resource.aliases/header_set_synop.pass.cpp
@@ -0,0 +1,66 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// 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 0000000..c160a09
--- /dev/null
+++ b/test/std/experimental/memory/memory.resource.aliases/header_string_synop.pass.cpp
@@ -0,0 +1,72 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// 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 0000000..77f44a9
--- /dev/null
+++ b/test/std/experimental/memory/memory.resource.aliases/header_unordered_map_synop.pass.cpp
@@ -0,0 +1,86 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// 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 0000000..214c7dc
--- /dev/null
+++ b/test/std/experimental/memory/memory.resource.aliases/header_unordered_set_synop.pass.cpp
@@ -0,0 +1,84 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// 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, 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, 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 0000000..814ade6
--- /dev/null
+++ b/test/std/experimental/memory/memory.resource.aliases/header_vector_synop.pass.cpp
@@ -0,0 +1,36 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// 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 0000000..c89c49d
--- /dev/null
+++ b/test/std/experimental/memory/memory.resource.global/default_resource.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/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 0000000..bd8c121
--- /dev/null
+++ b/test/std/experimental/memory/memory.resource.global/new_delete_resource.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/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 0000000..2be7436
--- /dev/null
+++ b/test/std/experimental/memory/memory.resource.global/null_memory_resource.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/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/containers/sequences/vector/const_value_type.pass.cpp b/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp
similarity index 65%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp
index e16e439..9a59227 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp
@@ -1,3 +1,4 @@
+// -*- C++ -*-
 //===----------------------------------------------------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
@@ -7,16 +8,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
-
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
-
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
 }
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 0000000..d990714
--- /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 0000000..0ccdeed
--- /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 0000000..ede1bfd
--- /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/containers/sequences/vector/const_value_type.pass.cpp b/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp
similarity index 62%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp
index e16e439..86bf8cc 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp
@@ -7,16 +7,4 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
-
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
-
-int main()
-{
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
-}
+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 0000000..eddfede
--- /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 0000000..26cf903
--- /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 0000000..d1a4ab2
--- /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 0000000..9e1d286
--- /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 0000000..32792cf
--- /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/containers/sequences/vector/const_value_type.pass.cpp b/test/std/experimental/memory/nothing_to_do.pass.cpp
similarity index 65%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/experimental/memory/nothing_to_do.pass.cpp
index e16e439..9a59227 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/experimental/memory/nothing_to_do.pass.cpp
@@ -1,3 +1,4 @@
+// -*- C++ -*-
 //===----------------------------------------------------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
@@ -7,16 +8,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
-
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
-
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
 }
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 81c3b4e..999d03d 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 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <optional>
 
 // optional<T>& operator=(const optional<T>& rhs);
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 c4361ea..ec98ef4 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 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <optional>
 
 // template <class... Args> void optional<T>::emplace(Args&&... args);
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 8d20be3..aada0f4 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 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <optional>
 
 // template <class U, class... Args>
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 d27313d..3e084e5 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 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <optional>
 
 // optional<T>& operator=(optional<T>&& rhs)
diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/const_T.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/const_T.pass.cpp
index 071f594..9b6511a 100644
--- a/test/std/experimental/optional/optional.object/optional.object.ctor/const_T.pass.cpp
+++ b/test/std/experimental/optional/optional.object/optional.object.ctor/const_T.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: c++98, c++03, c++11
+// XFAIL: libcpp-no-exceptions
 
 // <optional>
 
@@ -15,8 +18,6 @@
 #include <type_traits>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
-
 using std::experimental::optional;
 
 class X
@@ -39,18 +40,14 @@
 
 class Z
 {
-    int i_;
 public:
-    Z(int i) : i_(i) {}
+    Z(int)  {}
     Z(const Z&) {throw 6;}
 };
 
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     {
         typedef int T;
         constexpr T t(5);
@@ -113,5 +110,4 @@
             assert(i == 6);
         }
     }
-#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 8726f95..7d401de 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 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <optional>
 
 // optional(const optional<T>& rhs);
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 412c993..014ee85 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
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: c++98, c++03, c++11
+// XFAIL: libcpp-no-exceptions
 
 // <optional>
 
@@ -16,7 +19,6 @@
 #include <type_traits>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
 
 using std::experimental::optional;
 using std::experimental::in_place_t;
@@ -52,17 +54,13 @@
 
 class Z
 {
-    int i_;
 public:
-    Z(int i) : i_(i) {throw 6;}
+    Z(int i) {throw 6;}
 };
 
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     {
         constexpr optional<int> opt(in_place, 5);
         static_assert(static_cast<bool>(opt) == true, "");
@@ -141,5 +139,4 @@
             assert(i == 6);
         }
     }
-#endif  // _LIBCPP_STD_VER > 11
 }
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 98cb929..7a98e0b 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 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <optional>
 
 // template <class U, class... Args>
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 b320c95..40d55f9 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 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <optional>
 
 // optional(optional<T>&& rhs) noexcept(is_nothrow_move_constructible<T>::value);
diff --git a/test/std/experimental/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp b/test/std/experimental/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
index ac52a42..ef21fcd 100644
--- a/test/std/experimental/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
+++ b/test/std/experimental/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: c++98, c++03, c++11
+// XFAIL: libcpp-no-exceptions
 
 // <optional>
 
@@ -15,8 +18,6 @@
 #include <type_traits>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
-
 using std::experimental::optional;
 
 class X
@@ -41,17 +42,14 @@
 
 class Z
 {
-    int i_;
 public:
-    Z(int i) : i_(i) {}
+    Z(int) {}
     Z(Z&&) {throw 6;}
 };
 
-#endif  // _LIBCPP_STD_VER > 11
 
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     {
         typedef int T;
         constexpr optional<T> opt(T(5));
@@ -106,5 +104,4 @@
             assert(i == 6);
         }
     }
-#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 e91805e..85f9be6 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 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <optional>
 
 // T& optional<T>::value();
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 39bf687..c99baab 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 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <optional>
 
 // constexpr const T& optional<T>::value() const;
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 e0ecfde..d24a2d0 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 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <optional>
 
 // void swap(optional&)
diff --git a/test/std/experimental/optional/optional.specalg/swap.pass.cpp b/test/std/experimental/optional/optional.specalg/swap.pass.cpp
index e31d217..6c5f7b0 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 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <optional>
 
 // template <class T> void swap(optional<T>& x, optional<T>& y)
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 3003ea8..46804d4 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,12 +10,14 @@
 // 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>
 
 // constexpr const _CharT& at(size_type _pos) const;
 
 #include <experimental/string_view>
+#include <stdexcept>
 #include <cassert>
 
 template <typename CharT>
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 6b20639..7ccbd52 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,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string_view>
 
 // constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
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 2047862..244de9e 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
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 
+// XFAIL: libcpp-no-exceptions
 // <string_view>
 
 // constexpr int compare(size_type pos1, size_type n1, basic_string_view str) const;
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 acb48f5..1c3bc08 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
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 
+// XFAIL: libcpp-no-exceptions
 // <string_view>
 
 // constexpr int compare(size_type pos1, size_type n1,
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 33407ef..c7a6f1e 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
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 
+// XFAIL: libcpp-no-exceptions
 // <string_view>
 
 // constexpr int compare(size_type pos1, size_type n1, basic_string_view str,
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 96246d2..0e4eb9e 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
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 
+// XFAIL: libcpp-no-exceptions
 // <string_view>
 
 // size_type copy(charT* s, size_type n, size_type pos = 0) const;
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 1236462..c80e90a 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
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 
+// XFAIL: libcpp-no-exceptions
 // <string_view>
 
 // constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
diff --git a/test/std/experimental/utilities/tuple/tuple.apply/arg_type.pass.cpp b/test/std/experimental/utilities/tuple/tuple.apply/arg_type.pass.cpp
index 56dc3c6..cb44707 100644
--- a/test/std/experimental/utilities/tuple/tuple.apply/arg_type.pass.cpp
+++ b/test/std/experimental/utilities/tuple/tuple.apply/arg_type.pass.cpp
@@ -20,6 +20,11 @@
 #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"
+
+
 namespace ex = std::experimental;
 
 int call_with_value(int x, int y) { return (x + y); }
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 2d70048..5b8a8f0 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/extended_types.pass.cpp b/test/std/experimental/utilities/tuple/tuple.apply/extended_types.pass.cpp
index 3225549..0c5170f 100644
--- a/test/std/experimental/utilities/tuple/tuple.apply/extended_types.pass.cpp
+++ b/test/std/experimental/utilities/tuple/tuple.apply/extended_types.pass.cpp
@@ -22,6 +22,10 @@
 #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
diff --git a/test/std/experimental/utilities/tuple/tuple.apply/types.pass.cpp b/test/std/experimental/utilities/tuple/tuple.apply/types.pass.cpp
index 5d3d564..52eec27 100644
--- a/test/std/experimental/utilities/tuple/tuple.apply/types.pass.cpp
+++ b/test/std/experimental/utilities/tuple/tuple.apply/types.pass.cpp
@@ -20,6 +20,10 @@
 #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"
+
 namespace ex = std::experimental;
 
 int count = 0;
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 ec4ad8a..c42e205 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,8 +78,11 @@
 
 #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()
 {
@@ -88,6 +91,11 @@
     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/fstreams/filebuf.virtuals/overflow.pass.cpp b/test/std/input.output/file.streams/fstreams/filebuf.virtuals/overflow.pass.cpp
index 1da3856..042fe03 100644
--- a/test/std/input.output/file.streams/fstreams/filebuf.virtuals/overflow.pass.cpp
+++ b/test/std/input.output/file.streams/fstreams/filebuf.virtuals/overflow.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <fstream>
 
 // int_type overflow(int_type c = traits::eof());
diff --git a/test/std/input.output/file.streams/fstreams/filebuf.virtuals/underflow.pass.cpp b/test/std/input.output/file.streams/fstreams/filebuf.virtuals/underflow.pass.cpp
index e34bc84..9ada23b 100644
--- a/test/std/input.output/file.streams/fstreams/filebuf.virtuals/underflow.pass.cpp
+++ b/test/std/input.output/file.streams/fstreams/filebuf.virtuals/underflow.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <fstream>
 
 // int_type underflow();
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 17ff642..a8b82a6 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
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <iomanip>
 
 // template <class charT> T9 get_time(struct tm* tmb, const charT* fmt);
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 52a98a1..f4e3ded 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
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <iomanip>
 
 // template <class charT> T10 put_time(const struct tm* tmb, const charT* fmt);
diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp
index e6f4e1e..dc4e0ba 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp
@@ -63,4 +63,13 @@
         is.seekg(-1);
         assert(is.fail());
     }
+    {
+        testbuf<char> sb(" 123456789");
+        std::istream is(&sb);
+        is.setstate(std::ios_base::eofbit);
+        assert(is.eof());
+        is.seekg(5);
+        assert(is.good());
+        assert(!is.eof());
+    }
 }
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 73f3da1..818d42c 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 @@
     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);
@@ -71,4 +71,13 @@
         assert(is.fail());
         assert(seekoff_called == 4);
     }
+    {
+        testbuf<char> sb(" 123456789");
+        std::istream is(&sb);
+        is.setstate(std::ios_base::eofbit);
+        assert(is.eof());
+        is.seekg(5, std::ios_base::beg);
+        assert(is.good());
+        assert(!is.eof());
+    }
 }
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
similarity index 65%
rename from test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minus1.pass
rename to test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minus1.pass.cpp
index 27b8cfd..47e257a 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 @@
 {
     std::stringstream ss;
     ss << std::oct << static_cast<T>(-1);
-    
     assert(ss.str() == expected);
 }
 
@@ -39,8 +40,6 @@
 {
     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 @@
 {
     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 @@
     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 @@
     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/output.streams/ostream_sentry/destruct.pass.cpp b/test/std/input.output/iostream.format/output.streams/ostream_sentry/destruct.pass.cpp
index 112928c..a8ef34e 100644
--- a/test/std/input.output/iostream.format/output.streams/ostream_sentry/destruct.pass.cpp
+++ b/test/std/input.output/iostream.format/output.streams/ostream_sentry/destruct.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <ostream>
 
 // template <class charT, class traits = char_traits<charT> >
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 d09b3ca..a494357 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
+#include "test_macros.h"
 
-bool is_skipws ( const std::istream *is ) {
-    return ( is->flags() & std::ios_base::skipws ) != 0;
+#if TEST_STD_VER > 11
+
+template <class CharT, class Traits>
+bool is_skipws ( const std::basic_istream<CharT, Traits>& is ) {
+    return ( is.flags() & std::ios_base::skipws ) != 0;
     }
 
-
-bool is_skipws ( const std::wistream *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;
 }
 
@@ -107,61 +123,6 @@
 }
 
 
-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
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 2f516f8..2b4db2b 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;
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 bdd362d..789f927 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
diff --git a/test/std/input.output/iostreams.base/ios.base/ios.base.callback/register_callback.pass.cpp b/test/std/input.output/iostreams.base/ios.base/ios.base.callback/register_callback.pass.cpp
index c0ed315..f4d541e 100644
--- a/test/std/input.output/iostreams.base/ios.base/ios.base.callback/register_callback.pass.cpp
+++ b/test/std/input.output/iostreams.base/ios.base/ios.base.callback/register_callback.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <ios>
 
 // class ios_base
diff --git a/test/std/input.output/iostreams.base/ios.base/ios.base.locales/imbue.pass.cpp b/test/std/input.output/iostreams.base/ios.base/ios.base.locales/imbue.pass.cpp
index 4e34c08..1cad020 100644
--- a/test/std/input.output/iostreams.base/ios.base/ios.base.locales/imbue.pass.cpp
+++ b/test/std/input.output/iostreams.base/ios.base/ios.base.locales/imbue.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <ios>
 
 // class ios_base
diff --git a/test/std/input.output/iostreams.base/ios.base/ios.types/ios_failure/ctor_string_error_code.pass.cpp b/test/std/input.output/iostreams.base/ios.base/ios.types/ios_failure/ctor_string_error_code.pass.cpp
index 5c9abbe..a9c5f30 100644
--- a/test/std/input.output/iostreams.base/ios.base/ios.types/ios_failure/ctor_string_error_code.pass.cpp
+++ b/test/std/input.output/iostreams.base/ios.base/ios.types/ios_failure/ctor_string_error_code.pass.cpp
@@ -19,6 +19,9 @@
 
 int main()
 {
+    // LWG2462 std::ios_base::failure is overspecified
+    static_assert((std::is_base_of<std::system_error, std::ios_base::failure>::value), "");
+
     {
         std::string what_arg("io test message");
         std::ios_base::failure se(what_arg, make_error_code(std::errc::is_a_directory));
diff --git a/test/std/input.output/iostreams.base/ios/basic.ios.members/copyfmt.pass.cpp b/test/std/input.output/iostreams.base/ios/basic.ios.members/copyfmt.pass.cpp
index c46e2c0..acefb8d 100644
--- a/test/std/input.output/iostreams.base/ios/basic.ios.members/copyfmt.pass.cpp
+++ b/test/std/input.output/iostreams.base/ios/basic.ios.members/copyfmt.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // REQUIRES: locale.en_US.UTF-8
 // REQUIRES: locale.fr_FR.UTF-8
 
diff --git a/test/std/input.output/iostreams.base/ios/basic.ios.members/imbue.pass.cpp b/test/std/input.output/iostreams.base/ios/basic.ios.members/imbue.pass.cpp
index 6d4ce5f..1c1c8be 100644
--- a/test/std/input.output/iostreams.base/ios/basic.ios.members/imbue.pass.cpp
+++ b/test/std/input.output/iostreams.base/ios/basic.ios.members/imbue.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <ios>
 
 // template <class charT, class traits> class basic_ios
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 509b836..0b068e0 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 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 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 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
similarity index 100%
rename from test/std/input.output/iostreams.base/ios/basic.ios.members/narow.pass.cpp
rename to 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/set_rdbuf.pass.cpp b/test/std/input.output/iostreams.base/ios/basic.ios.members/set_rdbuf.pass.cpp
index 2d4beee..1c40a81 100644
--- a/test/std/input.output/iostreams.base/ios/basic.ios.members/set_rdbuf.pass.cpp
+++ b/test/std/input.output/iostreams.base/ios/basic.ios.members/set_rdbuf.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <ios>
 
 // template <class charT, class traits> class basic_ios
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 e44f4b3..2887ca1 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 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/iostreams.base/ios/iostate.flags/clear.pass.cpp b/test/std/input.output/iostreams.base/ios/iostate.flags/clear.pass.cpp
index 0c2e8f0..c4aad79 100644
--- a/test/std/input.output/iostreams.base/ios/iostate.flags/clear.pass.cpp
+++ b/test/std/input.output/iostreams.base/ios/iostate.flags/clear.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <ios>
 
 // template <class charT, class traits> class basic_ios
diff --git a/test/std/input.output/iostreams.base/ios/iostate.flags/exceptions_iostate.pass.cpp b/test/std/input.output/iostreams.base/ios/iostate.flags/exceptions_iostate.pass.cpp
index a0013ea..9347644 100644
--- a/test/std/input.output/iostreams.base/ios/iostate.flags/exceptions_iostate.pass.cpp
+++ b/test/std/input.output/iostreams.base/ios/iostate.flags/exceptions_iostate.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <ios>
 
 // template <class charT, class traits> class basic_ios
diff --git a/test/std/input.output/iostreams.base/ios/iostate.flags/setstate.pass.cpp b/test/std/input.output/iostreams.base/ios/iostate.flags/setstate.pass.cpp
index b3c66c4..41cb61d 100644
--- a/test/std/input.output/iostreams.base/ios/iostate.flags/setstate.pass.cpp
+++ b/test/std/input.output/iostreams.base/ios/iostate.flags/setstate.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <ios>
 
 // template <class charT, class traits> class basic_ios
diff --git a/test/std/input.output/stream.buffers/streambuf/streambuf.cons/copy.pass.cpp b/test/std/input.output/stream.buffers/streambuf/streambuf.cons/copy.pass.cpp
index c1e1839..7ca8f37 100644
--- a/test/std/input.output/stream.buffers/streambuf/streambuf.cons/copy.pass.cpp
+++ b/test/std/input.output/stream.buffers/streambuf/streambuf.cons/copy.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <streambuf>
 
 // template <class charT, class traits = char_traits<charT> >
diff --git a/test/std/input.output/stream.buffers/streambuf/streambuf.cons/default.pass.cpp b/test/std/input.output/stream.buffers/streambuf/streambuf.cons/default.pass.cpp
index d8ca8ae..0572a9b 100644
--- a/test/std/input.output/stream.buffers/streambuf/streambuf.cons/default.pass.cpp
+++ b/test/std/input.output/stream.buffers/streambuf/streambuf.cons/default.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <streambuf>
 
 // template <class charT, class traits = char_traits<charT> >
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 730cede..1935308 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 @@
     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 34a2a2d..2f4aad0 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 @@
     }
 
 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 4c68fad..36a19da 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 @@
     }
 
 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 b04b8b0..5ea48c1 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 @@
     }
 
 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 e03e8e0..4ced690 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 @@
     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/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.assign/assign.pass.cpp b/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.assign/assign.pass.cpp
index 8031989..fc1a18f 100644
--- a/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.assign/assign.pass.cpp
+++ b/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.assign/assign.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <streambuf>
 
 // template <class charT, class traits = char_traits<charT> >
diff --git a/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.assign/swap.pass.cpp b/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.assign/swap.pass.cpp
index 7a23206..4ede8a5 100644
--- a/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.assign/swap.pass.cpp
+++ b/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.assign/swap.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <streambuf>
 
 // template <class charT, class traits = char_traits<charT> >
diff --git a/test/std/iterators/iterator.primitives/iterator.operations/next.pass.cpp b/test/std/iterators/iterator.primitives/iterator.operations/next.pass.cpp
index f584110..0952588 100644
--- a/test/std/iterators/iterator.primitives/iterator.operations/next.pass.cpp
+++ b/test/std/iterators/iterator.primitives/iterator.operations/next.pass.cpp
@@ -12,6 +12,8 @@
 // template <InputIterator Iter>
 //   Iter next(Iter x, Iter::difference_type n = 1);
 
+// LWG #2353 relaxed the requirement on next from ForwardIterator to InputIterator
+
 #include <iterator>
 #include <cassert>
 
@@ -34,11 +36,13 @@
 int main()
 {
     const char* s = "1234567890";
+    test(input_iterator<const char*>(s), 10, input_iterator<const char*>(s+10));
     test(forward_iterator<const char*>(s), 10, forward_iterator<const char*>(s+10));
     test(bidirectional_iterator<const char*>(s), 10, bidirectional_iterator<const char*>(s+10));
     test(random_access_iterator<const char*>(s), 10, random_access_iterator<const char*>(s+10));
     test(s, 10, s+10);
 
+    test(input_iterator<const char*>(s), input_iterator<const char*>(s+1));
     test(forward_iterator<const char*>(s), forward_iterator<const char*>(s+1));
     test(bidirectional_iterator<const char*>(s), bidirectional_iterator<const char*>(s+1));
     test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s+1));
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 0f368c3..ecda1d1 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 0936595..e11b8e9 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 afeac3e..19b517c 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 7f7f66a..e315b27 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 04f830b..f16a3b7 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/predef.iterators/move.iterators/move.iterator/types.pass.cpp b/test/std/iterators/predef.iterators/move.iterators/move.iterator/types.pass.cpp
index 9bdf721..a6d4d61 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 @@
     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 @@
     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/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 5c4ddca..30057a2 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 @@
     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 85a70a0..1250e36 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/types.pass.cpp b/test/std/iterators/stream.iterators/istreambuf.iterator/types.pass.cpp
index 2ad927c..2507ae3 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,
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 321cfbd..6366355 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
similarity index 70%
rename from test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.cons.des/ostream_delem.pass.cpp
rename to test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.cons.des/ostream_delim.pass.cpp
index 8e5c771..69c2dfc 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 @@
         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/iterators/stream.iterators/ostream.iterator/ostream.iterator.ops/assign_t.pass.cpp b/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.ops/assign_t.pass.cpp
index 02ef571..932ef25 100644
--- a/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.ops/assign_t.pass.cpp
+++ b/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.ops/assign_t.pass.cpp
@@ -17,6 +17,10 @@
 #include <sstream>
 #include <cassert>
 
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wliteral-conversion"
+#endif
+
 int main()
 {
     {
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp
index a1a3035..55a3200 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // test operator new[]
 // NOTE: asan and msan will not call the new handler.
 // UNSUPPORTED: sanitizer-new-delete
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp
index b0db4a8..9531b1c 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // test operator new [] (nothrow)
 // NOTE: asan and msan will not call the new handler.
 // UNSUPPORTED: sanitizer-new-delete
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 5dc9f71..57ce287 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
@@ -7,6 +7,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.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp
index 8c095ad..c2f5830 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // test operator new (nothrow)
 
 // asan and msan will not call the new handler.
diff --git a/test/std/language.support/support.exception/except.nested/assign.pass.cpp b/test/std/language.support/support.exception/except.nested/assign.pass.cpp
index cbe303c..a5508d1 100644
--- a/test/std/language.support/support.exception/except.nested/assign.pass.cpp
+++ b/test/std/language.support/support.exception/except.nested/assign.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <exception>
 
 // class nested_exception;
diff --git a/test/std/language.support/support.exception/except.nested/ctor_copy.pass.cpp b/test/std/language.support/support.exception/except.nested/ctor_copy.pass.cpp
index bfa1370..f9f2933 100644
--- a/test/std/language.support/support.exception/except.nested/ctor_copy.pass.cpp
+++ b/test/std/language.support/support.exception/except.nested/ctor_copy.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <exception>
 
 // class nested_exception;
diff --git a/test/std/language.support/support.exception/except.nested/ctor_default.pass.cpp b/test/std/language.support/support.exception/except.nested/ctor_default.pass.cpp
index 1422f77..67766aa 100644
--- a/test/std/language.support/support.exception/except.nested/ctor_default.pass.cpp
+++ b/test/std/language.support/support.exception/except.nested/ctor_default.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <exception>
 
 // class nested_exception;
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 567ed57..a8b6e15 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <exception>
 
 // class nested_exception;
@@ -36,6 +37,13 @@
     B(const B& b) : A(b) {}
 };
 
+class C
+{
+public:
+	virtual ~C() {}
+	C * operator&() const { assert(false); } // should not be called
+};
+
 int main()
 {
     {
@@ -78,7 +86,7 @@
     {
         try
         {
-            std::rethrow_if_nested(1);
+            std::rethrow_if_nested(C());
             assert(true);
         }
         catch (...)
@@ -86,4 +94,5 @@
             assert(false);
         }
     }
+
 }
diff --git a/test/std/language.support/support.exception/except.nested/rethrow_nested.pass.cpp b/test/std/language.support/support.exception/except.nested/rethrow_nested.pass.cpp
index b072690..13c1dfe 100644
--- a/test/std/language.support/support.exception/except.nested/rethrow_nested.pass.cpp
+++ b/test/std/language.support/support.exception/except.nested/rethrow_nested.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <exception>
 
 // class nested_exception;
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 dad0df2..b507ecc 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <exception>
 
 // class nested_exception;
@@ -111,7 +112,7 @@
             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 9ff0d6e..7bf1df4 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <exception>
 
 // exception_ptr current_exception();
@@ -73,7 +74,7 @@
             throw A();
             assert(false);
         }
-        catch (A& a)
+        catch (A&)
         {
             std::exception_ptr p = std::current_exception();
             assert(A::constructed == 1);
@@ -93,7 +94,7 @@
             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.exception/propagation/make_exception_ptr.pass.cpp b/test/std/language.support/support.exception/propagation/make_exception_ptr.pass.cpp
index 89c9f85..6e4c0a9 100644
--- a/test/std/language.support/support.exception/propagation/make_exception_ptr.pass.cpp
+++ b/test/std/language.support/support.exception/propagation/make_exception_ptr.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <exception>
 
 // template<class E> exception_ptr make_exception_ptr(E e);
diff --git a/test/std/language.support/support.exception/propagation/rethrow_exception.pass.cpp b/test/std/language.support/support.exception/propagation/rethrow_exception.pass.cpp
index e47a598..c28c901 100644
--- a/test/std/language.support/support.exception/propagation/rethrow_exception.pass.cpp
+++ b/test/std/language.support/support.exception/propagation/rethrow_exception.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <exception>
 
 // void rethrow_exception [[noreturn]] (exception_ptr p);
diff --git a/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp b/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp
index 22d8d8e..573d85b 100644
--- a/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp
+++ b/test/std/language.support/support.exception/uncaught/uncaught_exception.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // test uncaught_exception
 
 #include <exception>
diff --git a/test/std/language.support/support.exception/uncaught/uncaught_exceptions.pass.cpp b/test/std/language.support/support.exception/uncaught/uncaught_exceptions.pass.cpp
index 1adc904..b35ad73 100644
--- a/test/std/language.support/support.exception/uncaught/uncaught_exceptions.pass.cpp
+++ b/test/std/language.support/support.exception/uncaught/uncaught_exceptions.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // test uncaught_exceptions
 
 #include <exception>
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp
index af93e78..23811fa 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp
@@ -13,7 +13,8 @@
 
 #include <limits>
 
-#if defined(__i386__) || defined(__x86_64__) || defined(__pnacl__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__pnacl__) || \
+    defined(__wasm__)
 static const bool integral_types_trap = true;
 #else
 static const bool integral_types_trap = false;
diff --git a/test/std/language.support/support.runtime/csetjmp.pass.cpp b/test/std/language.support/support.runtime/csetjmp.pass.cpp
index dc034ce..f506030 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/cstdlib.pass.cpp b/test/std/language.support/support.runtime/cstdlib.pass.cpp
index 8191350..d8f88cf 100644
--- a/test/std/language.support/support.runtime/cstdlib.pass.cpp
+++ b/test/std/language.support/support.runtime/cstdlib.pass.cpp
@@ -13,6 +13,12 @@
 #include <type_traits>
 #include <cassert>
 
+// As of 1/10/2015 clang emits a -Wnonnull warnings even if the warning occurs
+// in an unevaluated context. For this reason we manually suppress the warning.
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wnonnull"
+#endif
+
 #ifndef EXIT_FAILURE
 #error EXIT_FAILURE not defined
 #endif
diff --git a/test/std/language.support/support.runtime/ctime.pass.cpp b/test/std/language.support/support.runtime/ctime.pass.cpp
index 03a0aa4..5f29486 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};
+    ((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 @@
 #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 4d7c8b0..ca5170f 100644
--- a/test/std/language.support/support.types/nullptr_t.pass.cpp
+++ b/test/std/language.support/support.types/nullptr_t.pass.cpp
@@ -52,6 +52,28 @@
     assert(!(nullptr > p));
 }
 
+#if defined(__clang__)
+#pragma clang diagnostic push
+#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);
+    }
+}
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
 
 int main()
 {
@@ -72,8 +94,5 @@
         test_comparisons<A*>();
         test_comparisons<void(*)()>();
     }
-    {
-        bool b = nullptr;
-        assert(!b);
-    }
+    test_nullptr_conversions();
 }
diff --git a/test/std/localization/c.locales/clocale.pass.cpp b/test/std/localization/c.locales/clocale.pass.cpp
index a90725b..5342134 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 69af9ac..09009ce 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
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // template <class charT> class collate_byname
diff --git a/test/std/localization/locale.categories/category.collate/locale.collate.byname/hash.pass.cpp b/test/std/localization/locale.categories/category.collate/locale.collate.byname/hash.pass.cpp
index f8641cb..df67f43 100644
--- a/test/std/localization/locale.categories/category.collate/locale.collate.byname/hash.pass.cpp
+++ b/test/std/localization/locale.categories/category.collate/locale.collate.byname/hash.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // template <class charT> class collate_byname
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 8971412..d31705e 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
@@ -26,7 +26,7 @@
 int main()
 {
     // Ensure that the default locale is not C.  If it is, the second tests will fail.
-    putenv(const_cast<char*>("LANG=" LOCALE_en_US_UTF_8));
+    putenv(const_cast<char*>("LC_ALL=" LOCALE_en_US_UTF_8));
     {
         std::locale l(LOCALE_en_US_UTF_8);
         {
diff --git a/test/std/localization/locale.categories/category.collate/locale.collate.byname/types.pass.cpp b/test/std/localization/locale.categories/category.collate/locale.collate.byname/types.pass.cpp
index 04974b2..7c07c71 100644
--- a/test/std/localization/locale.categories/category.collate/locale.collate.byname/types.pass.cpp
+++ b/test/std/localization/locale.categories/category.collate/locale.collate.byname/types.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // template <class charT>
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt.byname/ctor_wchar_t.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt.byname/ctor_wchar_t.pass.cpp
index bc55f00..adaf4e8 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt.byname/ctor_wchar_t.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt.byname/ctor_wchar_t.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // template <> class codecvt_byname<wchar_t, char, mbstate_t>
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_in.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_in.pass.cpp
index 331f4ba..41c2650 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_in.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_in.pass.cpp
@@ -28,7 +28,7 @@
     const char from[] = "some text";
     F::intern_type to[9];
     const F& f = std::use_facet<F>(l);
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     const char* from_next = 0;
     F::intern_type* to_next = 0;
     assert(f.in(mbs, from, from + 9, from_next,
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_length.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_length.pass.cpp
index 34ab217..bd34829 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_length.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_length.pass.cpp
@@ -22,7 +22,7 @@
 {
     std::locale l = std::locale::classic();
     const F& f = std::use_facet<F>(l);
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     const char from[] = "some text";
     assert(f.length(mbs, from, from+10, 0) == 0);
     assert(f.length(mbs, from, from+10, 8) == 8);
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_out.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_out.pass.cpp
index 0f65f13..1899771 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_out.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_out.pass.cpp
@@ -31,7 +31,7 @@
     {
         F::intern_type from[9] = {'s', 'o', 'm', 'e', ' ', 't', 'e', 'x', 't'};
         char to[9] = {0};
-        std::mbstate_t mbs = {0};
+        std::mbstate_t mbs = {};
         const F::intern_type* from_next = 0;
         char* to_next = 0;
         F::result r = f.out(mbs, from, from + 9, from_next,
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_unshift.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_unshift.pass.cpp
index c213030..9b91a03 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_unshift.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_unshift.pass.cpp
@@ -26,7 +26,7 @@
     std::locale l = std::locale::classic();
     std::vector<char> to(3);
     const F& f = std::use_facet<F>(l);
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     char* to_next = 0;
     assert(f.unshift(mbs, to.data(), to.data() + to.size(), to_next) == F::noconv);
     assert(to_next == to.data());
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_in.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_in.pass.cpp
index 8fb28f0..8f9d1e6 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_in.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_in.pass.cpp
@@ -28,7 +28,7 @@
     const char from[] = "some text";
     F::intern_type to[9];
     const F& f = std::use_facet<F>(l);
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     const char* from_next = 0;
     F::intern_type* to_next = 0;
     assert(f.in(mbs, from, from + 9, from_next,
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_length.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_length.pass.cpp
index d8555d1..4455b9f 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_length.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_length.pass.cpp
@@ -22,7 +22,7 @@
 {
     std::locale l = std::locale::classic();
     const F& f = std::use_facet<F>(l);
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     const char from[] = "some text";
     assert(f.length(mbs, from, from+10, 0) == 0);
     assert(f.length(mbs, from, from+10, 8) == 8);
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_out.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_out.pass.cpp
index a1d11f7..4e0f600 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_out.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_out.pass.cpp
@@ -31,7 +31,7 @@
     {
         F::intern_type from[9] = {'s', 'o', 'm', 'e', ' ', 't', 'e', 'x', 't'};
         char to[9] = {0};
-        std::mbstate_t mbs = {0};
+        std::mbstate_t mbs = {};
         const F::intern_type* from_next = 0;
         char* to_next = 0;
         F::result r = f.out(mbs, from, from + 9, from_next,
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_unshift.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_unshift.pass.cpp
index 1bd45e0..0a4aa20 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_unshift.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_unshift.pass.cpp
@@ -26,7 +26,7 @@
     std::locale l = std::locale::classic();
     std::vector<char> to(3);
     const F& f = std::use_facet<F>(l);
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     char* to_next = 0;
     assert(f.unshift(mbs, to.data(), to.data() + to.size(), to_next) == F::noconv);
     assert(to_next == to.data());
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_in.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_in.pass.cpp
index 4d2f6f2..10c9fcd 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_in.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_in.pass.cpp
@@ -28,7 +28,7 @@
     const std::basic_string<F::intern_type> from("some text");
     std::vector<char> to(from.size());
     const F& f = std::use_facet<F>(l);
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     const char* from_next = 0;
     char* to_next = 0;
     assert(f.in(mbs, from.data(), from.data() + from.size(), from_next,
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_length.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_length.pass.cpp
index df33b18..c5897c8 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_length.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_length.pass.cpp
@@ -22,7 +22,7 @@
 {
     std::locale l = std::locale::classic();
     const F& f = std::use_facet<F>(l);
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     const char from[10]= {0};
     assert(f.length(mbs, from, from+10, 0) == 0);
     assert(f.length(mbs, from, from+10, 9) == 9);
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_out.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_out.pass.cpp
index de7f024..17bde6c 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_out.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_out.pass.cpp
@@ -28,7 +28,7 @@
     const std::basic_string<F::intern_type> from("some text");
     std::vector<char> to(from.size());
     const F& f = std::use_facet<F>(l);
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     const char* from_next = 0;
     char* to_next = 0;
     assert(f.out(mbs, from.data(), from.data() + from.size(), from_next,
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_unshift.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_unshift.pass.cpp
index 830bc43..834fa0f 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_unshift.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char_unshift.pass.cpp
@@ -26,7 +26,7 @@
     std::locale l = std::locale::classic();
     std::vector<char> to(3);
     const F& f = std::use_facet<F>(l);
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     char* to_next = 0;
     assert(f.unshift(mbs, to.data(), to.data() + to.size(), to_next) == F::noconv);
     assert(to_next == to.data());
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/utf_sanity_check.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/utf_sanity_check.pass.cpp
index 2505582..c256078 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/utf_sanity_check.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/utf_sanity_check.pass.cpp
@@ -30,7 +30,7 @@
     const F32_8& f32_8 = std::use_facet<F32_8>(std::locale::classic());
     const F32_16& f32_16 = std::use_facet<F32_16>(l);
     const F16_8& f16_8 = std::use_facet<F16_8>(std::locale::classic());
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     F32_8::intern_type* c32p;
     F16_8::intern_type* c16p;
     F32_8::extern_type* c8p;
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_in.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_in.pass.cpp
index e98097b..a4ff61b 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_in.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_in.pass.cpp
@@ -29,7 +29,7 @@
     const std::basic_string<F::intern_type> expected(from.begin(), from.end());
     std::basic_string<F::intern_type> to(from.size(), F::intern_type());
     const F& f = std::use_facet<F>(l);
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     const F::extern_type* from_next = 0;
     F::intern_type* to_next = 0;
     F::result r = f.in(mbs, from.data(), from.data() + from.size(), from_next,
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_length.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_length.pass.cpp
index f97f2b4..69037aa 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_length.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_length.pass.cpp
@@ -22,7 +22,7 @@
 {
     std::locale l = std::locale::classic();
     const F& f = std::use_facet<F>(l);
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     const char* from = "123467890";
     assert(f.length(mbs, from, from+10, 0) == 0);
     assert(f.length(mbs, from, from+10, 9) == 9);
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_out.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_out.pass.cpp
index dce2d38..6f025e3 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_out.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_out.pass.cpp
@@ -29,7 +29,7 @@
     {
         const std::basic_string<F::intern_type> from(L"some text");
         std::vector<char> to(from.size()+1);
-        std::mbstate_t mbs = {0};
+        std::mbstate_t mbs = {};
         const F::intern_type* from_next = 0;
         char* to_next = 0;
         F::result r = f.out(mbs, from.data(), from.data() + from.size(), from_next,
@@ -43,7 +43,7 @@
         std::basic_string<F::intern_type> from(L"some text");
         from[4] = '\0';
         std::vector<char> to(from.size()+1);
-        std::mbstate_t mbs = {0};
+        std::mbstate_t mbs = {};
         const F::intern_type* from_next = 0;
         char* to_next = 0;
         F::result r = f.out(mbs, from.data(), from.data() + from.size(), from_next,
@@ -56,7 +56,7 @@
     {
         std::basic_string<F::intern_type> from(L"some text");
         std::vector<char> to(from.size()-1);
-        std::mbstate_t mbs = {0};
+        std::mbstate_t mbs = {};
         const F::intern_type* from_next = 0;
         char* to_next = 0;
         F::result r = f.out(mbs, from.data(), from.data() + from.size(), from_next,
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_unshift.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_unshift.pass.cpp
index 4d8895c..10ab7a2 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_unshift.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_unshift.pass.cpp
@@ -28,7 +28,7 @@
     std::locale l = std::locale::classic();
     std::vector<F::extern_type> to(3);
     const F& f = std::use_facet<F>(l);
-    std::mbstate_t mbs = {0};
+    std::mbstate_t mbs = {};
     F::extern_type* to_next = 0;
     assert(f.unshift(mbs, to.data(), to.data() + to.size(), to_next) == F::ok);
     assert(to_next == to.data());
diff --git a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/tolower_1.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/tolower_1.pass.cpp
index c2eeea8..741f47f 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/tolower_1.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/tolower_1.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // template <class charT> class ctype_byname;
diff --git a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/tolower_many.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/tolower_many.pass.cpp
index b2577e3..bf1cb64 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/tolower_many.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/tolower_many.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // template <class charT> class ctype_byname;
diff --git a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/toupper_1.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/toupper_1.pass.cpp
index 8611293..3044ba1 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/toupper_1.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/toupper_1.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // template <class charT> class ctype_byname;
diff --git a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/toupper_many.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/toupper_many.pass.cpp
index d23a292..be6ba4c 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/toupper_many.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/toupper_many.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // template <class charT> class ctype_byname;
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 03e8dfc..fdfab57 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
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // template <class CharT>
diff --git a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/widen_1.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/widen_1.pass.cpp
index 320e08d..e5c49de 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/widen_1.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/widen_1.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // template <class charT> class ctype_byname;
diff --git a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/widen_many.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/widen_many.pass.cpp
index b46ae32..c16974a 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/widen_many.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/widen_many.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // template <class charT> class ctype_byname;
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 a54b373..596f8f8 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 706d92b..100fd9d 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
@@ -15,6 +15,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
 
@@ -24414,7 +24417,6 @@
 
 void test12()
 {
-    char str[200];
     output_iterator<char*> iter;
     std::locale lc = std::locale::classic();
     std::locale lg(lc, new my_numpunct);
@@ -24422,6 +24424,7 @@
 // This test is failing on FreeBSD, possibly due to different representations
 // of the floating point numbers.  
     const my_facet f(1);
+    char str[200];
     {
         long double v = 1234567890.125;
         std::ios ios(0);
@@ -26220,7 +26223,6 @@
     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.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 a442ae5..931ab5d 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 abreviated
-// 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 @@
         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 631a500..551f298 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 abreviated
-// 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 @@
         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/locales/locale.convenience/conversions/conversions.string/ctor_err_string.pass.cpp b/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_err_string.pass.cpp
index 27a3da7..5a58b06 100644
--- a/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_err_string.pass.cpp
+++ b/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_err_string.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <locale>
 
 // wstring_convert<Codecvt, Elem, Wide_alloc, Byte_alloc>
diff --git a/test/std/localization/locales/locale.global.templates/use_facet.pass.cpp b/test/std/localization/locales/locale.global.templates/use_facet.pass.cpp
index a40a2d2..303fd79 100644
--- a/test/std/localization/locales/locale.global.templates/use_facet.pass.cpp
+++ b/test/std/localization/locales/locale.global.templates/use_facet.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <locale>
 
 // template <class Facet> const Facet& use_facet(const locale& loc);
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 3567bf5..b808a76 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // REQUIRES: locale.ru_RU.UTF-8
 // REQUIRES: locale.zh_CN.UTF-8
 // UNSUPPORTED: sanitizer-new-delete
diff --git a/test/std/localization/locales/locale/locale.cons/default.pass.cpp b/test/std/localization/locales/locale/locale.cons/default.pass.cpp
index 1efc939..2bb3c9a 100644
--- a/test/std/localization/locales/locale/locale.cons/default.pass.cpp
+++ b/test/std/localization/locales/locale/locale.cons/default.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // locale() throw();
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 d48a572..59fbc59 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,7 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-
+ 
+// REQUIRES: locale.en_US.UTF-8
 // REQUIRES: locale.ru_RU.UTF-8
 // UNSUPPORTED: sanitizer-new-delete
 
diff --git a/test/std/localization/locales/locale/locale.members/combine.pass.cpp b/test/std/localization/locales/locale/locale.members/combine.pass.cpp
index e956102..26a760f 100644
--- a/test/std/localization/locales/locale/locale.members/combine.pass.cpp
+++ b/test/std/localization/locales/locale/locale.members/combine.pass.cpp
@@ -7,11 +7,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <locale>
 
 // template <class Facet> locale combine(const locale& other) const;
 
 #include <locale>
+#include <stdexcept>
 #include <cassert>
 
 #include "count_new.hpp"
diff --git a/test/std/localization/locales/locale/locale.members/name.pass.cpp b/test/std/localization/locales/locale/locale.members/name.pass.cpp
index 9d9b142..13ae272 100644
--- a/test/std/localization/locales/locale/locale.members/name.pass.cpp
+++ b/test/std/localization/locales/locale/locale.members/name.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // basic_string<char> name() const;
diff --git a/test/std/localization/locales/locale/locale.operators/eq.pass.cpp b/test/std/localization/locales/locale/locale.operators/eq.pass.cpp
index ec118e0..c809f49 100644
--- a/test/std/localization/locales/locale/locale.operators/eq.pass.cpp
+++ b/test/std/localization/locales/locale/locale.operators/eq.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // basic_string<char> name() const;
diff --git a/test/std/localization/locales/locale/locale.statics/global.pass.cpp b/test/std/localization/locales/locale/locale.statics/global.pass.cpp
index 59a6bc6..d4b1155 100644
--- a/test/std/localization/locales/locale/locale.statics/global.pass.cpp
+++ b/test/std/localization/locales/locale/locale.statics/global.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <locale>
 
 // static const locale& classic();
diff --git a/test/std/extensions/nothing_to_do.pass.cpp b/test/std/localization/locales/locale/locale.types/locale.facet/tested_elsewhere.pass.cpp
similarity index 100%
copy from test/std/extensions/nothing_to_do.pass.cpp
copy to test/std/localization/locales/locale/locale.types/locale.facet/tested_elsewhere.pass.cpp
diff --git a/test/std/extensions/nothing_to_do.pass.cpp b/test/std/localization/locales/locale/locale.types/locale.id/tested_elsewhere.pass.cpp
similarity index 100%
copy from test/std/extensions/nothing_to_do.pass.cpp
copy to test/std/localization/locales/locale/locale.types/locale.id/tested_elsewhere.pass.cpp
diff --git a/test/std/numerics/c.math/cmath.pass.cpp b/test/std/numerics/c.math/cmath.pass.cpp
index 0b0d862..5b78925 100644
--- a/test/std/numerics/c.math/cmath.pass.cpp
+++ b/test/std/numerics/c.math/cmath.pass.cpp
@@ -79,6 +79,7 @@
 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(); }
@@ -1010,6 +1011,28 @@
     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()
diff --git a/test/std/numerics/cfenv/cfenv.syn/cfenv.pass.cpp b/test/std/numerics/cfenv/cfenv.syn/cfenv.pass.cpp
index fcf075a..f2bf643 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 @@
 {
     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/rand/rand.device/ctor.pass.cpp b/test/std/numerics/rand/rand.device/ctor.pass.cpp
index 97f46b2..9709484 100644
--- a/test/std/numerics/rand/rand.device/ctor.pass.cpp
+++ b/test/std/numerics/rand/rand.device/ctor.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <random>
 
 // class random_device;
@@ -19,8 +20,13 @@
 // throw.
 
 #include <random>
+#include <system_error>
 #include <cassert>
+
+#if !defined(_WIN32)
 #include <unistd.h>
+#endif
+
 
 bool is_valid_random_device(const std::string &token) {
 #if defined(_LIBCPP_USING_DEV_RANDOM)
@@ -39,13 +45,37 @@
   try {
     std::random_device r(token);
     assert(false);
-  } catch (const std::system_error &e) {
+  } catch (const std::system_error&) {
   }
 }
 
-int main() {
-  { std::random_device r; }
 
+int main() {
+  {
+    std::random_device r;
+  }
+  {
+    std::string token = "wrong file";
+    check_random_device_invalid(token);
+  }
+  {
+    std::string token = "/dev/urandom";
+    if (is_valid_random_device(token))
+      check_random_device_valid(token);
+    else
+      check_random_device_invalid(token);
+  }
+  {
+    std::string token = "/dev/random";
+    if (is_valid_random_device(token))
+      check_random_device_valid(token);
+    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);
@@ -56,28 +86,5 @@
     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);
-  }
-
-  {
-    std::string token = "/dev/urandom";
-    if (is_valid_random_device(token))
-      check_random_device_valid(token);
-    else
-      check_random_device_invalid(token);
-  }
-
-  {
-    std::string token = "/dev/random";
-    if (is_valid_random_device(token))
-      check_random_device_valid(token);
-    else
-      check_random_device_invalid(token);
-  }
+#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 72aff07..e319e0f 100644
--- a/test/std/numerics/rand/rand.device/eval.pass.cpp
+++ b/test/std/numerics/rand/rand.device/eval.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <random>
 
 // class random_device;
@@ -29,7 +30,7 @@
         r();
         assert(false);
     }
-    catch (const std::system_error& e)
+    catch (const std::system_error&)
     {
     }
 }
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 5d14b36..0472afa 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>
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 6850115..12b2f6b 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>
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 af75fce..6b0af42 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
@@ -59,10 +61,10 @@
         }
         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)
@@ -109,10 +111,10 @@
         }
         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)
@@ -159,10 +161,10 @@
         }
         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)
@@ -209,10 +211,10 @@
         }
         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)
@@ -259,10 +261,10 @@
         }
         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)
@@ -309,10 +311,10 @@
         }
         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.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 fe70422..8054a69 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 @@
         }
         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/re/re.alg/re.alg.match/awk.pass.cpp b/test/std/re/re.alg/re.alg.match/awk.pass.cpp
index e4b2f3e..a32b2ca 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 82f8e3b..f1a5554 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
@@ -18,12 +18,13 @@
 //                    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 @@
         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 2ddc07a..901bf90 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 785a61c..a4568f6 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 dd2e603..53cff85 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 9ca31d1..5e08d0a 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 2dc0966..efd33cb 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 949739b..1dc4ee4 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
@@ -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.match/parse_curly_brackets.pass.cpp b/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp
index 0b4c694..59b2832 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 9fd84fd..13cc8f2 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 63a4ed5..679644f 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 d116786..c8b8c64 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 fba1bc1..251eae8 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 7190e41..53720d6 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 b017800..a00ac75 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 7fc1b3f..05d1f59 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 7da5860..f33b844 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 9ab6a21..c6b2b41 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
@@ -18,12 +18,13 @@
 //                     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 @@
         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 bdfcd9c..f5157f5 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 fb9fc26..d6a3da6 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 1dffed4..0bf8386 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 81eef2f..88af3b9 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 113243e..197af8d 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <regex>
 
 // template <class BidirectionalIterator, class Allocator, class charT, class traits>
@@ -19,8 +20,34 @@
 #include <regex>
 #include <cassert>
 
+#include "test_macros.h"
 #include "test_iterators.h"
 
+extern "C" void LLVMFuzzerTestOneInput(const char *data)
+{
+    size_t size = strlen(data);
+    if (size > 0)
+    {
+        try
+        {
+            std::regex::flag_type flag = std::regex_constants::grep;
+            std::string s((const char *)data, size);
+            std::regex re(s, flag);
+            std::regex_match(s, re);
+        } 
+        catch (std::regex_error &) {} 
+    } 
+}
+
+
+void fuzz_tests()  // patterns that the fuzzer has found
+{
+// Raw string literals are a C++11 feature.
+#if TEST_STD_VER >= 11
+    LLVMFuzzerTestOneInput(R"XX(Õ)_%()()((\8'_%()_%()_%()_%(()_%()_%()_%(.t;)()¥f()_%()(.)_%;)()!¥f(((()()XX");
+#endif
+}
+
 int main()
 {
     {
@@ -55,4 +82,5 @@
         assert(m.position(0) == 0);
         assert(m.str(0) == "");
     }
+    fuzz_tests();
 }
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 9f5f954..207612b 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,6 +20,7 @@
 
 #include <regex>
 #include <cassert>
+#include "test_macros.h"
 
 int main() 
 {
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 ef9cec5..600425d 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 02fecbd..f175271 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 150855b..3609d41 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 b48703c..c7b2a80 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 41ac0ce..81a103c 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
@@ -17,6 +17,7 @@
 
 #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 594c9fb..a6cb97c 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
@@ -17,6 +17,7 @@
 
 #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 1c4f824..ad6111c 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 208de0e..0089362 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,12 +17,13 @@
 //                      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()
 {
@@ -33,4 +34,3 @@
             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 c9fc7a3..c1cabff 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 9d4766d..cb44fb3 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 e4933fe..800f564 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 3ec0d6c..f3b57f6 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 db1d3eb..5b79957 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 6753b0a..8f90b23 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 @@
                                      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 a51b827..6d8c2f3 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 382815e..e71f3a6 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 e581836..9d53873 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 @@
                                       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 b40d7eb..6cffc0d 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 d0a100a..f4601f3 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 @@
                                      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 d811136..37fe2d9 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 94d8f96..d5d5f4c 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 @@
                                      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 b04f580..473a706 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 d6399f1..49d1b1b 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 b096e3c..73ec62c 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 727ab7a..7d55bc1 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 89287bd..b7777fb 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 96cadf1..39c3a22 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 8bf9826..988d555 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <regex>
 
 // template <class charT, class traits = regex_traits<charT>> class basic_regex;
@@ -15,6 +16,7 @@
 
 #include <regex>
 #include <cassert>
+#include "test_macros.h"
 
 int main()
 {
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 529a64a..7cd4845 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 dd39dee..33b9cad 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 679cd9d..7ec4f77 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 46f984d..247d277 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 2a616ff..3f212f7 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 a9d8ada..022170f 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 4c42f82..d2af1f9 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 7f09e53..65cc4a3 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 85297b9..e699de8 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 4b7e5e6..671fac5 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,6 +16,7 @@
 
 #include <regex>
 #include <cassert>
+#include "test_macros.h"
 
 int main() 
 {
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 ddf2607..39e019b 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <regex>
 
 // template <class charT, class traits = regex_traits<charT>> class basic_regex;
@@ -16,6 +17,7 @@
 
 #include <regex>
 #include <cassert>
+#include "test_macros.h"
 
 static bool error_escape_thrown(const char *pat) 
 {
@@ -32,6 +34,7 @@
 {
     assert(error_escape_thrown("[\\a]"));
     assert(error_escape_thrown("\\a"));
+    assert(error_escape_thrown("\\"));
 
     assert(error_escape_thrown("[\\e]"));
     assert(error_escape_thrown("\\e"));
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 bc70ec1..dc0b35e 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <regex>
 
 // template <class charT, class traits = regex_traits<charT>> class basic_regex;
@@ -16,6 +17,7 @@
 
 #include <regex>
 #include <cassert>
+#include "test_macros.h"
 
 static bool error_badrepeat_thrown(const char *pat) 
 {
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 c2788f0..a266289 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 d959c1e..f1d7bf7 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 70d28df..c1554d6 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 a38e162..4a93d17 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 c4c440e..347989c 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 b99b58b..05fba02 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 138e20e..d37b815 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 d623a15..a0ceb70 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 b58b8e0..a8f2e9b 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 768de56..5f87af1 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 be0b26d..8590048 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
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <regex>
 
 // template <class charT, class traits = regex_traits<charT>> class basic_regex;
@@ -17,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 9d3c481..7b23172 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 cda8ef3..a04c64d 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 02011ac..5c0a592 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 80c06f2..a5ed051 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 a983c8a..67ec606 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 79d4b9a..8118d3c 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 9102085..7bf689c 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 2698e2d..b7df2c7 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 58cdabc..0c8572a 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 2ebfeab..512bd9e 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 b842ea8..a78bb67 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 0436795..c4fe96d 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 a24c669..73347d0 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 e10fbfd..2fa8553 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 9701c60..55b5ade 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()
@@ -38,6 +39,31 @@
     {
         std::match_results<const char*> m;
         const char s[] = "abcdefghijk";
+        assert(std::regex_search(s, m, std::regex("cd((e)fg)hi",
+                                                  std::regex_constants::nosubs)));
+
+        char out[100] = {0};
+        const char fmt[] = "prefix: $`, match: $&, suffix: $', m[1]: $1, m[2]: $2";
+        char* r = m.format(output_iterator<char*>(out),
+                    fmt, fmt + std::char_traits<char>::length(fmt)).base();
+        assert(r == out + 54);
+        assert(std::string(out) == "prefix: ab, match: cdefghi, suffix: jk, m[1]: , m[2]: ");
+    }
+    {
+        std::match_results<const char*> m;
+        const char s[] = "abcdefghijk";
+        assert(std::regex_search(s, m, std::regex("cdefghi")));
+
+        char out[100] = {0};
+        const char fmt[] = "prefix: $`, match: $&, suffix: $', m[1]: $1, m[2]: $2";
+        char* r = m.format(output_iterator<char*>(out),
+                    fmt, fmt + std::char_traits<char>::length(fmt)).base();
+        assert(r == out + 54);
+        assert(std::string(out) == "prefix: ab, match: cdefghi, suffix: jk, m[1]: , m[2]: ");
+    }
+    {
+        std::match_results<const char*> m;
+        const char s[] = "abcdefghijk";
         assert(std::regex_search(s, m, std::regex("cd((e)fg)hi")));
 
         char out[100] = {0};
@@ -61,6 +87,33 @@
         assert(r == out + 34);
         assert(std::string(out) == "match: cdefghi, m[1]: efg, m[2]: e");
     }
+    {
+        std::match_results<const char*> m;
+        const char s[] = "abcdefghijk";
+        assert(std::regex_search(s, m, std::regex("cd((e)fg)hi",
+                                                  std::regex_constants::nosubs)));
+
+        char out[100] = {0};
+        const char fmt[] = "match: &, m[1]: \\1, m[2]: \\2";
+        char* r = m.format(output_iterator<char*>(out),
+                    fmt, fmt + std::char_traits<char>::length(fmt),
+                    std::regex_constants::format_sed).base();
+        assert(r == out + 30);
+        assert(std::string(out) == "match: cdefghi, m[1]: , m[2]: ");
+    }
+    {
+        std::match_results<const char*> m;
+        const char s[] = "abcdefghijk";
+        assert(std::regex_search(s, m, std::regex("cdefghi")));
+
+        char out[100] = {0};
+        const char fmt[] = "match: &, m[1]: \\1, m[2]: \\2";
+        char* r = m.format(output_iterator<char*>(out),
+                    fmt, fmt + std::char_traits<char>::length(fmt),
+                    std::regex_constants::format_sed).base();
+        assert(r == out + 30);
+        assert(std::string(out) == "match: cdefghi, m[1]: , m[2]: ");
+    }
 
     {
         std::match_results<const wchar_t*> m;
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 b18b7fb..ab7a525 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 27f2388..e4c2e3d 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 1d44c32..2c8aa9b 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 7902b8e..0a32f2e 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 6634d92..f03f5f7 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 0b31409..1ba29b9 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 8f586c3..1348016 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 09b85c0..cd1d72a 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 3f5e34d..81e6c81 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 4d55383..0b76875 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 c14d5bc..be05afd 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 0874742..4b74f65 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 48c05ca..097a391 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 451466a..1805f7e 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 4874c0d..2009548 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 dd856a5..4c2877c 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 ca5fd7d..9a82189 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 36376aa..6770fa4 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
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 050bb06..9f8c986 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 47c7914..e5a00ca 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 1364b78..bf467bc 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 7b6ac13..ed5839d 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 36ee9b6..85dca0c 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 e0de67b..2a87d8b 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 a208442..32fcb82 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 8732353..e2fc061 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 7acd961..1463164 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 185fd62..aa85680 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 b378339..181b7a3 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 3ca8ed5..0eb1256 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 99469ec..20c0d0d 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 f16911f..01a7f3c 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 7e8c872..f757d3f 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 635eac0..23be43b 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 092c7d1..1483808 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 0052716..436e6d7 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 dc71991..5ceb241 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 2360a15..23b92bb 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 c9a97e0..b1e2358 100644
--- a/test/std/re/re.traits/default.pass.cpp
+++ b/test/std/re/re.traits/default.pass.cpp
@@ -8,6 +8,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <regex>
 
 // template <class charT> struct regex_traits;
@@ -17,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 27ab6cd..929659d 100644
--- a/test/std/re/re.traits/getloc.pass.cpp
+++ b/test/std/re/re.traits/getloc.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <regex>
 
 // template <class charT> struct regex_traits;
@@ -16,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 11eca41..04b4f5f 100644
--- a/test/std/re/re.traits/imbue.pass.cpp
+++ b/test/std/re/re.traits/imbue.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// REQUIRES: locale.en_US.UTF-8
+
 // <regex>
 
 // template <class charT> struct regex_traits;
@@ -17,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 ad69f05..3d1e747 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 473c233..b80f9b5 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 0b1b18e..4f7cf61 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 @@
 
 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 a7cd5f0..3aeed7b 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 85235e0..57e6b75 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 438cd75..03b4f39 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 c352338..7eaf30e 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 f9fa38d..bf79629 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 50586a1..611ef04 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 349a29c..dfed66c 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/containers/sequences/vector/const_value_type.pass.cpp b/test/std/strings/basic.string/allocator_mismatch.fail.cpp
similarity index 65%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/strings/basic.string/allocator_mismatch.fail.cpp
index e16e439..644137e 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/strings/basic.string/allocator_mismatch.fail.cpp
@@ -7,16 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <string>
+//   The container's value type must be the same as the allocator's value type
 
-// vector<const int> v;  // an extension
-
-#include <vector>
-#include <type_traits>
+#include <string>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    std::basic_string<char, std::char_traits<char>, std::allocator<int> > s;
 }
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 8fada8f..87998e1 100644
--- a/test/std/strings/basic.string/string.access/at.pass.cpp
+++ b/test/std/strings/basic.string/string.access/at.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // const_reference at(size_type pos) const;
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 bae7621..c05346a 100644
--- a/test/std/strings/basic.string/string.capacity/capacity.pass.cpp
+++ b/test/std/strings/basic.string/string.capacity/capacity.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // size_type capacity() const;
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 e4ff556..d857be2 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // size_type max_size() const;
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 bbadb9c..9c8f679 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // size_type max_size() const;
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 a155825..b2c254d 100644
--- a/test/std/strings/basic.string/string.capacity/reserve.pass.cpp
+++ b/test/std/strings/basic.string/string.capacity/reserve.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // void reserve(size_type res_arg=0);
@@ -15,6 +16,7 @@
 #include <stdexcept>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -24,7 +26,7 @@
     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());
@@ -82,7 +84,7 @@
     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 14fe209..5589415 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // void resize(size_type n);
@@ -15,6 +16,7 @@
 #include <stdexcept>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -24,7 +26,7 @@
     try
     {
         s.resize(n);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(n <= s.max_size());
         assert(s == expected);
     }
@@ -55,7 +57,7 @@
          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 f293df9..79f972b 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // void resize(size_type n, charT c);
@@ -15,6 +16,7 @@
 #include <stdexcept>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -24,7 +26,7 @@
     try
     {
         s.resize(n, c);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(n <= s.max_size());
         assert(s == expected);
     }
@@ -55,7 +57,7 @@
          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 aacbffd..656ea1d 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 @@
     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 @@
     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.cons/alloc.pass.cpp b/test/std/strings/basic.string/string.cons/alloc.pass.cpp
index 1c4f204..a803d33 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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 1c582bc..f6bacb7 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 @@
 {
     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 @@
     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 9c9fc32..cc4deb9 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 @@
 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 @@
     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 cf80210..b3447b9 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 @@
 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 @@
     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 ccb6c59..b1e9108 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 @@
 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 @@
            "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 af11710..87698ec 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 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
     {
         typedef std::string C;
         static_assert(std::is_nothrow_default_constructible<C>::value, "");
@@ -42,5 +43,4 @@
         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 b3cc127..c4ac1f1 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 @@
     ~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 @@
         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 d6ff850..3007b9e 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 @@
         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 @@
         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 7530768..20279c8 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 664cb80..cb0792a 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 @@
     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 @@
     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 @@
     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 b94f189..9ed2444 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 @@
 {
     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 @@
     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 @@
     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 a232a46..d486692 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 @@
 {
     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 @@
     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 @@
     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 32c9514..8dfc68b 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,18 +7,24 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: c++98, c++03
+
 // <string>
 
 // basic_string& operator=(basic_string&& c)
 //     noexcept(
-//          allocator_type::propagate_on_container_move_assignment::value &&
-//          is_nothrow_move_assignable<allocator_type>::value);
-
-// This tests a conforming extension
+//         allocator_traits<allocator_type>::propagate_on_container_move_assignment::value ||
+//         allocator_traits<allocator_type>::is_always_equal::value); // C++17
+//
+//	before C++17, we use the conforming extension
+//     noexcept(
+//         allocator_type::propagate_on_container_move_assignment::value &&
+//         is_nothrow_move_assignable<allocator_type>::value);
 
 #include <string>
 #include <cassert>
 
+#include "test_macros.h"
 #include "test_allocator.h"
 
 template <class T>
@@ -28,9 +34,34 @@
     some_alloc(const some_alloc&);
 };
 
+template <class T>
+struct some_alloc2
+{
+    typedef T value_type;
+    
+    some_alloc2() {}
+    some_alloc2(const some_alloc2&);
+    void deallocate(void*, unsigned) {}
+
+    typedef std::false_type propagate_on_container_move_assignment;
+    typedef std::true_type is_always_equal;
+};
+
+template <class T>
+struct some_alloc3
+{
+    typedef T value_type;
+    
+    some_alloc3() {}
+    some_alloc3(const some_alloc3&);
+    void deallocate(void*, unsigned) {}
+
+    typedef std::false_type propagate_on_container_move_assignment;
+    typedef std::false_type is_always_equal;
+};
+
 int main()
 {
-#if __has_feature(cxx_noexcept)
     {
         typedef std::string C;
         static_assert(std::is_nothrow_move_assignable<C>::value, "");
@@ -41,6 +72,22 @@
     }
     {
         typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C;
+#if TEST_STD_VER > 14
+    //  if the allocators are always equal, then the move assignment can be noexcept
+        static_assert( std::is_nothrow_move_assignable<C>::value, "");
+#else
+        static_assert(!std::is_nothrow_move_assignable<C>::value, "");
+#endif
+    }
+#if TEST_STD_VER > 14
+    {
+    //	POCMA is false, always equal
+        typedef std::basic_string<char, std::char_traits<char>, some_alloc2<char>> C;
+        static_assert( std::is_nothrow_move_assignable<C>::value, "");
+    }
+    {
+    //	POCMA is false, not always equal
+        typedef std::basic_string<char, std::char_traits<char>, some_alloc3<char>> C;
         static_assert(!std::is_nothrow_move_assignable<C>::value, "");
     }
 #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 5bc1c8a..006b5b9 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 @@
 {
     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 @@
            "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 @@
            "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 b287a94..9a7c65c 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 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
     {
         typedef std::string C;
         static_assert(std::is_nothrow_move_constructible<C>::value, "");
@@ -46,5 +47,4 @@
         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 f6e9e00..b678247 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 @@
     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 @@
     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 @@
     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 c691613..506ab93 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 @@
 {
     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 @@
            "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 f1f107a..bcab9eb 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 @@
     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 @@
     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 @@
     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 4dfe906..60d41b1 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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 2a9bf2a..a10239b 100644
--- a/test/std/strings/basic.string/string.cons/substr.pass.cpp
+++ b/test/std/strings/basic.string/string.cons/substr.pass.cpp
@@ -7,17 +7,25 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <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"
 
@@ -30,7 +38,7 @@
     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);
@@ -53,7 +61,7 @@
     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);
@@ -76,7 +84,7 @@
     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);
@@ -90,6 +98,20 @@
     }
 }
 
+#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()
 {
     {
@@ -130,7 +152,7 @@
     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;
@@ -169,5 +191,7 @@
     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.modifiers/string_append/initializer_list.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp
index fb28e49..d30ca44 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 __cplusplus >= 201103L
     {
         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 3bf2afa..55fc63d 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
@@ -15,7 +15,7 @@
 #include <string>
 #include <cassert>
 
-#include "../../input_iterator.h"
+#include "test_iterators.h"
 #include "min_allocator.h"
 
 template <class S, class It>
@@ -23,10 +23,26 @@
 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)
+{
+	S aCopy = s;
+    try {
+    	s.append(first, last);
+    	assert(false);
+    	}
+    catch (...) {}
+    LIBCPP_ASSERT(s.__invariants());
+    assert(s == aCopy);
+}
+#endif
+
 int main()
 {
     {
@@ -87,7 +103,7 @@
     test(S("12345678901234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+52),
          S("12345678901234567890""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";
@@ -147,4 +163,19 @@
          S("12345678901234567890""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
     }
 #endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
+	{ // test iterator operations that throw
+    typedef std::string S;
+    typedef ThrowingIterator<char> TIter;
+    typedef input_iterator<TIter> IIter;
+    const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
+    test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
+    test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+
+    test_exceptions(S(), TIter(s, s+10, 4, TIter::TAIncrement), TIter());
+    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 5ae15f0..7c45068 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 @@
 test(S s, const typename S::value_type* str, S expected)
 {
     s.append(str);
-    assert(s.__invariants());
+    LIBCPP_ASSERT(s.__invariants());
     assert(s == expected);
 }
 
@@ -43,7 +44,7 @@
     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_append/pointer_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp
index 5a9e8e2..6c594eb 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 @@
 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);
 }
 
@@ -48,7 +49,7 @@
     test(S("12345678901234567890"), "12345678901234567890", 20,
          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(), "", 0, S());
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 b0a2eb5..f2fb878 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 @@
 test(S s, typename S::value_type c, S expected)
 {
     s.push_back(c);
-    assert(s.__invariants());
+    LIBCPP_ASSERT(s.__invariants());
     assert(s == expected);
 }
 
@@ -33,7 +34,7 @@
     test(S("12345"), 'a', S("12345a"));
     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(1, 'a'));
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 00e6ae3..1610ab5 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 @@
 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);
 }
 
@@ -43,7 +44,7 @@
     test(S("12345678901234567890"), 1, 'a', S("12345678901234567890a"));
     test(S("12345678901234567890"), 10, 'a', S("12345678901234567890aaaaaaaaaa"));
     }
-#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.modifiers/string_append/string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp
index 31f174b..b58ed63 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 @@
 test(S s, S str, S expected)
 {
     s.append(str);
-    assert(s.__invariants());
+    LIBCPP_ASSERT(s.__invariants());
     assert(s == expected);
 }
 
@@ -51,7 +52,7 @@
     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_append/string_size_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp
index e8f54f4..9e8158c 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // basic_string<charT,traits,Allocator>&
@@ -17,6 +18,7 @@
 #include <stdexcept>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -26,7 +28,7 @@
     try
     {
         s.append(str, pos, n);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(pos <= str.size());
         assert(s == expected);
     }
@@ -43,7 +45,7 @@
     try
     {
         s.append(str, pos);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(pos <= str.size());
         assert(s == expected);
     }
@@ -79,7 +81,7 @@
     test(S("12345678901234567890"), S("12345678901234567890"), 5, 10,
          S("123456789012345678906789012345"));
     }
-#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, 0, S());
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 2dae107..a2114cf 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 __cplusplus >= 201103L
     {
         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 83b5dd1..e6a5751 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,7 +15,8 @@
 #include <string>
 #include <cassert>
 
-#include "../../input_iterator.h"
+#include "test_macros.h"
+#include "test_iterators.h"
 #include "min_allocator.h"
 
 template <class S, class It>
@@ -23,10 +24,26 @@
 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)
+{
+	S aCopy = s;
+    try {
+   	    s.assign(first, last);
+    	assert(false);
+    }
+    catch (...) {}
+    LIBCPP_ASSERT(s.__invariants());
+    assert(s == aCopy);
+}
+#endif
+
 int main()
 {
     {
@@ -87,7 +104,7 @@
     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";
@@ -147,4 +164,19 @@
          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
     }
 #endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
+	{ // test iterator operations that throw
+    typedef std::string S;
+    typedef ThrowingIterator<char> TIter;
+    typedef input_iterator<TIter> IIter;
+    const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
+    test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
+    test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+
+    test_exceptions(S(), TIter(s, s+10, 4, TIter::TAIncrement), TIter());
+    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 adf24ac..386dee6 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 @@
 test(S s, const typename S::value_type* str, S expected)
 {
     s.assign(str);
-    assert(s.__invariants());
+    LIBCPP_ASSERT(s.__invariants());
     assert(s == expected);
 }
 
@@ -43,7 +44,7 @@
     test(S("12345678901234567890"), "12345678901234567890",
          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.modifiers/string_assign/pointer_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp
index 476fe96..0eeb926 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 @@
 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);
 }
 
@@ -48,7 +49,7 @@
     test(S("12345678901234567890"), "12345678901234567890", 20,
          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(), "", 0, S());
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 4273860..6b89df9 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 @@
 test(S s, S str, S expected)
 {
     s.assign(std::move(str));
-    assert(s.__invariants());
+    LIBCPP_ASSERT(s.__invariants());
     assert(s == expected);
 }
 
@@ -52,7 +53,7 @@
     test(S("12345678901234567890"), S("12345678901234567890"),
          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(), S());
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 a8f7470..a899e0d 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 @@
 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);
 }
 
@@ -43,7 +44,7 @@
     test(S("12345678901234567890"), 1, 'a', S(1, 'a'));
     test(S("12345678901234567890"), 10, 'a', S(10, 'a'));
     }
-#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.modifiers/string_assign/string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp
index d7ddb77..788512b 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,8 +62,23 @@
     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>());
     }
-#if __cplusplus >= 201103L
+
+    { //  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;
     test(S(), S(), S());
@@ -74,6 +101,17 @@
     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 TEST_STD_VER > 14
+    {
+    typedef std::string S;
+    static_assert(noexcept(S().assign(S())), "");  // LWG#2063
     }
 #endif
 }
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 5f5983e..d9d3cb4 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // basic_string<charT,traits,Allocator>&
@@ -17,6 +18,7 @@
 #include <stdexcept>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -26,7 +28,7 @@
     try
     {
         s.assign(str, pos, n);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(pos <= str.size());
         assert(s == expected);
     }
@@ -43,7 +45,7 @@
     try
     {
         s.assign(str, pos);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(pos <= str.size());
         assert(s == expected);
     }
@@ -79,7 +81,7 @@
     test(S("12345678901234567890"), S("12345678901234567890"), 5, 10,
          S("6789012345"));
     }
-#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, 0, S());
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 3380135..b668776 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // size_type copy(charT* s, size_type n, size_type pos = 0) const;
@@ -16,6 +17,7 @@
 #include <algorithm>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -103,7 +105,7 @@
     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 c44db71..8de5fc7 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 @@
 {
     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 @@
     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 dbe6d7b..e4fe2cd 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 @@
     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 @@
     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 790ce40..64f8e50 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 @@
 test(S s, S expected)
 {
     s.pop_back();
-    assert(s.__invariants());
+    LIBCPP_ASSERT(s.__invariants());
     assert(s == expected);
 }
 
@@ -37,7 +34,7 @@
     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 @@
     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 bc9ec1c..5db97ec 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // basic_string<charT,traits,Allocator>&
@@ -16,6 +17,7 @@
 #include <stdexcept>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -27,7 +29,7 @@
     try
     {
         s.erase(pos, n);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(pos <= old_size);
         assert(s == expected);
     }
@@ -47,7 +49,7 @@
     try
     {
         s.erase(pos);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(pos <= old_size);
         assert(s == expected);
     }
@@ -63,7 +65,7 @@
 test(S s, S expected)
 {
     s.erase();
-    assert(s.__invariants());
+    LIBCPP_ASSERT(s.__invariants());
     assert(s == expected);
 }
 
@@ -172,7 +174,7 @@
     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 b9e5fa8..6bd9b7e 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 @@
     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);
@@ -56,7 +53,7 @@
     test(s, s.begin()+5, 'B', S("a567AB1432dcb"));
     test(s, s.begin()+6, 'C', S("a567ABC1432dcb"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     S s;
@@ -76,13 +73,4 @@
     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_initializer_list.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp
index e091662..2adf846 100644
--- a/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp
+++ b/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp
@@ -29,7 +29,7 @@
         assert(i - s.begin() == 3);
         assert(s == "123abc456");
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
         typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
         S s("123456");
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 38353dd..bbae394 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
@@ -19,7 +19,7 @@
 #include <string>
 #include <cassert>
 
-#include "../../input_iterator.h"
+#include "test_iterators.h"
 #include "min_allocator.h"
 
 template <class S, class It>
@@ -28,11 +28,28 @@
 {
     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)
+{
+    typename S::const_iterator p = s.cbegin() + pos;
+	S aCopy = s;
+    try {
+        s.insert(p, first, last);
+        assert(false);
+        }
+    catch (...) {}
+    LIBCPP_ASSERT(s.__invariants());
+    assert(s == aCopy);
+}
+#endif
+
 int main()
 {
     {
@@ -80,7 +97,7 @@
     test(S("12345678901234567890"), 20, input_iterator<const char*>(s), input_iterator<const char*>(s+52),
          S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
     }
-#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";
@@ -127,6 +144,21 @@
          S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
     }
 #endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
+	{ // test iterator operations that throw
+    typedef std::string S;
+    typedef ThrowingIterator<char> TIter;
+    typedef input_iterator<TIter> IIter;
+    const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    test_exceptions(S(), 0, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
+    test_exceptions(S(), 0, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
+    test_exceptions(S(), 0, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+
+    test_exceptions(S(), 0, TIter(s, s+10, 4, TIter::TAIncrement), TIter());
+    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 739c894..c9cd0c2 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 @@
 {
     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);
 }
@@ -101,7 +98,7 @@
     test(S("abcdefghijklmnopqrst"), 20, 10, '1', S("abcdefghijklmnopqrst1111111111"));
     test(S("abcdefghijklmnopqrst"), 20, 20, '1', S("abcdefghijklmnopqrst11111111111111111111"));
     }
-#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, '1', S(""));
@@ -170,12 +167,4 @@
     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 734dd8d..faab5bd 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // basic_string<charT,traits,Allocator>&
@@ -16,6 +17,7 @@
 #include <stdexcept>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -27,7 +29,7 @@
     try
     {
         s.insert(pos, str);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(pos <= old_size);
         assert(s == expected);
     }
@@ -123,7 +125,7 @@
     test(S("abcdefghijklmnopqrst"), 21, "1234567890", S("can't happen"));
     test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", S("can't 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.modifiers/string_insert/size_pointer_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp
index 29b00ec..30d3df9 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // basic_string<charT,traits,Allocator>&
@@ -16,6 +17,7 @@
 #include <stdexcept>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -28,7 +30,7 @@
     try
     {
         s.insert(pos, str, n);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(pos <= old_size);
         assert(s == expected);
     }
@@ -364,7 +366,7 @@
     test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 19, S("can't happen"));
     test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 20, S("can't 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, "", 0, S(""));
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 fd85696..04ea1d3 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // basic_string<charT,traits,Allocator>&
@@ -16,6 +17,7 @@
 #include <stdexcept>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -28,7 +30,7 @@
     try
     {
         s.insert(pos, n, str);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(pos <= old_size);
         assert(s == expected);
     }
@@ -124,7 +126,7 @@
     test(S("abcdefghijklmnopqrst"), 21, 10, '1', S("can't happen"));
     test(S("abcdefghijklmnopqrst"), 21, 20, '1', S("can't 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, 0, '1', S(""));
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 8c18941..1945871 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // basic_string<charT,traits,Allocator>&
@@ -16,6 +17,7 @@
 #include <stdexcept>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -27,7 +29,7 @@
     try
     {
         s.insert(pos, str);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(pos <= old_size);
         assert(s == expected);
     }
@@ -123,7 +125,7 @@
     test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), S("can't happen"));
     test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), S("can't 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(""), S(""));
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 51c9e72..32485db 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // basic_string<charT,traits,Allocator>&
@@ -18,6 +19,7 @@
 #include <stdexcept>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -30,7 +32,7 @@
     try
     {
         s.insert(pos1, str, pos2, n);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(pos1 <= old_size && pos2 <= str.size());
         assert(s == expected);
     }
@@ -50,7 +52,7 @@
     try
     {
         s.insert(pos1, str, pos2);
-        assert(s.__invariants());
+        LIBCPP_ASSERT(s.__invariants());
         assert(pos1 <= old_size && pos2 <= str.size());
         assert(s == expected);
     }
@@ -1745,7 +1747,7 @@
     test29<S>();
     test30<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.modifiers/string_op_plus_equal/char.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp
index 7384ae7..f39ed03 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 @@
 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 @@
     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 c291028..5b32af9 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 77b20d1..c19fd29 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 @@
 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 @@
     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 3364979..1064855 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 @@
 test(S s, S str, S expected)
 {
     s += str;
-    assert(s.__invariants());
+    LIBCPP_ASSERT(s.__invariants());
     assert(s == expected);
 }
 
@@ -51,7 +52,7 @@
     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_initializer_list.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp
index 20455b2..b60a58c 100644
--- a/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp
+++ b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp
@@ -24,7 +24,7 @@
         s.replace(s.cbegin() + 3, s.cbegin() + 6, {'a', 'b', 'c'});
         assert(s == "123abc456");
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
         typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
         S s("123def456");
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 9295c5b..cc37e79 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
@@ -18,6 +18,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "test_iterators.h"
 
 template <class S, class It>
 void
@@ -28,12 +29,30 @@
     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)
+{
+    typename S::const_iterator first = s.begin() + pos1;
+    typename S::const_iterator last = s.begin() + pos1 + n1;
+	S aCopy = s;
+	try {
+	    s.replace(first, last, f, l);
+	    assert(false);
+	    }
+	catch (...) {}
+    LIBCPP_ASSERT(s.__invariants());
+    assert(s == aCopy);
+}
+#endif
+
 const char* str = "12345678901234567890";
 
 template <class S>
@@ -959,7 +978,7 @@
     test7<S>();
     test8<S>();
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0<S>();
@@ -973,4 +992,19 @@
     test8<S>();
     }
 #endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
+	{ // test iterator operations that throw
+    typedef std::string S;
+    typedef ThrowingIterator<char> TIter;
+    typedef input_iterator<TIter> IIter;
+    const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
+    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
+    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+
+    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 4, TIter::TAIncrement), TIter());
+    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 cb4ce61..730fc1a 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 @@
     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);
@@ -274,7 +274,7 @@
     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.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 b1d6ab1..4a910e4 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 @@
     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);
@@ -959,7 +958,7 @@
     test7<S>();
     test8<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.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 b0e2234..4dbc8ab 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 @@
     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);
@@ -275,7 +274,7 @@
     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.modifiers/string_replace/iter_iter_string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp
index 0f95492..190e10d 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 @@
     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);
@@ -274,7 +273,7 @@
     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.modifiers/string_replace/size_size_pointer.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp
index 914081b..3beb074 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
@@ -7,18 +7,18 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // 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>
@@ -31,7 +31,7 @@
     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);
@@ -364,7 +364,7 @@
     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.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 d987042..d961e9e 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
@@ -7,18 +7,18 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // 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>
@@ -32,7 +32,7 @@
     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);
@@ -1307,7 +1307,7 @@
     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.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 33f57fd..d4696fb 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // basic_string<charT,traits,Allocator>&
@@ -17,6 +18,7 @@
 #include <algorithm>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -30,7 +32,7 @@
     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);
@@ -363,7 +365,7 @@
     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.modifiers/string_replace/size_size_string.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp
index c130780..1be45d8 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // basic_string<charT,traits,Allocator>&
@@ -17,6 +18,7 @@
 #include <algorithm>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -28,7 +30,7 @@
     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);
@@ -361,7 +363,7 @@
     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.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 ef0de89..3f4bf45 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // basic_string<charT,traits,Allocator>&
@@ -19,6 +20,7 @@
 #include <algorithm>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -32,7 +34,7 @@
     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);
@@ -57,7 +59,7 @@
     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);
@@ -5902,7 +5904,7 @@
     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.modifiers/string_swap/swap.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp
index 4973bda..fe2ee1f 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 @@
     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 @@
     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.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp
index cee5388..a2e2519 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 @@
     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 @@
     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 cfe0365..d30d85b 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,6 +24,7 @@
 #include <string>
 #include <cassert>
 
+#include "test_macros.h"
 #include "test_allocator.h"
 
 template <class T>
@@ -51,7 +54,6 @@
 
 int main()
 {
-#if __has_feature(cxx_noexcept)
     {
         typedef std::string C;
         C c1, c2;
@@ -80,6 +82,4 @@
         static_assert( noexcept(swap(c1, c2)), "");
     }
 #endif
-
-#endif
 }
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 917248f..9b66cb0 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 @@
         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_compare/size_size_pointer.pass.cpp b/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp
index 9ed58a3..2fef19a 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // int compare(size_type pos, size_type n1, const charT *s) const;
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 ee804d9..cc61a2e 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // int compare(size_type pos, size_type n1, const charT *s, size_type n2) const;
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 3deb617..6641748 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // int compare(size_type pos1, size_type n1, const basic_string& str) const;
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 122e6e9..f5c0676 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // int compare(size_type pos1, size_type n1, const basic_string& str,
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 a73f70c..145e8dd 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // basic_string substr(size_type pos = 0, size_type n = npos) const;
@@ -16,6 +17,7 @@
 #include <algorithm>
 #include <cassert>
 
+#include "test_macros.h"
 #include "min_allocator.h"
 
 template <class S>
@@ -25,7 +27,7 @@
     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);
@@ -100,7 +102,7 @@
     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/c.strings/cctype.pass.cpp b/test/std/strings/c.strings/cctype.pass.cpp
index 867338f..027fbcd 100644
--- a/test/std/strings/c.strings/cctype.pass.cpp
+++ b/test/std/strings/c.strings/cctype.pass.cpp
@@ -86,18 +86,18 @@
     static_assert((std::is_same<decltype(std::tolower(0)), int>::value), "");
     static_assert((std::is_same<decltype(std::toupper(0)), int>::value), "");
 
-    assert(isalnum('a'));
-    assert(isalpha('a'));
-    assert(isblank(' '));
-    assert(!iscntrl(' '));
-    assert(!isdigit('a'));
-    assert(isgraph('a'));
-    assert(islower('a'));
-    assert(isprint('a'));
-    assert(!ispunct('a'));
-    assert(!isspace('a'));
-    assert(!isupper('a'));
-    assert(isxdigit('a'));
-    assert(tolower('A') == 'a');
-    assert(toupper('a') == 'A');
+    assert(std::isalnum('a'));
+    assert(std::isalpha('a'));
+    assert(std::isblank(' '));
+    assert(!std::iscntrl(' '));
+    assert(!std::isdigit('a'));
+    assert(std::isgraph('a'));
+    assert(std::islower('a'));
+    assert(std::isprint('a'));
+    assert(!std::ispunct('a'));
+    assert(!std::isspace('a'));
+    assert(!std::isupper('a'));
+    assert(std::isxdigit('a'));
+    assert(std::tolower('A') == 'a');
+    assert(std::toupper('a') == 'A');
 }
diff --git a/test/std/strings/c.strings/cstring.pass.cpp b/test/std/strings/c.strings/cstring.pass.cpp
index 20f4050..63f86d3 100644
--- a/test/std/strings/c.strings/cstring.pass.cpp
+++ b/test/std/strings/c.strings/cstring.pass.cpp
@@ -34,17 +34,12 @@
     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 @@
     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 c3d868f..2b7c3c4 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
@@ -30,18 +31,25 @@
 
 int main()
 {
-    std::mbstate_t mb = {0};
+    std::mbstate_t mb = {};
     std::size_t s = 0;
     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 @@
     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 @@
     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/string.conversions/stod.pass.cpp b/test/std/strings/string.conversions/stod.pass.cpp
index 026d230..27d5e5c 100644
--- a/test/std/strings/string.conversions/stod.pass.cpp
+++ b/test/std/strings/string.conversions/stod.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // double stod(const string& str, size_t *idx = 0);
diff --git a/test/std/strings/string.conversions/stof.pass.cpp b/test/std/strings/string.conversions/stof.pass.cpp
index 3e9b681..38519a2 100644
--- a/test/std/strings/string.conversions/stof.pass.cpp
+++ b/test/std/strings/string.conversions/stof.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin11
 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin12
 
diff --git a/test/std/strings/string.conversions/stoi.pass.cpp b/test/std/strings/string.conversions/stoi.pass.cpp
index c2fc210..2380727 100644
--- a/test/std/strings/string.conversions/stoi.pass.cpp
+++ b/test/std/strings/string.conversions/stoi.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // int stoi(const string& str, size_t *idx = 0, int base = 10);
diff --git a/test/std/strings/string.conversions/stol.pass.cpp b/test/std/strings/string.conversions/stol.pass.cpp
index dbbccc9..2ca2c01 100644
--- a/test/std/strings/string.conversions/stol.pass.cpp
+++ b/test/std/strings/string.conversions/stol.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin11
 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin12
 
diff --git a/test/std/strings/string.conversions/stold.pass.cpp b/test/std/strings/string.conversions/stold.pass.cpp
index 93c59fe..f489df2 100644
--- a/test/std/strings/string.conversions/stold.pass.cpp
+++ b/test/std/strings/string.conversions/stold.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <string>
 
 // long double stold(const string& str, size_t *idx = 0);
diff --git a/test/std/strings/string.conversions/stoll.pass.cpp b/test/std/strings/string.conversions/stoll.pass.cpp
index f68490e..d41db42 100644
--- a/test/std/strings/string.conversions/stoll.pass.cpp
+++ b/test/std/strings/string.conversions/stoll.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin11
 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin12
 
diff --git a/test/std/strings/string.conversions/stoul.pass.cpp b/test/std/strings/string.conversions/stoul.pass.cpp
index 37d33c4..9dbd952 100644
--- a/test/std/strings/string.conversions/stoul.pass.cpp
+++ b/test/std/strings/string.conversions/stoul.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin11
 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin12
 
diff --git a/test/std/strings/string.conversions/stoull.pass.cpp b/test/std/strings/string.conversions/stoull.pass.cpp
index c0667ed..837ca31 100644
--- a/test/std/strings/string.conversions/stoull.pass.cpp
+++ b/test/std/strings/string.conversions/stoull.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin11
 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin12
 
diff --git a/test/std/thread/futures/futures.async/async.pass.cpp b/test/std/thread/futures/futures.async/async.pass.cpp
index 6cfed59..5cb824d 100644
--- a/test/std/thread/futures/futures.async/async.pass.cpp
+++ b/test/std/thread/futures/futures.async/async.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
 // UNSUPPORTED: c++98, c++03
 
@@ -20,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;
 }
@@ -37,163 +45,109 @@
 
 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;
+}
+
+template <class Ret, class CheckLamdba, class ...Args>
+void test(CheckLamdba&& getAndCheckFn, bool IsDeferred, Args&&... args) {
+    // Reset global state.
+    invoked = false;
+
+    // Create the future and wait
+    std::future<Ret> f = std::async(std::forward<Args>(args)...);
+    std::this_thread::sleep_for(ms(300));
+
+    // 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()
 {
-    {
-        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));
-    }
+    // 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<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));
+        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<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));
+        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<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));
+        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<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));
+        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(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();
-        assert(t1-t0 < ms(100));
-    }
-    {
-        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));
-    }
-    {
-        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));
-    }
-
-    {
-        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));
-    }
-
-    {
-        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));
-    }
-
     {
         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/launch.pass.cpp b/test/std/thread/futures/futures.overview/launch.pass.cpp
index da54f7e..bf75fe4 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), "");
+    LIBCPP_STATIC_ASSERT(std::launch::any == (std::launch::async ^ std::launch::deferred), "");
     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/alloc_ctor.pass.cpp b/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp
index 70a4e00..c0fe2ef 100644
--- a/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp
+++ b/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
@@ -19,36 +20,36 @@
 #include <future>
 #include <cassert>
 
-#include "../test_allocator.h"
+#include "test_allocator.h"
 #include "min_allocator.h"
 
 int main()
 {
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
-        std::promise<int> p(std::allocator_arg, test_allocator<int>());
-        assert(test_alloc_base::count == 1);
+        std::promise<int> p(std::allocator_arg, test_allocator<int>(42));
+        assert(test_alloc_base::alloc_count == 1);
         std::future<int> f = p.get_future();
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
-        std::promise<int&> p(std::allocator_arg, test_allocator<int>());
-        assert(test_alloc_base::count == 1);
+        std::promise<int&> p(std::allocator_arg, test_allocator<int>(42));
+        assert(test_alloc_base::alloc_count == 1);
         std::future<int&> f = p.get_future();
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
-        std::promise<void> p(std::allocator_arg, test_allocator<void>());
-        assert(test_alloc_base::count == 1);
+        std::promise<void> p(std::allocator_arg, test_allocator<void>(42));
+        assert(test_alloc_base::alloc_count == 1);
         std::future<void> f = p.get_future();
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     // Test with a minimal allocator
     {
         std::promise<int> p(std::allocator_arg, bare_allocator<void>());
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 c082781..0311cf9 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>
 
@@ -14,74 +16,36 @@
 // promise& operator=(const promise& rhs) = delete;
 
 #include <future>
-#include <cassert>
 
-#include "../test_allocator.h"
+#include "test_macros.h"
 
 int main()
 {
-    assert(test_alloc_base::count == 0);
+#if TEST_STD_VER >= 11
     {
-        std::promise<int> p0(std::allocator_arg, test_allocator<int>());
-        std::promise<int> p(std::allocator_arg, test_allocator<int>());
-        assert(test_alloc_base::count == 2);
-        p = p0;
-        assert(test_alloc_base::count == 1);
-        std::future<int> f = p.get_future();
-        assert(test_alloc_base::count == 1);
-        assert(f.valid());
-        try
-        {
-            f = p0.get_future();
-            assert(false);
-        }
-        catch (const std::future_error& e)
-        {
-            assert(e.code() == make_error_code(std::future_errc::no_state));
-        }
-        assert(test_alloc_base::count == 1);
+        std::promise<int> p0, p;
+        p = p0; // expected-error {{overload resolution selected deleted operator '='}}
     }
-    assert(test_alloc_base::count == 0);
     {
-        std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
-        std::promise<int&> p(std::allocator_arg, test_allocator<int>());
-        assert(test_alloc_base::count == 2);
-        p = p0;
-        assert(test_alloc_base::count == 1);
-        std::future<int&> f = p.get_future();
-        assert(test_alloc_base::count == 1);
-        assert(f.valid());
-        try
-        {
-            f = p0.get_future();
-            assert(false);
-        }
-        catch (const std::future_error& e)
-        {
-            assert(e.code() == make_error_code(std::future_errc::no_state));
-        }
-        assert(test_alloc_base::count == 1);
+        std::promise<int&> p0, p;
+        p = p0; // expected-error {{overload resolution selected deleted operator '='}}
     }
-    assert(test_alloc_base::count == 0);
     {
-        std::promise<void> p0(std::allocator_arg, test_allocator<void>());
-        std::promise<void> p(std::allocator_arg, test_allocator<void>());
-        assert(test_alloc_base::count == 2);
-        p = p0;
-        assert(test_alloc_base::count == 1);
-        std::future<void> f = p.get_future();
-        assert(test_alloc_base::count == 1);
-        assert(f.valid());
-        try
-        {
-            f = p0.get_future();
-            assert(false);
-        }
-        catch (const std::future_error& e)
-        {
-            assert(e.code() == make_error_code(std::future_errc::no_state));
-        }
-        assert(test_alloc_base::count == 1);
+        std::promise<void> p0, p;
+        p = p0; // expected-error {{overload resolution selected deleted operator '='}}
     }
-    assert(test_alloc_base::count == 0);
+#else
+    {
+        std::promise<int> p0, p;
+        p = p0; // expected-error {{'operator=' is a private member of 'std::__1::promise<int>'}}
+    }
+    {
+        std::promise<int&> p0, p;
+        p = p0; // expected-error {{'operator=' is a private member of 'std::__1::promise<int &>'}}
+    }
+    {
+        std::promise<void> p0, p;
+        p = p0; // expected-error {{'operator=' is a private member of 'std::__1::promise<void>'}}
+    }
+#endif
 }
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 36a3555..779fc5b 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>
 
@@ -14,68 +16,36 @@
 // promise(const promise&) = delete;
 
 #include <future>
-#include <cassert>
 
-#include "../test_allocator.h"
+#include "test_macros.h"
 
 int main()
 {
-    assert(test_alloc_base::count == 0);
+#if TEST_STD_VER >= 11
     {
-        std::promise<int> p0(std::allocator_arg, test_allocator<int>());
-        std::promise<int> p(p0);
-        assert(test_alloc_base::count == 1);
-        std::future<int> f = p.get_future();
-        assert(test_alloc_base::count == 1);
-        assert(f.valid());
-        try
-        {
-            f = p0.get_future();
-            assert(false);
-        }
-        catch (const std::future_error& e)
-        {
-            assert(e.code() == make_error_code(std::future_errc::no_state));
-        }
-        assert(test_alloc_base::count == 1);
+        std::promise<int> p0;
+        std::promise<int> p(p0); // expected-error {{call to deleted constructor of 'std::promise<int>'}}
     }
-    assert(test_alloc_base::count == 0);
     {
-        std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
-        std::promise<int&> p(p0);
-        assert(test_alloc_base::count == 1);
-        std::future<int&> f = p.get_future();
-        assert(test_alloc_base::count == 1);
-        assert(f.valid());
-        try
-        {
-            f = p0.get_future();
-            assert(false);
-        }
-        catch (const std::future_error& e)
-        {
-            assert(e.code() == make_error_code(std::future_errc::no_state));
-        }
-        assert(test_alloc_base::count == 1);
+        std::promise<int &> p0;
+        std::promise<int &> p(p0); // expected-error {{call to deleted constructor of 'std::promise<int &>'}}
     }
-    assert(test_alloc_base::count == 0);
     {
-        std::promise<void> p0(std::allocator_arg, test_allocator<void>());
-        std::promise<void> p(p0);
-        assert(test_alloc_base::count == 1);
-        std::future<void> f = p.get_future();
-        assert(test_alloc_base::count == 1);
-        assert(f.valid());
-        try
-        {
-            f = p0.get_future();
-            assert(false);
-        }
-        catch (const std::future_error& e)
-        {
-            assert(e.code() == make_error_code(std::future_errc::no_state));
-        }
-        assert(test_alloc_base::count == 1);
+        std::promise<void> p0;
+        std::promise<void> p(p0); // expected-error {{call to deleted constructor of 'std::promise<void>'}}
     }
-    assert(test_alloc_base::count == 0);
+#else
+    {
+        std::promise<int> p0;
+        std::promise<int> p(p0); // expected-error {{calling a private constructor of class 'std::__1::promise<int>'}}
+    }
+    {
+        std::promise<int &> p0;
+        std::promise<int &> p(p0); // expected-error {{calling a private constructor of class 'std::__1::promise<int &>'}}
+    }
+    {
+        std::promise<void> p0;
+        std::promise<void> p(p0); // expected-error {{calling a private constructor of class 'std::__1::promise<void>'}}
+    }
+#endif
 }
diff --git a/test/std/thread/futures/futures.promise/default.pass.cpp b/test/std/thread/futures/futures.promise/default.pass.cpp
index 95c9657..d108b42 100644
--- a/test/std/thread/futures/futures.promise/default.pass.cpp
+++ b/test/std/thread/futures/futures.promise/default.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.promise/dtor.pass.cpp b/test/std/thread/futures/futures.promise/dtor.pass.cpp
index 78912f1..e3151ab 100644
--- a/test/std/thread/futures/futures.promise/dtor.pass.cpp
+++ b/test/std/thread/futures/futures.promise/dtor.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.promise/get_future.pass.cpp b/test/std/thread/futures/futures.promise/get_future.pass.cpp
index a7d084e..bc45e28 100644
--- a/test/std/thread/futures/futures.promise/get_future.pass.cpp
+++ b/test/std/thread/futures/futures.promise/get_future.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.promise/move_assign.pass.cpp b/test/std/thread/futures/futures.promise/move_assign.pass.cpp
index c3097df..9dd8a9d 100644
--- a/test/std/thread/futures/futures.promise/move_assign.pass.cpp
+++ b/test/std/thread/futures/futures.promise/move_assign.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
@@ -18,20 +20,19 @@
 #include <future>
 #include <cassert>
 
-#include "../test_allocator.h"
+#include "test_allocator.h"
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         std::promise<int> p0(std::allocator_arg, test_allocator<int>());
         std::promise<int> p(std::allocator_arg, test_allocator<int>());
-        assert(test_alloc_base::count == 2);
+        assert(test_alloc_base::alloc_count == 2);
         p = std::move(p0);
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         std::future<int> f = p.get_future();
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
         try
         {
@@ -42,17 +43,17 @@
         {
             assert(e.code() == make_error_code(std::future_errc::no_state));
         }
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
         std::promise<int&> p(std::allocator_arg, test_allocator<int>());
-        assert(test_alloc_base::count == 2);
+        assert(test_alloc_base::alloc_count == 2);
         p = std::move(p0);
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         std::future<int&> f = p.get_future();
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
         try
         {
@@ -63,17 +64,17 @@
         {
             assert(e.code() == make_error_code(std::future_errc::no_state));
         }
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         std::promise<void> p0(std::allocator_arg, test_allocator<void>());
         std::promise<void> p(std::allocator_arg, test_allocator<void>());
-        assert(test_alloc_base::count == 2);
+        assert(test_alloc_base::alloc_count == 2);
         p = std::move(p0);
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         std::future<void> f = p.get_future();
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
         try
         {
@@ -84,8 +85,7 @@
         {
             assert(e.code() == make_error_code(std::future_errc::no_state));
         }
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
     }
-    assert(test_alloc_base::count == 0);
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    assert(test_alloc_base::alloc_count == 0);
 }
diff --git a/test/std/thread/futures/futures.promise/move_ctor.pass.cpp b/test/std/thread/futures/futures.promise/move_ctor.pass.cpp
index eeec4fb..9a68b5c 100644
--- a/test/std/thread/futures/futures.promise/move_ctor.pass.cpp
+++ b/test/std/thread/futures/futures.promise/move_ctor.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
@@ -18,18 +20,17 @@
 #include <future>
 #include <cassert>
 
-#include "../test_allocator.h"
+#include "test_allocator.h"
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         std::promise<int> p0(std::allocator_arg, test_allocator<int>());
         std::promise<int> p(std::move(p0));
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         std::future<int> f = p.get_future();
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
         try
         {
@@ -40,15 +41,15 @@
         {
             assert(e.code() == make_error_code(std::future_errc::no_state));
         }
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
         std::promise<int&> p(std::move(p0));
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         std::future<int&> f = p.get_future();
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
         try
         {
@@ -59,15 +60,15 @@
         {
             assert(e.code() == make_error_code(std::future_errc::no_state));
         }
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         std::promise<void> p0(std::allocator_arg, test_allocator<void>());
         std::promise<void> p(std::move(p0));
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         std::future<void> f = p.get_future();
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
         try
         {
@@ -78,8 +79,7 @@
         {
             assert(e.code() == make_error_code(std::future_errc::no_state));
         }
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
     }
-    assert(test_alloc_base::count == 0);
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    assert(test_alloc_base::alloc_count == 0);
 }
diff --git a/test/std/thread/futures/futures.promise/set_exception.pass.cpp b/test/std/thread/futures/futures.promise/set_exception.pass.cpp
index 51c05eb..6ef41af 100644
--- a/test/std/thread/futures/futures.promise/set_exception.pass.cpp
+++ b/test/std/thread/futures/futures.promise/set_exception.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
index 5e57692..f54d7cd 100644
--- a/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
+++ b/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp b/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp
index cdc3777..9839487 100644
--- a/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp
+++ b/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp
index 18f87c5..e127d2c 100644
--- a/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp
+++ b/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp b/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp
index dab4bf7..9cce3f5 100644
--- a/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp
+++ b/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
diff --git a/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp
index ec50cc3..7913748 100644
--- a/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp
+++ b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp
index 8c09208..6a0ce36 100644
--- a/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp
+++ b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.promise/set_value_const.pass.cpp b/test/std/thread/futures/futures.promise/set_value_const.pass.cpp
index 6673f63..db7465c 100644
--- a/test/std/thread/futures/futures.promise/set_value_const.pass.cpp
+++ b/test/std/thread/futures/futures.promise/set_value_const.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.promise/set_value_void.pass.cpp b/test/std/thread/futures/futures.promise/set_value_void.pass.cpp
index 5012e0b..87be8cd 100644
--- a/test/std/thread/futures/futures.promise/set_value_void.pass.cpp
+++ b/test/std/thread/futures/futures.promise/set_value_void.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.promise/swap.pass.cpp b/test/std/thread/futures/futures.promise/swap.pass.cpp
index 1ed3e64..21c9469 100644
--- a/test/std/thread/futures/futures.promise/swap.pass.cpp
+++ b/test/std/thread/futures/futures.promise/swap.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
@@ -20,65 +21,65 @@
 #include <future>
 #include <cassert>
 
-#include "../test_allocator.h"
+#include "test_allocator.h"
 
 int main()
 {
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         std::promise<int> p0(std::allocator_arg, test_allocator<int>());
         std::promise<int> p(std::allocator_arg, test_allocator<int>());
-        assert(test_alloc_base::count == 2);
+        assert(test_alloc_base::alloc_count == 2);
         p.swap(p0);
-        assert(test_alloc_base::count == 2);
+        assert(test_alloc_base::alloc_count == 2);
         std::future<int> f = p.get_future();
-        assert(test_alloc_base::count == 2);
+        assert(test_alloc_base::alloc_count == 2);
         assert(f.valid());
         f = p0.get_future();
         assert(f.valid());
-        assert(test_alloc_base::count == 2);
+        assert(test_alloc_base::alloc_count == 2);
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         std::promise<int> p0(std::allocator_arg, test_allocator<int>());
         std::promise<int> p(std::allocator_arg, test_allocator<int>());
-        assert(test_alloc_base::count == 2);
+        assert(test_alloc_base::alloc_count == 2);
         swap(p, p0);
-        assert(test_alloc_base::count == 2);
+        assert(test_alloc_base::alloc_count == 2);
         std::future<int> f = p.get_future();
-        assert(test_alloc_base::count == 2);
+        assert(test_alloc_base::alloc_count == 2);
         assert(f.valid());
         f = p0.get_future();
         assert(f.valid());
-        assert(test_alloc_base::count == 2);
+        assert(test_alloc_base::alloc_count == 2);
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         std::promise<int> p0(std::allocator_arg, test_allocator<int>());
         std::promise<int> p;
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         p.swap(p0);
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         std::future<int> f = p.get_future();
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
         f = p0.get_future();
         assert(f.valid());
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         std::promise<int> p0(std::allocator_arg, test_allocator<int>());
         std::promise<int> p;
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         swap(p, p0);
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         std::future<int> f = p.get_future();
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
         f = p0.get_future();
         assert(f.valid());
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
 }
diff --git a/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp b/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp
index 458826e..9a1d41c 100644
--- a/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp
+++ b/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp
@@ -18,7 +18,7 @@
 //      : true_type { };
 
 #include <future>
-#include "../test_allocator.h"
+#include "test_allocator.h"
 
 int main()
 {
diff --git a/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp b/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp
index b23ba19..3f9e945 100644
--- a/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp
+++ b/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
@@ -20,7 +21,6 @@
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     {
         typedef int T;
         std::promise<T> p;
@@ -72,5 +72,4 @@
         assert(!f0.valid());
         assert(!f.valid());
     }
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp b/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp
index 425d1f9..1da0880 100644
--- a/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp
+++ b/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp b/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp
index 3a78b80..1590efd 100644
--- a/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp
+++ b/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.shared_future/dtor.pass.cpp b/test/std/thread/futures/futures.shared_future/dtor.pass.cpp
index baa89cb..af06126 100644
--- a/test/std/thread/futures/futures.shared_future/dtor.pass.cpp
+++ b/test/std/thread/futures/futures.shared_future/dtor.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
@@ -18,51 +20,51 @@
 #include <future>
 #include <cassert>
 
-#include "../test_allocator.h"
+#include "test_allocator.h"
 
 int main()
 {
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         typedef int T;
         std::shared_future<T> f;
         {
             std::promise<T> p(std::allocator_arg, test_allocator<T>());
-            assert(test_alloc_base::count == 1);
+            assert(test_alloc_base::alloc_count == 1);
             f = p.get_future();
-            assert(test_alloc_base::count == 1);
+            assert(test_alloc_base::alloc_count == 1);
             assert(f.valid());
         }
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         typedef int& T;
         std::shared_future<T> f;
         {
             std::promise<T> p(std::allocator_arg, test_allocator<int>());
-            assert(test_alloc_base::count == 1);
+            assert(test_alloc_base::alloc_count == 1);
             f = p.get_future();
-            assert(test_alloc_base::count == 1);
+            assert(test_alloc_base::alloc_count == 1);
             assert(f.valid());
         }
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         typedef void T;
         std::shared_future<T> f;
         {
             std::promise<T> p(std::allocator_arg, test_allocator<T>());
-            assert(test_alloc_base::count == 1);
+            assert(test_alloc_base::alloc_count == 1);
             f = p.get_future();
-            assert(test_alloc_base::count == 1);
+            assert(test_alloc_base::alloc_count == 1);
             assert(f.valid());
         }
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
 }
diff --git a/test/std/thread/futures/futures.shared_future/get.pass.cpp b/test/std/thread/futures/futures.shared_future/get.pass.cpp
index c5ee234..6eea1d8 100644
--- a/test/std/thread/futures/futures.shared_future/get.pass.cpp
+++ b/test/std/thread/futures/futures.shared_future/get.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp b/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp
index 6b58f41..3a1ef7a 100644
--- a/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp
+++ b/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
@@ -20,7 +21,6 @@
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     {
         typedef int T;
         std::promise<T> p;
@@ -72,5 +72,4 @@
         assert(!f0.valid());
         assert(!f.valid());
     }
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp b/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp
index 32b8fd7..15323d6 100644
--- a/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp
+++ b/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.shared_future/wait.pass.cpp b/test/std/thread/futures/futures.shared_future/wait.pass.cpp
index 4293fca..6ff74f6 100644
--- a/test/std/thread/futures/futures.shared_future/wait.pass.cpp
+++ b/test/std/thread/futures/futures.shared_future/wait.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp b/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp
index e5a4754..1ec0862 100644
--- a/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp
+++ b/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp b/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
index 6a6aeba..9cdc2e4 100644
--- a/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
+++ b/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
@@ -8,6 +8,7 @@
  //===----------------------------------------------------------------------===//
  //
  // UNSUPPORTED: libcpp-has-no-threads
+ // UNSUPPORTED: c++98, c++03
 
  // <future>
 
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp
index 70ea0ad..9449e14 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
@@ -14,35 +17,11 @@
 // packaged_task& operator=(packaged_task&) = delete;
 
 #include <future>
-#include <cassert>
-
-class A
-{
-    long data_;
-
-public:
-    explicit A(long i) : data_(i) {}
-
-    long operator()(long i, long j) const {return data_ + i + j;}
-};
 
 int main()
 {
     {
-        std::packaged_task<double(int, char)> p0(A(5));
-        std::packaged_task<double(int, char)> p;
-        p = p0;
-        assert(!p0.valid());
-        assert(p.valid());
-        std::future<double> f = p.get_future();
-        p(3, 'a');
-        assert(f.get() == 105.0);
-    }
-    {
-        std::packaged_task<double(int, char)> p0;
-        std::packaged_task<double(int, char)> p;
-        p = p0;
-        assert(!p0.valid());
-        assert(!p.valid());
+        std::packaged_task<double(int, char)> p0, p;
+        p = p0; // expected-error {{overload resolution selected deleted operator '='}}
     }
 }
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp
index 18786f4..3f11d67 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp
index 45048b7..5d53119 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
@@ -25,5 +28,6 @@
 
 int main()
 {
-    PT p { VPT{} };
+    PT p { VPT{} }; // expected-error {{no matching constructor for initialization of 'PT' (aka 'packaged_task<A (int, char)>')}}
+    // expected-note@future:* 1 {{candidate template ignored: disabled by 'enable_if'}}
 }
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp
index e4df4ec..bedff38 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
@@ -18,7 +21,7 @@
 #include <future>
 #include <cassert>
 
-#include "../../test_allocator.h"
+#include "test_allocator.h"
 
 struct A {};
 typedef std::packaged_task<A(int, char)> PT;
@@ -26,5 +29,6 @@
 
 int main()
 {
-    PT p { std::allocator_arg_t{}, test_allocator<A>{}, VPT {}};
+    PT p { std::allocator_arg_t{}, test_allocator<A>{}, VPT {}}; // expected-error {{no matching constructor for initialization of 'PT' (aka 'packaged_task<A (int, char)>')}}
+    // expected-note@future:* 1 {{candidate template ignored: disabled by 'enable_if'}}
 }
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp
index 9884c49..ff07db9 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
@@ -14,33 +17,12 @@
 // packaged_task(packaged_task&) = delete;
 
 #include <future>
-#include <cassert>
 
-class A
-{
-    long data_;
-
-public:
-    explicit A(long i) : data_(i) {}
-
-    long operator()(long i, long j) const {return data_ + i + j;}
-};
 
 int main()
 {
     {
-        std::packaged_task<double(int, char)> p0(A(5));
-        std::packaged_task<double(int, char)> p(p0);
-        assert(!p0.valid());
-        assert(p.valid());
-        std::future<double> f = p.get_future();
-        p(3, 'a');
-        assert(f.get() == 105.0);
-    }
-    {
         std::packaged_task<double(int, char)> p0;
-        std::packaged_task<double(int, char)> p(p0);
-        assert(!p0.valid());
-        assert(!p.valid());
+        std::packaged_task<double(int, char)> p(p0); // expected-error {{call to deleted constructor of 'std::packaged_task<double (int, char)>'}}
     }
 }
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp
index 7690496..ed147d7 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp
index 2eee2cb..14ac761 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp
index 3aac2b2..3978487 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
@@ -19,7 +20,7 @@
 #include <future>
 #include <cassert>
 
-#include "../../test_allocator.h"
+#include "test_allocator.h"
 #include "min_allocator.h"
 
 class A
@@ -47,7 +48,7 @@
     {
         std::packaged_task<double(int, char)> p(std::allocator_arg,
                                                 test_allocator<A>(), A(5));
-        assert(test_alloc_base::count > 0);
+        assert(test_alloc_base::alloc_count > 0);
         assert(p.valid());
         std::future<double> f = p.get_future();
         p(3, 'a');
@@ -55,14 +56,14 @@
         assert(A::n_copies == 0);
         assert(A::n_moves > 0);
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     A::n_copies = 0;
     A::n_moves  = 0;
     {
         A a(5);
         std::packaged_task<double(int, char)> p(std::allocator_arg,
                                                 test_allocator<A>(), a);
-        assert(test_alloc_base::count > 0);
+        assert(test_alloc_base::alloc_count > 0);
         assert(p.valid());
         std::future<double> f = p.get_future();
         p(3, 'a');
@@ -70,31 +71,31 @@
         assert(A::n_copies > 0);
         assert(A::n_moves > 0);
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     A::n_copies = 0;
     A::n_moves  = 0;
     {
         A a(5);
         std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), &func);
-        assert(test_alloc_base::count > 0);
+        assert(test_alloc_base::alloc_count > 0);
         assert(p.valid());
         std::future<int> f = p.get_future();
         p(4);
         assert(f.get() == 4);
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     A::n_copies = 0;
     A::n_moves  = 0;
     {
         A a(5);
         std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), func);
-        assert(test_alloc_base::count > 0);
+        assert(test_alloc_base::alloc_count > 0);
         assert(p.valid());
         std::future<int> f = p.get_future();
         p(4);
         assert(f.get() == 4);
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     A::n_copies = 0;
     A::n_moves  = 0;
     {
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp
index 88f0722..d9951dc 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
index e24232d..7fafd10 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp
index 13b5db1..c8e5d6e 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
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.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
index 61a6a4f..54ac644 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
index 2a09353..9ad1509 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp
index 9d38d9b..02a5675 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp
index 33763be..eb0091c 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp
index 668732b..d90d593 100644
--- a/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp
index 986f71e..bbe75de 100644
--- a/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp
@@ -9,6 +9,12 @@
 //
 // UNSUPPORTED: libcpp-has-no-threads
 
+// This test is marked XFAIL and not UNSUPPORTED because the non-variadic
+// declaration of packaged_task is available in C++03. Therefore the test
+// should fail because the static_assert fires and not because std::packaged_task
+// in undefined.
+// XFAIL: c++98, c++03
+
 // <future>
 
 // class packaged_task<R(ArgTypes...)>
@@ -18,7 +24,7 @@
 //      : true_type { };
 
 #include <future>
-#include "../../test_allocator.h"
+#include "test_allocator.h"
 
 int main()
 {
diff --git a/test/std/thread/futures/futures.tas/types.pass.cpp b/test/std/thread/futures/futures.tas/types.pass.cpp
index dd1724d..f7c9b22 100644
--- a/test/std/thread/futures/futures.tas/types.pass.cpp
+++ b/test/std/thread/futures/futures.tas/types.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp b/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp
index ebdcbf9..d20f0c3 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>
 
@@ -14,61 +16,36 @@
 // future& operator=(const future&) = delete;
 
 #include <future>
-#include <cassert>
+
+#include "test_macros.h"
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
     {
-        typedef int T;
-        std::promise<T> p;
-        std::future<T> f0 = p.get_future();
-        std::future<T> f;
-        f = f0;
-        assert(!f0.valid());
-        assert(f.valid());
+        std::future<int> f0, f;
+        f = f0; // expected-error {{overload resolution selected deleted operator '='}}
     }
     {
-        typedef int T;
-        std::future<T> f0;
-        std::future<T> f;
-        f = f0;
-        assert(!f0.valid());
-        assert(!f.valid());
+        std::future<int &> f0, f;
+        f = f0; // expected-error {{overload resolution selected deleted operator '='}}
     }
     {
-        typedef int& T;
-        std::promise<T> p;
-        std::future<T> f0 = p.get_future();
-        std::future<T> f;
-        f = f0;
-        assert(!f0.valid());
-        assert(f.valid());
+        std::future<void> f0, f;
+        f = f0; // expected-error {{overload resolution selected deleted operator '='}}
+    }
+#else
+    {
+        std::future<int> f0, f;
+        f = f0; // expected-error {{'operator=' is a private member of 'std::__1::future<int>'}}
     }
     {
-        typedef int& T;
-        std::future<T> f0;
-        std::future<T> f;
-        f = f0;
-        assert(!f0.valid());
-        assert(!f.valid());
+        std::future<int &> f0, f;
+        f = f0; // expected-error {{'operator=' is a private member of 'std::__1::future<int &>'}}
     }
     {
-        typedef void T;
-        std::promise<T> p;
-        std::future<T> f0 = p.get_future();
-        std::future<T> f;
-        f = f0;
-        assert(!f0.valid());
-        assert(f.valid());
+        std::future<void> f0, f;
+        f = f0; // expected-error {{'operator=' is a private member of 'std::__1::future<void>'}}
     }
-    {
-        typedef void T;
-        std::future<T> f0;
-        std::future<T> f;
-        f = f0;
-        assert(!f0.valid());
-        assert(!f.valid());
-    }
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
 }
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 8d43294..e1d85ac 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>
 
@@ -14,53 +16,36 @@
 // future(const future&) = delete;
 
 #include <future>
-#include <cassert>
+
+#include "test_macros.h"
 
 int main()
 {
+#if TEST_STD_VER >= 11
     {
-        typedef int T;
-        std::promise<T> p;
-        std::future<T> f0 = p.get_future();
-        std::future<T> f = f0;
-        assert(!f0.valid());
-        assert(f.valid());
+        std::future<int> f0;
+        std::future<int> f = f0; // expected-error {{call to deleted constructor of 'std::future<int>'}}
     }
     {
-        typedef int T;
-        std::future<T> f0;
-        std::future<T> f = f0;
-        assert(!f0.valid());
-        assert(!f.valid());
+        std::future<int &> f0;
+        std::future<int &> f = f0; // expected-error {{call to deleted constructor of 'std::future<int &>'}}
     }
     {
-        typedef int& T;
-        std::promise<T> p;
-        std::future<T> f0 = p.get_future();
-        std::future<T> f = f0;
-        assert(!f0.valid());
-        assert(f.valid());
+        std::future<void> f0;
+        std::future<void> f = f0; // expected-error {{call to deleted constructor of 'std::future<void>'}}
+    }
+#else
+    {
+        std::future<int> f0;
+        std::future<int> f = f0; // expected-error {{calling a private constructor of class 'std::__1::future<int>'}}
     }
     {
-        typedef int& T;
-        std::future<T> f0;
-        std::future<T> f = std::move(f0);
-        assert(!f0.valid());
-        assert(!f.valid());
+        std::future<int &> f0;
+        std::future<int &> f = f0; // expected-error {{calling a private constructor of class 'std::__1::future<int &>'}}
     }
     {
-        typedef void T;
-        std::promise<T> p;
-        std::future<T> f0 = p.get_future();
-        std::future<T> f = f0;
-        assert(!f0.valid());
-        assert(f.valid());
+        std::future<void> f0;
+        std::future<void> f = f0; // expected-error {{calling a private constructor of class 'std::__1::future<void>'}}
     }
-    {
-        typedef void T;
-        std::future<T> f0;
-        std::future<T> f = f0;
-        assert(!f0.valid());
-        assert(!f.valid());
-    }
+#endif
 }
diff --git a/test/std/thread/futures/futures.unique_future/dtor.pass.cpp b/test/std/thread/futures/futures.unique_future/dtor.pass.cpp
index 5e9697b..03d7c91 100644
--- a/test/std/thread/futures/futures.unique_future/dtor.pass.cpp
+++ b/test/std/thread/futures/futures.unique_future/dtor.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
@@ -18,51 +20,51 @@
 #include <future>
 #include <cassert>
 
-#include "../test_allocator.h"
+#include "test_allocator.h"
 
 int main()
 {
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         typedef int T;
         std::future<T> f;
         {
             std::promise<T> p(std::allocator_arg, test_allocator<T>());
-            assert(test_alloc_base::count == 1);
+            assert(test_alloc_base::alloc_count == 1);
             f = p.get_future();
-            assert(test_alloc_base::count == 1);
+            assert(test_alloc_base::alloc_count == 1);
             assert(f.valid());
         }
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         typedef int& T;
         std::future<T> f;
         {
             std::promise<T> p(std::allocator_arg, test_allocator<int>());
-            assert(test_alloc_base::count == 1);
+            assert(test_alloc_base::alloc_count == 1);
             f = p.get_future();
-            assert(test_alloc_base::count == 1);
+            assert(test_alloc_base::alloc_count == 1);
             assert(f.valid());
         }
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
     {
         typedef void T;
         std::future<T> f;
         {
             std::promise<T> p(std::allocator_arg, test_allocator<T>());
-            assert(test_alloc_base::count == 1);
+            assert(test_alloc_base::alloc_count == 1);
             f = p.get_future();
-            assert(test_alloc_base::count == 1);
+            assert(test_alloc_base::alloc_count == 1);
             assert(f.valid());
         }
-        assert(test_alloc_base::count == 1);
+        assert(test_alloc_base::alloc_count == 1);
         assert(f.valid());
     }
-    assert(test_alloc_base::count == 0);
+    assert(test_alloc_base::alloc_count == 0);
 }
diff --git a/test/std/thread/futures/futures.unique_future/get.pass.cpp b/test/std/thread/futures/futures.unique_future/get.pass.cpp
index 758e38a..67b1052 100644
--- a/test/std/thread/futures/futures.unique_future/get.pass.cpp
+++ b/test/std/thread/futures/futures.unique_future/get.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.unique_future/share.pass.cpp b/test/std/thread/futures/futures.unique_future/share.pass.cpp
index 794b5ce..ef011d8 100644
--- a/test/std/thread/futures/futures.unique_future/share.pass.cpp
+++ b/test/std/thread/futures/futures.unique_future/share.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.unique_future/wait.pass.cpp b/test/std/thread/futures/futures.unique_future/wait.pass.cpp
index e10d37c..f6de983 100644
--- a/test/std/thread/futures/futures.unique_future/wait.pass.cpp
+++ b/test/std/thread/futures/futures.unique_future/wait.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp b/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp
index 0a381d9..c4f3582 100644
--- a/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp
+++ b/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
 // <future>
 
diff --git a/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp b/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp
index d5865b9..541c008 100644
--- a/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp
+++ b/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp
@@ -1,129 +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.
- //
- //===----------------------------------------------------------------------===//
- //
- // UNSUPPORTED: libcpp-has-no-threads
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
 
- // <future>
+// <future>
 
- // class future<R>
+// class future<R>
 
- // template <class Clock, class Duration>
- //   future_status
- //   wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+// template <class Clock, class Duration>
+//   future_status
+//   wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
 
- #include <future>
- #include <atomic>
- #include <cassert>
+#include <future>
+#include <atomic>
+#include <cassert>
 
- enum class WorkerThreadState { Uninitialized, AllowedToRun, Exiting };
- typedef std::chrono::milliseconds ms;
+enum class WorkerThreadState { Uninitialized, AllowedToRun, Exiting };
+typedef std::chrono::milliseconds ms;
 
- std::atomic<WorkerThreadState> thread_state(WorkerThreadState::Uninitialized);
+std::atomic<WorkerThreadState> thread_state(WorkerThreadState::Uninitialized);
 
- void set_worker_thread_state(WorkerThreadState state)
- {
-     thread_state.store(state, std::memory_order_relaxed);
- }
+void set_worker_thread_state(WorkerThreadState state)
+{
+    thread_state.store(state, std::memory_order_relaxed);
+}
 
- void wait_for_worker_thread_state(WorkerThreadState state)
- {
-     while (thread_state.load(std::memory_order_relaxed) != state);
- }
+void wait_for_worker_thread_state(WorkerThreadState state)
+{
+    while (thread_state.load(std::memory_order_relaxed) != state);
+}
 
- void func1(std::promise<int> p)
- {
-     wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
-     p.set_value(3);
-     set_worker_thread_state(WorkerThreadState::Exiting);
- }
+void func1(std::promise<int> p)
+{
+    wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+    p.set_value(3);
+    set_worker_thread_state(WorkerThreadState::Exiting);
+}
 
- int j = 0;
+int j = 0;
 
- void func3(std::promise<int&> p)
- {
-     wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
-     j = 5;
-     p.set_value(j);
-     set_worker_thread_state(WorkerThreadState::Exiting);
- }
+void func3(std::promise<int&> p)
+{
+    wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+    j = 5;
+    p.set_value(j);
+    set_worker_thread_state(WorkerThreadState::Exiting);
+}
 
- void func5(std::promise<void> p)
- {
-     wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
-     p.set_value();
-     set_worker_thread_state(WorkerThreadState::Exiting);
- }
+void func5(std::promise<void> p)
+{
+    wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+    p.set_value();
+    set_worker_thread_state(WorkerThreadState::Exiting);
+}
 
- int main()
- {
-     typedef std::chrono::high_resolution_clock Clock;
-     {
-         typedef int T;
-         std::promise<T> p;
-         std::future<T> f = p.get_future();
-         std::thread(func1, std::move(p)).detach();
-         assert(f.valid());
-         assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
-         assert(f.valid());
+int main()
+{
+    typedef std::chrono::high_resolution_clock Clock;
+    {
+        typedef int T;
+        std::promise<T> p;
+        std::future<T> f = p.get_future();
+        std::thread(func1, std::move(p)).detach();
+        assert(f.valid());
+        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+        assert(f.valid());
 
-         // allow the worker thread to produce the result and wait until the worker is done
-         set_worker_thread_state(WorkerThreadState::AllowedToRun);
-         wait_for_worker_thread_state(WorkerThreadState::Exiting);
+        // allow the worker thread to produce the result and wait until the worker is done
+        set_worker_thread_state(WorkerThreadState::AllowedToRun);
+        wait_for_worker_thread_state(WorkerThreadState::Exiting);
 
-         assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
-         assert(f.valid());
-         Clock::time_point t0 = Clock::now();
-         f.wait();
-         Clock::time_point t1 = Clock::now();
-         assert(f.valid());
-         assert(t1-t0 < ms(5));
-     }
-     {
-         typedef int& T;
-         std::promise<T> p;
-         std::future<T> f = p.get_future();
-         std::thread(func3, std::move(p)).detach();
-         assert(f.valid());
-         assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
-         assert(f.valid());
+        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+        assert(f.valid());
+        Clock::time_point t0 = Clock::now();
+        f.wait();
+        Clock::time_point t1 = Clock::now();
+        assert(f.valid());
+        assert(t1-t0 < ms(5));
+    }
+    {
+        typedef int& T;
+        std::promise<T> p;
+        std::future<T> f = p.get_future();
+        std::thread(func3, std::move(p)).detach();
+        assert(f.valid());
+        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+        assert(f.valid());
 
-         // allow the worker thread to produce the result and wait until the worker is done
-         set_worker_thread_state(WorkerThreadState::AllowedToRun);
-         wait_for_worker_thread_state(WorkerThreadState::Exiting);
+        // allow the worker thread to produce the result and wait until the worker is done
+        set_worker_thread_state(WorkerThreadState::AllowedToRun);
+        wait_for_worker_thread_state(WorkerThreadState::Exiting);
 
-         assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
-         assert(f.valid());
-         Clock::time_point t0 = Clock::now();
-         f.wait();
-         Clock::time_point t1 = Clock::now();
-         assert(f.valid());
-         assert(t1-t0 < ms(5));
-     }
-     {
-         typedef void T;
-         std::promise<T> p;
-         std::future<T> f = p.get_future();
-         std::thread(func5, std::move(p)).detach();
-         assert(f.valid());
-         assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
-         assert(f.valid());
+        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+        assert(f.valid());
+        Clock::time_point t0 = Clock::now();
+        f.wait();
+        Clock::time_point t1 = Clock::now();
+        assert(f.valid());
+        assert(t1-t0 < ms(5));
+    }
+    {
+        typedef void T;
+        std::promise<T> p;
+        std::future<T> f = p.get_future();
+        std::thread(func5, std::move(p)).detach();
+        assert(f.valid());
+        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+        assert(f.valid());
 
-         // allow the worker thread to produce the result and wait until the worker is done
-         set_worker_thread_state(WorkerThreadState::AllowedToRun);
-         wait_for_worker_thread_state(WorkerThreadState::Exiting);
+        // allow the worker thread to produce the result and wait until the worker is done
+        set_worker_thread_state(WorkerThreadState::AllowedToRun);
+        wait_for_worker_thread_state(WorkerThreadState::Exiting);
 
-         assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
-         assert(f.valid());
-         Clock::time_point t0 = Clock::now();
-         f.wait();
-         Clock::time_point t1 = Clock::now();
-         assert(f.valid());
-         assert(t1-t0 < ms(5));
-     }
- }
+        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+        assert(f.valid());
+        Clock::time_point t0 = Clock::now();
+        f.wait();
+        Clock::time_point t1 = Clock::now();
+        assert(f.valid());
+        assert(t1-t0 < ms(5));
+    }
+}
diff --git a/test/std/thread/futures/test_allocator.h b/test/std/thread/futures/test_allocator.h
deleted file mode 100644
index 5007290..0000000
--- a/test/std/thread/futures/test_allocator.h
+++ /dev/null
@@ -1,158 +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.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TEST_ALLOCATOR_H
-#define TEST_ALLOCATOR_H
-
-#include <cstddef>
-#include <type_traits>
-#include <utility>
-#include <cstdlib>
-#include <new>
-#include <climits>
-
-class test_alloc_base
-{
-public:
-    static int count;
-public:
-    static int throw_after;
-};
-
-int test_alloc_base::count = 0;
-int test_alloc_base::throw_after = INT_MAX;
-
-template <class T>
-class test_allocator
-    : public test_alloc_base
-{
-    int data_;
-
-    template <class U> friend class test_allocator;
-public:
-
-    typedef unsigned                                                   size_type;
-    typedef int                                                        difference_type;
-    typedef T                                                          value_type;
-    typedef value_type*                                                pointer;
-    typedef const value_type*                                          const_pointer;
-    typedef typename std::add_lvalue_reference<value_type>::type       reference;
-    typedef typename std::add_lvalue_reference<const value_type>::type const_reference;
-
-    template <class U> struct rebind {typedef test_allocator<U> other;};
-
-    test_allocator() throw() : data_(-1) {}
-    explicit test_allocator(int i) throw() : data_(i) {}
-    test_allocator(const test_allocator& a) throw()
-        : data_(a.data_) {}
-    template <class U> test_allocator(const test_allocator<U>& a) throw()
-        : data_(a.data_) {}
-    ~test_allocator() throw() {data_ = 0;}
-    pointer address(reference x) const {return &x;}
-    const_pointer address(const_reference x) const {return &x;}
-    pointer allocate(size_type n, const void* = 0)
-        {
-            if (count >= throw_after) {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-                throw std::bad_alloc();
-#else
-                std::terminate();
-#endif
-            }
-            ++count;
-            return (pointer)std::malloc(n * sizeof(T));
-        }
-    void deallocate(pointer p, size_type n)
-        {--count; std::free(p);}
-    size_type max_size() const throw()
-        {return UINT_MAX / sizeof(T);}
-    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();}
-
-    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)
-        {return !(x == y);}
-};
-
-template <>
-class test_allocator<void>
-    : public test_alloc_base
-{
-    int data_;
-
-    template <class U> friend class test_allocator;
-public:
-
-    typedef unsigned                                                   size_type;
-    typedef int                                                        difference_type;
-    typedef void                                                       value_type;
-    typedef value_type*                                                pointer;
-    typedef const value_type*                                          const_pointer;
-
-    template <class U> struct rebind {typedef test_allocator<U> other;};
-
-    test_allocator() throw() : data_(-1) {}
-    explicit test_allocator(int i) throw() : data_(i) {}
-    test_allocator(const test_allocator& a) throw()
-        : data_(a.data_) {}
-    template <class U> test_allocator(const test_allocator<U>& a) throw()
-        : data_(a.data_) {}
-    ~test_allocator() throw() {data_ = 0;}
-
-    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)
-        {return !(x == y);}
-};
-
-template <class T>
-class other_allocator
-{
-    int data_;
-
-    template <class U> friend class other_allocator;
-
-public:
-    typedef T value_type;
-
-    other_allocator() : data_(-1) {}
-    explicit other_allocator(int i) : data_(i) {}
-    template <class U> other_allocator(const other_allocator<U>& a)
-        : data_(a.data_) {}
-    T* allocate(std::size_t n)
-        {return (T*)std::malloc(n * sizeof(T));}
-    void deallocate(T* p, std::size_t n)
-        {std::free(p);}
-
-    other_allocator select_on_container_copy_construction() const
-        {return other_allocator(-2);}
-
-    friend bool operator==(const other_allocator& x, const other_allocator& y)
-        {return x.data_ == y.data_;}
-    friend bool operator!=(const other_allocator& x, const other_allocator& y)
-        {return !(x == y);}
-
-    typedef std::true_type propagate_on_container_copy_assignment;
-    typedef std::true_type propagate_on_container_move_assignment;
-    typedef std::true_type propagate_on_container_swap;
-
-#ifdef _LIBCPP_HAS_NO_ADVANCED_SFINAE
-    std::size_t max_size() const
-        {return UINT_MAX / sizeof(T);}
-#endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
-
-};
-
-#endif  // TEST_ALLOCATOR_H
diff --git a/test/std/thread/thread.condition/notify_all_at_thread_exit.pass.cpp b/test/std/thread/thread.condition/notify_all_at_thread_exit.pass.cpp
index 2b8772f..02da345 100644
--- a/test/std/thread/thread.condition/notify_all_at_thread_exit.pass.cpp
+++ b/test/std/thread/thread.condition/notify_all_at_thread_exit.pass.cpp
@@ -9,6 +9,10 @@
 //
 // UNSUPPORTED: libcpp-has-no-threads
 
+// notify_all_at_thread_exit(...) requires move semantics to transfer the
+// unique_lock.
+// UNSUPPORTED: c++98, c++03
+
 // <condition_variable>
 
 // void
@@ -36,9 +40,10 @@
 int main()
 {
     std::unique_lock<std::mutex> lk(mut);
-    std::thread(func).detach();
+    std::thread t(func);
     Clock::time_point t0 = Clock::now();
     cv.wait(lk);
     Clock::time_point t1 = Clock::now();
     assert(t1-t0 > ms(250));
+    t.join();
 }
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp
index 6236a13..e99ebee 100644
--- a/test/std/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp
+++ b/test/std/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp
@@ -16,16 +16,17 @@
 // void notify_one();
 
 #include <condition_variable>
+#include <atomic>
 #include <mutex>
 #include <thread>
 #include <cassert>
 
+
 std::condition_variable cv;
 std::mutex mut;
 
-int test0 = 0;
-int test1 = 0;
-int test2 = 0;
+std::atomic_int test1(0);
+std::atomic_int test2(0);
 
 void f1()
 {
@@ -64,11 +65,13 @@
     }
     if (test1 == 2)
     {
+        assert(test2 == 1);
         t1.join();
         test1 = 0;
     }
     else if (test2 == 2)
     {
+        assert(test1 == 1);
         t2.join();
         test2 = 0;
     }
@@ -81,11 +84,13 @@
     }
     if (test1 == 2)
     {
+        assert(test2 == 0);
         t1.join();
         test1 = 0;
     }
     else if (test2 == 2)
     {
+        assert(test1 == 0);
         t2.join();
         test2 = 0;
     }
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp
deleted file mode 100644
index 522c61b..0000000
--- a/test/std/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: libcpp-has-no-threads
-
-#include <thread>
-#include <condition_variable>
-#include <mutex>
-#include <chrono>
-#include <iostream>
-#include <cassert>
-
-void f1()
-{
-    std::exit(0);
-}
-
-struct Mutex
-{
-    unsigned state = 0;
-    Mutex() = default;
-    ~Mutex() = default;
-    Mutex(const Mutex&) = delete;
-    Mutex& operator=(const Mutex&) = delete;
-
-    void lock()
-    {
-    if (++state == 2)
-        throw 1;  // this throw should end up calling terminate()
-    }
-
-    void unlock() {}
-};
-
-Mutex mut;
-std::condition_variable_any cv;
-
-void
-signal_me()
-{
-    std::this_thread::sleep_for(std::chrono::milliseconds(500));
-    cv.notify_one();
-}
-
-int
-main()
-{
-    std::set_terminate(f1);
-    try
-    {
-        std::thread(signal_me).detach();
-        mut.lock();
-        cv.wait(mut);
-    }
-    catch (...) {}
-    assert(false);
-}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp
deleted file mode 100644
index 1906b58..0000000
--- a/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: libcpp-has-no-threads
-
-#include <thread>
-#include <condition_variable>
-#include <mutex>
-#include <chrono>
-#include <iostream>
-#include <cassert>
-
-void f1()
-{
-    std::exit(0);
-}
-
-struct Mutex
-{
-    unsigned state = 0;
-    Mutex() = default;
-    ~Mutex() = default;
-    Mutex(const Mutex&) = delete;
-    Mutex& operator=(const Mutex&) = delete;
-
-    void lock()
-    {
-    if (++state == 2)
-        throw 1;  // this throw should end up calling terminate()
-    }
-
-    void unlock() {}
-};
-
-Mutex mut;
-std::condition_variable_any cv;
-
-void
-signal_me()
-{
-    std::this_thread::sleep_for(std::chrono::milliseconds(500));
-    cv.notify_one();
-}
-
-int
-main()
-{
-    std::set_terminate(f1);
-    try
-    {
-        std::thread(signal_me).detach();
-        mut.lock();
-        cv.wait_for(mut, std::chrono::milliseconds(250));
-    }
-    catch (...) {}
-    assert(false);
-}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/wait_terminates.sh.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_terminates.sh.cpp
new file mode 100644
index 0000000..f9a35cc
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/wait_terminates.sh.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.
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: libcpp-no-exceptions
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable_any;
+
+// RUN: %build
+// RUN: %run 1
+// RUN: %run 2
+// RUN: %run 3
+// RUN: %run 4
+// RUN: %run 5
+// RUN: %run 6
+
+// -----------------------------------------------------------------------------
+// Overview
+//   Check that std::terminate is called if wait(...) fails to meet it's post
+//   conditions. This can happens when reacquiring the mutex throws
+//   an exception.
+//
+//  The following methods are tested within this file
+//   1.  void wait(Lock& lock);
+//   2.  void wait(Lock& lock, Pred);
+//   3.  void wait_for(Lock& lock, Duration);
+//   4.  void wait_for(Lock& lock, Duration, Pred);
+//   5.  void wait_until(Lock& lock, TimePoint);
+//   6.  void wait_until(Lock& lock, TimePoint, Pred);
+//
+// Plan
+//   1 Create a mutex type, 'ThrowingMutex', that throws when the lock is aquired
+//     for the *second* time.
+//
+//   2 Replace the terminate handler with one that exits with a '0' exit code.
+//
+//   3 Create a 'condition_variable_any' object 'cv' and a 'ThrowingMutex'
+//     object 'm' and lock 'm'.
+//
+//   4 Start a thread 'T2' that will notify 'cv' once 'm' has been unlocked.
+//
+//   5 From the main thread call the specified wait method on 'cv' with 'm'.
+//     When 'T2' notifies 'cv' and the wait method attempts to re-lock
+//    'm' an exception will be thrown from 'm.lock()'.
+//
+//   6 Check that control flow does not return from the wait method and that
+//     terminate is called (If the program exits with a 0 exit code we know
+//     that terminate has been called)
+
+
+#include <condition_variable>
+#include <atomic>
+#include <thread>
+#include <chrono>
+#include <string>
+#include <cstdlib>
+#include <cassert>
+
+void my_terminate() {
+  std::_Exit(0); // Use _Exit to prevent cleanup from taking place.
+}
+
+// The predicate used in the cv.wait calls.
+bool pred = false;
+bool pred_function() {
+  return pred == true;
+}
+
+class ThrowingMutex
+{
+  std::atomic_bool locked;
+  unsigned state = 0;
+  ThrowingMutex(const ThrowingMutex&) = delete;
+  ThrowingMutex& operator=(const ThrowingMutex&) = delete;
+public:
+  ThrowingMutex() {
+    locked = false;
+  }
+  ~ThrowingMutex() = default;
+
+  void lock() {
+    locked = true;
+    if (++state == 2) {
+      assert(pred); // Check that we actually waited until we were signaled.
+      throw 1;  // this throw should end up calling terminate()
+    }
+  }
+
+  void unlock() { locked = false; }
+  bool isLocked() const { return locked == true; }
+};
+
+ThrowingMutex mut;
+std::condition_variable_any cv;
+
+void signal_me() {
+  while (mut.isLocked()) {} // wait until T1 releases mut inside the cv.wait call.
+  pred = true;
+  cv.notify_one();
+}
+
+typedef std::chrono::system_clock Clock;
+typedef std::chrono::milliseconds MS;
+
+int main(int argc, char** argv) {
+  assert(argc == 2);
+  int id = std::stoi(argv[1]);
+  assert(id >= 1 && id <= 6);
+  std::set_terminate(my_terminate); // set terminate after std::stoi because it can throw.
+  MS wait(250);
+  try {
+    mut.lock();
+    assert(pred == false);
+    std::thread(signal_me).detach();
+    switch (id) {
+      case 1: cv.wait(mut); break;
+      case 2: cv.wait(mut, pred_function); break;
+      case 3: cv.wait_for(mut, wait); break;
+      case 4: cv.wait_for(mut, wait, pred_function); break;
+      case 5: cv.wait_until(mut, Clock::now() + wait); break;
+      case 6: cv.wait_until(mut, Clock::now() + wait, pred_function); break;
+      default: assert(false);
+    }
+  } catch (...) {}
+  assert(false);
+}
diff --git a/test/std/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp
index f67ca21..eac7600 100644
--- a/test/std/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
diff --git a/test/std/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp
index f0c54b7..8889408 100644
--- a/test/std/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp
index 2c1c665..f7cf49c 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -20,9 +21,7 @@
 
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     std::shared_lock<std::shared_timed_mutex> ul;
     assert(!ul.owns_lock());
     assert(ul.mutex() == nullptr);
-#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 8676f2c..bd707bb 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
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -17,23 +18,33 @@
 
 #include <shared_mutex>
 #include <cassert>
+#include "nasty_containers.hpp"
 
-#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);
+    {
+    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);
-#endif  // _LIBCPP_STD_VER > 11
+    }
+    {
+    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 f59d2e8..c29a3fb 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
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -17,19 +18,28 @@
 
 #include <shared_mutex>
 #include <cassert>
-
-#if _LIBCPP_STD_VER > 11
-std::shared_timed_mutex m;
-#endif  // _LIBCPP_STD_VER > 11
+#include "nasty_containers.hpp"
 
 int main()
 {
-#if _LIBCPP_STD_VER > 11
-    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);
-#endif  // _LIBCPP_STD_VER > 11
+    }
+    {
+    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.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
index c8a0287..12bef34 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -21,9 +22,7 @@
 #include <cstdlib>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
-
-std::shared_timed_mutex m;
+#include "test_macros.h"
 
 typedef std::chrono::system_clock Clock;
 typedef Clock::time_point time_point;
@@ -31,6 +30,19 @@
 typedef std::chrono::milliseconds ms;
 typedef std::chrono::nanoseconds ns;
 
+ms WaitTime = ms(250);
+
+// Thread sanitizer causes more overhead and will sometimes cause this test
+// to fail. To prevent this we give Thread sanitizer more time to complete the
+// test.
+#if !defined(TEST_HAS_SANITIZERS)
+ms Tolerance = ms(50);
+#else
+ms Tolerance = ms(50 * 5);
+#endif
+
+std::shared_timed_mutex m;
+
 void f()
 {
     time_point t0 = Clock::now();
@@ -39,8 +51,8 @@
     std::shared_lock<std::shared_timed_mutex> ul(m);
     t1 = Clock::now();
     }
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within tolerance
 }
 
 void g()
@@ -52,30 +64,30 @@
     t1 = Clock::now();
     }
     ns d = t1 - t0;
-    assert(d < ms(50));  // within 50ms
+    assert(d < Tolerance);  // within tolerance
 }
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
-    m.lock();
     std::vector<std::thread> v;
-    for (int i = 0; i < 5; ++i)
-        v.push_back(std::thread(f));
-    std::this_thread::sleep_for(ms(250));
-    m.unlock();
-    for (auto& t : v)
-        t.join();
-    m.lock_shared();
-    for (auto& t : v)
-        t = std::thread(g);
-    std::thread q(f);
-    std::this_thread::sleep_for(ms(250));
-    m.unlock_shared();
-    for (auto& t : v)
-        t.join();
-    q.join();
-#endif  // _LIBCPP_STD_VER > 11
+    {
+        m.lock();
+        for (int i = 0; i < 5; ++i)
+            v.push_back(std::thread(f));
+        std::this_thread::sleep_for(WaitTime);
+        m.unlock();
+        for (auto& t : v)
+            t.join();
+    }
+    {
+        m.lock_shared();
+        for (auto& t : v)
+            t = std::thread(g);
+        std::thread q(f);
+        std::this_thread::sleep_for(WaitTime);
+        m.unlock_shared();
+        for (auto& t : v)
+            t.join();
+        q.join();
+    }
 }
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 3b49b30..341f0ce 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
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -17,14 +18,24 @@
 
 #include <shared_mutex>
 #include <cassert>
+#include "nasty_containers.hpp"
 
 int main()
 {
-#if _LIBCPP_STD_VER > 11
-    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);
-#endif  // _LIBCPP_STD_VER > 11
+    }
+    {
+    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 bbc38fc..5fbb724 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
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -17,13 +18,22 @@
 
 #include <shared_mutex>
 #include <cassert>
+#include "nasty_containers.hpp"
 
 int main()
 {
-#if _LIBCPP_STD_VER > 11
-    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);
-#endif  // _LIBCPP_STD_VER > 11
+    }
+    {
+    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.shared/thread.lock.shared.cons/mutex_duration.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp
index 9816e57..84f868d 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -22,7 +23,7 @@
 #include <cstdlib>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
+#include "test_macros.h"
 
 std::shared_timed_mutex m;
 
@@ -32,37 +33,46 @@
 typedef std::chrono::milliseconds ms;
 typedef std::chrono::nanoseconds ns;
 
+ms WaitTime = ms(250);
+
+// Thread sanitizer causes more overhead and will sometimes cause this test
+// to fail. To prevent this we give Thread sanitizer more time to complete the
+// test.
+#if !defined(TEST_HAS_SANITIZERS)
+ms Tolerance = ms(50);
+#else
+ms Tolerance = ms(50 * 5);
+#endif
+
+
 void f1()
 {
     time_point t0 = Clock::now();
-    std::shared_lock<std::shared_timed_mutex> lk(m, ms(300));
+    std::shared_lock<std::shared_timed_mutex> lk(m, WaitTime + Tolerance);
     assert(lk.owns_lock() == true);
     time_point t1 = Clock::now();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within 50ms
 }
 
 void f2()
 {
     time_point t0 = Clock::now();
-    std::shared_lock<std::shared_timed_mutex> lk(m, ms(250));
+    std::shared_lock<std::shared_timed_mutex> lk(m, WaitTime);
     assert(lk.owns_lock() == false);
     time_point t1 = Clock::now();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within 50ms
 }
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     {
         m.lock();
         std::vector<std::thread> v;
         for (int i = 0; i < 5; ++i)
             v.push_back(std::thread(f1));
-        std::this_thread::sleep_for(ms(250));
+        std::this_thread::sleep_for(WaitTime);
         m.unlock();
         for (auto& t : v)
             t.join();
@@ -72,10 +82,9 @@
         std::vector<std::thread> v;
         for (int i = 0; i < 5; ++i)
             v.push_back(std::thread(f2));
-        std::this_thread::sleep_for(ms(300));
+        std::this_thread::sleep_for(WaitTime + Tolerance);
         m.unlock();
         for (auto& t : v)
             t.join();
     }
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp
index 5d188ab..9359731 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -22,7 +23,7 @@
 #include <cstdlib>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
+#include "test_macros.h"
 
 std::shared_timed_mutex m;
 
@@ -32,37 +33,45 @@
 typedef std::chrono::milliseconds ms;
 typedef std::chrono::nanoseconds ns;
 
+ms WaitTime = ms(250);
+
+// Thread sanitizer causes more overhead and will sometimes cause this test
+// to fail. To prevent this we give Thread sanitizer more time to complete the
+// test.
+#if !defined(TEST_HAS_SANITIZERS)
+ms Tolerance = ms(50);
+#else
+ms Tolerance = ms(50 * 5);
+#endif
+
 void f1()
 {
     time_point t0 = Clock::now();
-    std::shared_lock<std::shared_timed_mutex> lk(m, Clock::now() + ms(300));
+    std::shared_lock<std::shared_timed_mutex> lk(m, Clock::now() + WaitTime + Tolerance);
     assert(lk.owns_lock() == true);
     time_point t1 = Clock::now();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ns(50000000));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within 50ms
 }
 
 void f2()
 {
     time_point t0 = Clock::now();
-    std::shared_lock<std::shared_timed_mutex> lk(m, Clock::now() + ms(250));
+    std::shared_lock<std::shared_timed_mutex> lk(m, Clock::now() + WaitTime);
     assert(lk.owns_lock() == false);
     time_point t1 = Clock::now();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within 50ms
 }
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     {
         m.lock();
         std::vector<std::thread> v;
         for (int i = 0; i < 5; ++i)
             v.push_back(std::thread(f1));
-        std::this_thread::sleep_for(ms(250));
+        std::this_thread::sleep_for(WaitTime);
         m.unlock();
         for (auto& t : v)
             t.join();
@@ -72,10 +81,9 @@
         std::vector<std::thread> v;
         for (int i = 0; i < 5; ++i)
             v.push_back(std::thread(f2));
-        std::this_thread::sleep_for(ms(300));
+        std::this_thread::sleep_for(WaitTime + Tolerance);
         m.unlock();
         for (auto& t : v)
             t.join();
     }
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp
index f2d4e0d..7f89f0a 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -21,8 +22,6 @@
 #include <cstdlib>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
-
 std::shared_timed_mutex m;
 
 typedef std::chrono::system_clock Clock;
@@ -57,11 +56,8 @@
     assert(d < ms(200));  // within 200ms
 }
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     m.lock();
     std::vector<std::thread> v;
     for (int i = 0; i < 5; ++i)
@@ -70,5 +66,4 @@
     m.unlock();
     for (auto& t : v)
         t.join();
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
index f150065..5c3513c 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -21,7 +23,7 @@
 #include <cstdlib>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
+#include "test_macros.h"
 
 std::shared_timed_mutex m;
 
@@ -31,6 +33,18 @@
 typedef std::chrono::milliseconds ms;
 typedef std::chrono::nanoseconds ns;
 
+ms WaitTime = ms(250);
+
+// Thread sanitizer causes more overhead and will sometimes cause this test
+// to fail. To prevent this we give Thread sanitizer more time to complete the
+// test.
+#if !defined(TEST_HAS_SANITIZERS)
+ms Tolerance = ms(25);
+#else
+ms Tolerance = ms(25 * 5);
+#endif
+
+
 void f()
 {
     std::shared_lock<std::shared_timed_mutex> lk(m, std::defer_lock);
@@ -38,8 +52,8 @@
     lk.lock();
     time_point t1 = Clock::now();
     assert(lk.owns_lock() == true);
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(25));  // within 25ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within tolerance
     try
     {
         lk.lock();
@@ -62,18 +76,14 @@
     }
 }
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     m.lock();
     std::vector<std::thread> v;
     for (int i = 0; i < 5; ++i)
         v.push_back(std::thread(f));
-    std::this_thread::sleep_for(ms(250));
+    std::this_thread::sleep_for(WaitTime);
     m.unlock();
     for (auto& t : v)
         t.join();
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
index 82b1ff8..01693c7 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -18,8 +20,6 @@
 #include <shared_mutex>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
-
 bool try_lock_called = false;
 
 struct mutex
@@ -34,11 +34,9 @@
 
 mutex m;
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
+
     std::shared_lock<mutex> lk(m, std::defer_lock);
     assert(lk.try_lock() == true);
     assert(try_lock_called == true);
@@ -66,5 +64,4 @@
     {
         assert(e.code().value() == EPERM);
     }
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
index 5867465..852a94e 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -19,8 +21,6 @@
 #include <shared_mutex>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
-
 bool try_lock_for_called = false;
 
 typedef std::chrono::milliseconds ms;
@@ -39,11 +39,8 @@
 
 mutex m;
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     std::shared_lock<mutex> lk(m, std::defer_lock);
     assert(lk.try_lock_for(ms(5)) == true);
     assert(try_lock_for_called == true);
@@ -71,5 +68,4 @@
     {
         assert(e.code().value() == EPERM);
     }
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
index 9d38983..31574af 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -19,8 +21,6 @@
 #include <shared_mutex>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
-
 bool try_lock_until_called = false;
 
 struct mutex
@@ -38,11 +38,8 @@
 
 mutex m;
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     typedef std::chrono::steady_clock Clock;
     std::shared_lock<mutex> lk(m, std::defer_lock);
     assert(lk.try_lock_until(Clock::now()) == true);
@@ -71,5 +68,4 @@
     {
         assert(e.code().value() == EPERM);
     }
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
index eb08a45..6a7385e 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -18,8 +20,6 @@
 #include <shared_mutex>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
-
 bool unlock_called = false;
 
 struct mutex
@@ -30,11 +30,8 @@
 
 mutex m;
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     std::shared_lock<mutex> lk(m);
     lk.unlock();
     assert(unlock_called == true);
@@ -58,5 +55,4 @@
     {
         assert(e.code().value() == EPERM);
     }
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
index 8505763..23a0c70 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -18,8 +19,6 @@
 #include <shared_mutex>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
-
 struct mutex
 {
     void lock_shared() {}
@@ -28,11 +27,8 @@
 
 mutex m;
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     std::shared_lock<mutex> lk1(m);
     std::shared_lock<mutex> lk2;
     lk1.swap(lk2);
@@ -41,5 +37,4 @@
     assert(lk2.mutex() == &m);
     assert(lk2.owns_lock() == true);
     static_assert(noexcept(lk1.swap(lk2)), "member swap must be noexcept");
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
index 057dbc4..0f19174 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -19,8 +20,6 @@
 #include <shared_mutex>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
-
 struct mutex
 {
     void lock_shared() {}
@@ -29,11 +28,8 @@
 
 mutex m;
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     std::shared_lock<mutex> lk1(m);
     std::shared_lock<mutex> lk2;
     swap(lk1, lk2);
@@ -42,5 +38,4 @@
     assert(lk2.mutex() == &m);
     assert(lk2.owns_lock() == true);
     static_assert(noexcept(swap(lk1, lk2)), "non-member swap must be noexcept");
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
index 65ddca6..2b5f8c1 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -18,8 +19,6 @@
 #include <shared_mutex>
 #include <cassert>
 
-#if _LIBCPP_STD_VER > 11
-
 struct mutex
 {
     static int lock_count;
@@ -33,11 +32,8 @@
 
 mutex m;
 
-#endif  // _LIBCPP_STD_VER > 11
-
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     std::shared_lock<mutex> lk(m);
     assert(lk.mutex() == &m);
     assert(lk.owns_lock() == true);
@@ -49,5 +45,4 @@
     assert(mutex::lock_count == 1);
     assert(mutex::unlock_count == 0);
     static_assert(noexcept(lk.release()), "release must be noexcept");
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp
index 4eb75d8..711ab7c 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -18,15 +19,10 @@
 #include <shared_mutex>
 #include <cassert>
 
-#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;
     assert(lk0.mutex() == nullptr);
     std::shared_lock<std::shared_timed_mutex> lk1(m);
@@ -34,5 +30,4 @@
     lk1.unlock();
     assert(lk1.mutex() == &m);
     static_assert(noexcept(lk0.mutex()), "mutex() must be noexcept");
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
index d079d2d..3f6ad2b 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -18,15 +19,10 @@
 #include <shared_mutex>
 #include <cassert>
 
-#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;
     assert(static_cast<bool>(lk0) == false);
     std::shared_lock<std::shared_timed_mutex> lk1(m);
@@ -34,5 +30,4 @@
     lk1.unlock();
     assert(static_cast<bool>(lk1) == false);
     static_assert(noexcept(static_cast<bool>(lk0)), "explicit operator bool() must be noexcept");
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp
index d64b0aa..5ab3ac0 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
 
 // <shared_mutex>
 
@@ -18,15 +19,10 @@
 #include <shared_mutex>
 #include <cassert>
 
-#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;
     assert(lk0.owns_lock() == false);
     std::shared_lock<std::shared_timed_mutex> lk1(m);
@@ -34,5 +30,4 @@
     lk1.unlock();
     assert(lk1.owns_lock() == false);
     static_assert(noexcept(lk0.owns_lock()), "owns_lock must be noexcept");
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp
index c153b45..f555d3d 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp
@@ -8,6 +8,8 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11
+
 
 // <shared_mutex>
 
@@ -24,8 +26,6 @@
 
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     static_assert((std::is_same<std::shared_lock<std::mutex>::mutex_type,
                    std::mutex>::value), "");
-#endif  // _LIBCPP_STD_VER > 11
 }
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 4f47744..8d864ea 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 4888fe9..0673021 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 4dff853..e5db685 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() == &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::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);
+    }
 #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 aa640ee..427deab 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 9c3a7b6..20f7d24 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 bf62231..242dacb 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.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
index f5408df..6ce3376 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
index bd88577..27d0562 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
index 558f079..6f0a721 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
index 24e4d10..b7e8724 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp
index bbabfc4..62497c9 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
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 7bcb2d6..81995f6 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
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11, c++14
 
 // <shared_mutex>
 
@@ -15,15 +18,9 @@
 
 #include <shared_mutex>
 
-#include "test_macros.h"
-
 int main()
 {
-#if TEST_STD_VER > 14
     std::shared_mutex m0;
     std::shared_mutex m1;
-    m1 = m0;
-#else
-#   error
-#endif
+    m1 = m0; // expected-error {{overload resolution selected deleted operator '='}}
 }
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 af064ae..e4bee4b 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
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03, c++11, c++14
 
 // <shared_mutex>
 
@@ -15,14 +18,8 @@
 
 #include <shared_mutex>
 
-#include "test_macros.h"
-
 int main()
 {
-#if TEST_STD_VER > 14
     std::shared_mutex m0;
-    std::shared_mutex m1(m0);
-#else
-#   error
-#endif
+    std::shared_mutex m1(m0); // expected-error {{call to deleted constructor of 'std::shared_mutex'}}
 }
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp
index 9bf7a79..75ddebf 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp
@@ -21,6 +21,7 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "test_macros.h"
 
 std::shared_mutex m;
 
@@ -30,21 +31,32 @@
 typedef std::chrono::milliseconds ms;
 typedef std::chrono::nanoseconds ns;
 
+ms WaitTime = ms(250);
+
+// Thread sanitizer causes more overhead and will sometimes cause this test
+// to fail. To prevent this we give Thread sanitizer more time to complete the
+// test.
+#if !defined(TEST_HAS_SANITIZERS)
+ms Tolerance = ms(50);
+#else
+ms Tolerance = ms(50 * 5);
+#endif
+
 void f()
 {
     time_point t0 = Clock::now();
     m.lock();
     time_point t1 = Clock::now();
     m.unlock();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within tolerance
 }
 
 int main()
 {
     m.lock();
     std::thread t(f);
-    std::this_thread::sleep_for(ms(250));
+    std::this_thread::sleep_for(WaitTime);
     m.unlock();
     t.join();
 }
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp
index 3ffa9e2..6b5089d 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp
@@ -22,6 +22,8 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "test_macros.h"
+
 std::shared_mutex m;
 
 typedef std::chrono::system_clock Clock;
@@ -30,14 +32,25 @@
 typedef std::chrono::milliseconds ms;
 typedef std::chrono::nanoseconds ns;
 
+ms WaitTime = ms(250);
+
+// Thread sanitizer causes more overhead and will sometimes cause this test
+// to fail. To prevent this we give Thread sanitizer more time to complete the
+// test.
+#if !defined(TEST_HAS_SANITIZERS)
+ms Tolerance = ms(50);
+#else
+ms Tolerance = ms(50 * 5);
+#endif
+
 void f()
 {
     time_point t0 = Clock::now();
     m.lock_shared();
     time_point t1 = Clock::now();
     m.unlock_shared();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within tolerance
 }
 
 void g()
@@ -47,7 +60,7 @@
     time_point t1 = Clock::now();
     m.unlock_shared();
     ns d = t1 - t0;
-    assert(d < ms(50));  // within 50ms
+    assert(d < Tolerance);  // within tolerance
 }
 
 
@@ -57,7 +70,7 @@
     std::vector<std::thread> v;
     for (int i = 0; i < 5; ++i)
         v.push_back(std::thread(f));
-    std::this_thread::sleep_for(ms(250));
+    std::this_thread::sleep_for(WaitTime);
     m.unlock();
     for (auto& t : v)
         t.join();
@@ -65,7 +78,7 @@
     for (auto& t : v)
         t = std::thread(g);
     std::thread q(f);
-    std::this_thread::sleep_for(ms(250));
+    std::this_thread::sleep_for(WaitTime);
     m.unlock_shared();
     for (auto& t : v)
         t.join();
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp
index 62bb736..2818bd6 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp
@@ -21,6 +21,8 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "test_macros.h"
+
 std::shared_timed_mutex m;
 
 typedef std::chrono::system_clock Clock;
@@ -29,6 +31,19 @@
 typedef std::chrono::milliseconds ms;
 typedef std::chrono::nanoseconds ns;
 
+
+ms WaitTime = ms(250);
+
+// Thread sanitizer causes more overhead and will sometimes cause this test
+// to fail. To prevent this we give Thread sanitizer more time to complete the
+// test.
+#if !TEST_HAS_FEATURE(thread_sanitizer)
+ms Tolerance = ms(50);
+#else
+ms Tolerance = ms(100);
+#endif
+
+
 void f()
 {
     time_point t0 = Clock::now();
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp
index 8fc6299..77a9107 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp
@@ -22,6 +22,8 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "test_macros.h"
+
 std::shared_timed_mutex m;
 
 typedef std::chrono::system_clock Clock;
@@ -30,14 +32,27 @@
 typedef std::chrono::milliseconds ms;
 typedef std::chrono::nanoseconds ns;
 
+
+ms WaitTime = ms(250);
+
+// Thread sanitizer causes more overhead and will sometimes cause this test
+// to fail. To prevent this we give Thread sanitizer more time to complete the
+// test.
+#if !defined(TEST_HAS_SANITIZERS)
+ms Tolerance = ms(50);
+#else
+ms Tolerance = ms(50 * 5);
+#endif
+
+
 void f()
 {
     time_point t0 = Clock::now();
     m.lock_shared();
     time_point t1 = Clock::now();
     m.unlock_shared();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within tolerance
 }
 
 void g()
@@ -47,7 +62,7 @@
     time_point t1 = Clock::now();
     m.unlock_shared();
     ns d = t1 - t0;
-    assert(d < ms(50));  // within 50ms
+    assert(d < Tolerance);  // within tolerance
 }
 
 
@@ -57,7 +72,7 @@
     std::vector<std::thread> v;
     for (int i = 0; i < 5; ++i)
         v.push_back(std::thread(f));
-    std::this_thread::sleep_for(ms(250));
+    std::this_thread::sleep_for(WaitTime);
     m.unlock();
     for (auto& t : v)
         t.join();
@@ -65,7 +80,7 @@
     for (auto& t : v)
         t = std::thread(g);
     std::thread q(f);
-    std::this_thread::sleep_for(ms(250));
+    std::this_thread::sleep_for(WaitTime);
     m.unlock_shared();
     for (auto& t : v)
         t.join();
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp
index ab20241..320a268 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp
@@ -22,6 +22,8 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "test_macros.h"
+
 std::shared_timed_mutex m;
 
 typedef std::chrono::steady_clock Clock;
@@ -30,23 +32,35 @@
 typedef std::chrono::milliseconds ms;
 typedef std::chrono::nanoseconds ns;
 
+
+ms WaitTime = ms(250);
+
+// Thread sanitizer causes more overhead and will sometimes cause this test
+// to fail. To prevent this we give Thread sanitizer more time to complete the
+// test.
+#if !defined(TEST_HAS_SANITIZERS)
+ms Tolerance = ms(50);
+#else
+ms Tolerance = ms(50 * 5);
+#endif
+
 void f1()
 {
     time_point t0 = Clock::now();
-    assert(m.try_lock_for(ms(300)) == true);
+    assert(m.try_lock_for(WaitTime + Tolerance) == true);
     time_point t1 = Clock::now();
     m.unlock();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within tolerance
 }
 
 void f2()
 {
     time_point t0 = Clock::now();
-    assert(m.try_lock_for(ms(250)) == false);
+    assert(m.try_lock_for(WaitTime) == false);
     time_point t1 = Clock::now();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within tolerance
 }
 
 int main()
@@ -54,14 +68,14 @@
     {
         m.lock();
         std::thread t(f1);
-        std::this_thread::sleep_for(ms(250));
+        std::this_thread::sleep_for(WaitTime);
         m.unlock();
         t.join();
     }
     {
         m.lock();
         std::thread t(f2);
-        std::this_thread::sleep_for(ms(300));
+        std::this_thread::sleep_for(WaitTime + Tolerance);
         m.unlock();
         t.join();
     }
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp
index 9c2d8c9..3d5604d 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp
@@ -22,6 +22,8 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "test_macros.h"
+
 std::shared_timed_mutex m;
 
 typedef std::chrono::system_clock Clock;
@@ -30,6 +32,13 @@
 typedef std::chrono::milliseconds ms;
 typedef std::chrono::nanoseconds ns;
 
+
+#if !defined(TEST_HAS_SANITIZERS)
+ms Tolerance = ms(200);
+#else
+ms Tolerance = ms(200 * 5);
+#endif
+
 void f()
 {
     time_point t0 = Clock::now();
@@ -41,7 +50,7 @@
     time_point t1 = Clock::now();
     m.unlock_shared();
     ns d = t1 - t0 - ms(250);
-    assert(d < ms(200));  // within 200ms
+    assert(d < Tolerance);  // within tolerance
 }
 
 int main()
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp
index 3544411..4cdb587 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp
@@ -23,6 +23,8 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "test_macros.h"
+
 std::shared_timed_mutex m;
 
 typedef std::chrono::steady_clock Clock;
@@ -31,23 +33,34 @@
 typedef std::chrono::milliseconds ms;
 typedef std::chrono::nanoseconds ns;
 
+ms WaitTime = ms(250);
+
+// Thread sanitizer causes more overhead and will sometimes cause this test
+// to fail. To prevent this we give Thread sanitizer more time to complete the
+// test.
+#if !defined(TEST_HAS_SANITIZERS)
+ms Tolerance = ms(50);
+#else
+ms Tolerance = ms(50 * 5);
+#endif
+
 void f1()
 {
     time_point t0 = Clock::now();
-    assert(m.try_lock_shared_for(ms(300)) == true);
+    assert(m.try_lock_shared_for(WaitTime + Tolerance) == true);
     time_point t1 = Clock::now();
     m.unlock_shared();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within 50ms
 }
 
 void f2()
 {
     time_point t0 = Clock::now();
-    assert(m.try_lock_shared_for(ms(250)) == false);
+    assert(m.try_lock_shared_for(WaitTime) == false);
     time_point t1 = Clock::now();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within 50ms
 }
 
 int main()
@@ -57,7 +70,7 @@
         std::vector<std::thread> v;
         for (int i = 0; i < 5; ++i)
             v.push_back(std::thread(f1));
-        std::this_thread::sleep_for(ms(250));
+        std::this_thread::sleep_for(WaitTime);
         m.unlock();
         for (auto& t : v)
             t.join();
@@ -67,7 +80,7 @@
         std::vector<std::thread> v;
         for (int i = 0; i < 5; ++i)
             v.push_back(std::thread(f2));
-        std::this_thread::sleep_for(ms(300));
+        std::this_thread::sleep_for(WaitTime + Tolerance);
         m.unlock();
         for (auto& t : v)
             t.join();
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp
index 4e0f19d..f7ddbae 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp
@@ -23,6 +23,8 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "test_macros.h"
+
 std::shared_timed_mutex m;
 
 typedef std::chrono::steady_clock Clock;
@@ -31,23 +33,34 @@
 typedef std::chrono::milliseconds ms;
 typedef std::chrono::nanoseconds ns;
 
+ms WaitTime = ms(250);
+
+// Thread sanitizer causes more overhead and will sometimes cause this test
+// to fail. To prevent this we give Thread sanitizer more time to complete the
+// test.
+#if !defined(TEST_HAS_SANITIZERS)
+ms Tolerance = ms(50);
+#else
+ms Tolerance = ms(50 * 5);
+#endif
+
 void f1()
 {
     time_point t0 = Clock::now();
-    assert(m.try_lock_shared_until(Clock::now() + ms(300)) == true);
+    assert(m.try_lock_shared_until(Clock::now() + WaitTime + Tolerance) == true);
     time_point t1 = Clock::now();
     m.unlock_shared();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within 50ms
 }
 
 void f2()
 {
     time_point t0 = Clock::now();
-    assert(m.try_lock_shared_until(Clock::now() + ms(250)) == false);
+    assert(m.try_lock_shared_until(Clock::now() + WaitTime) == false);
     time_point t1 = Clock::now();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within tolerance
 }
 
 int main()
@@ -57,7 +70,7 @@
         std::vector<std::thread> v;
         for (int i = 0; i < 5; ++i)
             v.push_back(std::thread(f1));
-        std::this_thread::sleep_for(ms(250));
+        std::this_thread::sleep_for(WaitTime);
         m.unlock();
         for (auto& t : v)
             t.join();
@@ -67,7 +80,7 @@
         std::vector<std::thread> v;
         for (int i = 0; i < 5; ++i)
             v.push_back(std::thread(f2));
-        std::this_thread::sleep_for(ms(300));
+        std::this_thread::sleep_for(WaitTime + Tolerance);
         m.unlock();
         for (auto& t : v)
             t.join();
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp
index aa90cf7..1560af2 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp
@@ -32,23 +32,35 @@
 typedef std::chrono::milliseconds ms;
 typedef std::chrono::nanoseconds ns;
 
+
+ms WaitTime = ms(250);
+
+// Thread sanitizer causes more overhead and will sometimes cause this test
+// to fail. To prevent this we give Thread sanitizer more time to complete the
+// test.
+#if !defined(TEST_HAS_SANITIZERS)
+ms Tolerance = ms(50);
+#else
+ms Tolerance = ms(50 * 5);
+#endif
+
 void f1()
 {
     time_point t0 = Clock::now();
-    assert(m.try_lock_until(Clock::now() + ms(300)) == true);
+    assert(m.try_lock_until(Clock::now() + WaitTime + Tolerance) == true);
     time_point t1 = Clock::now();
     m.unlock();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within tolerance
 }
 
 void f2()
 {
     time_point t0 = Clock::now();
-    assert(m.try_lock_until(Clock::now() + ms(250)) == false);
+    assert(m.try_lock_until(Clock::now() + WaitTime) == false);
     time_point t1 = Clock::now();
-    ns d = t1 - t0 - ms(250);
-    assert(d < ms(50));  // within 50ms
+    ns d = t1 - t0 - WaitTime;
+    assert(d < Tolerance);  // within tolerance
 }
 
 int main()
@@ -56,14 +68,14 @@
     {
         m.lock();
         std::thread t(f1);
-        std::this_thread::sleep_for(ms(250));
+        std::this_thread::sleep_for(WaitTime);
         m.unlock();
         t.join();
     }
     {
         m.lock();
         std::thread t(f2);
-        std::this_thread::sleep_for(ms(300));
+        std::this_thread::sleep_for(WaitTime + Tolerance);
         m.unlock();
         t.join();
     }
diff --git a/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp b/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
index 89b9934..afc318c 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
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 a8b4be1..2489bfc 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// XFAIL: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
@@ -19,21 +20,28 @@
 
 #include <thread>
 #include <new>
+#include <atomic>
 #include <cstdlib>
 #include <cassert>
 
-unsigned throw_one = 0xFFFF;
+#include "test_macros.h"
+
+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;
+    ++outstanding_new;
     return std::malloc(s);
 }
 
 void  operator delete(void* p) throw()
 {
+    --outstanding_new;
     std::free(p);
 }
 
@@ -75,7 +83,7 @@
 int G::n_alive = 0;
 bool G::op_run = false;
 
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+#if TEST_STD_VER >= 11
 
 class MoveOnly
 {
@@ -91,27 +99,58 @@
 
 #endif
 
+// 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();
+    }
+    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(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);
     }
-    f_run = false;
-    {
-        try
-        {
-            throw_one = 0;
-            std::thread t(f);
-            assert(false);
-        }
-        catch (...)
-        {
-            throw_one = 0xFFFF;
-            assert(!f_run);
-        }
-    }
+
     {
         assert(G::n_alive == 0);
         assert(!G::op_run);
@@ -137,7 +176,7 @@
             assert(!G::op_run);
         }
     }
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+#if TEST_STD_VER >= 11
     {
         assert(G::n_alive == 0);
         assert(!G::op_run);
@@ -150,5 +189,5 @@
         std::thread t = std::thread(MoveOnly(), MoveOnly());
         t.join();
     }
-#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif
 }
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp
index ddf96d0..0efb771 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp
@@ -9,8 +9,6 @@
 //
 // UNSUPPORTED: libcpp-has-no-threads
 
-// NOTE: TSAN will report this test as leaking a thread.
-// XFAIL: tsan
 
 // <thread>
 
@@ -47,7 +45,7 @@
 
 void f1()
 {
-    std::exit(0);
+    std::_Exit(0);
 }
 
 int main()
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 f4a4d1f..726395d 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
@@ -19,7 +19,7 @@
 #include <atomic>
 #include <cassert>
 
-std::atomic_bool done = ATOMIC_VAR_INIT(false);
+std::atomic_bool done(false);
 
 class G
 {
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 e165d98..bc5de61 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
@@ -37,7 +37,10 @@
 {
      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 +74,10 @@
 {
      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, "");
diff --git a/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/copy_assign.pass.cpp b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/copy_assign.pass.cpp
new file mode 100644
index 0000000..72f0e86
--- /dev/null
+++ b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/copy_assign.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor& other);
+
+
+#include <scoped_allocator>
+#include <cassert>
+
+#include "allocators.h"
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        A a1(A1<int>(3));
+        A aN;
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        aN = a1;
+        assert(A1<int>::copy_called == true);
+        assert(A1<int>::move_called == false);
+        assert(aN == a1);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        A a1(A1<int>(4), A2<int>(5));
+        A aN;
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        A2<int>::copy_called = false;
+        A2<int>::move_called = false;
+        aN = a1;
+        assert(A1<int>::copy_called == true);
+        assert(A1<int>::move_called == false);
+        assert(A2<int>::copy_called == true);
+        assert(A2<int>::move_called == false);
+        assert(aN == a1);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        A a1(A1<int>(4), A2<int>(5), A3<int>(6));
+        A aN;
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        A2<int>::copy_called = false;
+        A2<int>::move_called = false;
+        A3<int>::copy_called = false;
+        A3<int>::move_called = false;
+        aN = a1;
+        assert(A1<int>::copy_called == true);
+        assert(A1<int>::move_called == false);
+        assert(A2<int>::copy_called == true);
+        assert(A2<int>::move_called == false);
+        assert(A3<int>::copy_called == true);
+        assert(A3<int>::move_called == false);
+        assert(aN == a1);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/move_assign.pass.cpp b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/move_assign.pass.cpp
new file mode 100644
index 0000000..0dc479c
--- /dev/null
+++ b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/move_assign.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&& other);
+
+
+#include <scoped_allocator>
+#include <cassert>
+
+#include "allocators.h"
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        A a1(A1<int>(3));
+        A aN;
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        aN = std::move(a1);
+        assert(A1<int>::copy_called == false);
+        assert(A1<int>::move_called == true);
+        assert(aN == a1);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        A a1(A1<int>(4), A2<int>(5));
+        A aN;
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        A2<int>::copy_called = false;
+        A2<int>::move_called = false;
+        aN = std::move(a1);
+        assert(A1<int>::copy_called == false);
+        assert(A1<int>::move_called == true);
+        assert(A2<int>::copy_called == false);
+        assert(A2<int>::move_called == true);
+        assert(aN == a1);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        A a1(A1<int>(4), A2<int>(5), A3<int>(6));
+        A aN;
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        A2<int>::copy_called = false;
+        A2<int>::move_called = false;
+        A3<int>::copy_called = false;
+        A3<int>::move_called = false;
+        aN = std::move(a1);
+        assert(A1<int>::copy_called == false);
+        assert(A1<int>::move_called == true);
+        assert(A2<int>::copy_called == false);
+        assert(A2<int>::move_called == true);
+        assert(A3<int>::copy_called == false);
+        assert(A3<int>::move_called == true);
+        assert(aN == a1);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
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 0000000..5e347c4
--- /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/invoke_function_object.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp
index 4577d0b..a0c686d 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 @@
     }
 };
 
-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/func.invoke/invoke.pass.cpp b/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp
index 4b9cc76..3f02c7c 100644
--- a/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp
+++ b/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp
@@ -40,6 +40,7 @@
 
 #include <functional>
 #include <type_traits>
+#include <utility> // for std::move
 #include <cassert>
 
 struct NonCopyable {
@@ -173,6 +174,32 @@
     }
     {
         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);
@@ -218,6 +245,22 @@
     }
     {
         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);
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 4096bd8..f371223 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
@@ -69,4 +69,7 @@
     test0(std::mem_fn(&A::test0));
     test1(std::mem_fn(&A::test1));
     test2(std::mem_fn(&A::test2));
+#if __has_feature(cxx_noexcept)
+    static_assert((noexcept(std::mem_fn(&A::test0))), ""); // LWG#2489
+#endif
 }
diff --git a/test/std/containers/sequences/vector/const_value_type.pass.cpp b/test/std/utilities/function.objects/func.require/INVOKE_tested_elsewhere.pass.cpp
similarity index 60%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/utilities/function.objects/func.require/INVOKE_tested_elsewhere.pass.cpp
index e16e439..d61c377 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/utilities/function.objects/func.require/INVOKE_tested_elsewhere.pass.cpp
@@ -7,16 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// INVOKE (f, t1, t2, ..., tN)
 
-// vector<const int> v;  // an extension
+// 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.
 
-#include <vector>
-#include <type_traits>
-
-int main()
-{
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
-}
+int main() {}
diff --git a/test/std/utilities/function.objects/func.require/invoke_helpers.h b/test/std/utilities/function.objects/func.require/invoke_helpers.h
deleted file mode 100644
index 0583b62..0000000
--- a/test/std/utilities/function.objects/func.require/invoke_helpers.h
+++ /dev/null
@@ -1,317 +0,0 @@
-#ifndef INVOKE_HELPERS_H
-#define INVOKE_HELPERS_H
-
-#include <type_traits>
-#include <cassert>
-#include <functional>
-
-#include "test_macros.h"
-
-template <int I>
-struct Int : public std::integral_constant<int, I> {};
-
-template <bool P>
-struct Bool : public std::integral_constant<bool, P> {};
-
-struct Q_None {
-    template <class T>
-    struct apply { typedef T type; };
-};
-
-struct Q_Const {
-    template <class T>
-    struct apply { typedef T const type; };
-};
-
-struct Q_Volatile {
-    template <class T>
-    struct apply { typedef T volatile type; };
-};
-
-struct Q_CV {
-    template <class T>
-    struct apply { typedef T const volatile type; };
-};
-
-// Caster - A functor object that performs cv-qualifier and value category
-//   conversions.
-//   QualTag - A metafunction type that applies cv-qualifiers to its argument.
-//   RValue - True if the resulting object should be an RValue reference.
-//            False otherwise.
-template <class QualTag, bool RValue = false>
-struct Caster {
-    template <class T>
-    struct apply {
-        typedef typename std::remove_reference<T>::type RawType;
-        typedef typename QualTag::template apply<RawType>::type CVType;
-#if TEST_STD_VER >= 11
-        typedef typename std::conditional<RValue,
-            CVType&&, CVType&
-        >::type type;
-#else
-        typedef CVType& type;
-#endif
-    };
-
-    template <class T>
-    typename apply<T>::type
-    operator()(T& obj) const {
-        typedef typename apply<T>::type OutType;
-        return static_cast<OutType>(obj);
-    }
-};
-
-typedef Caster<Q_None>           LValueCaster;
-typedef Caster<Q_Const>          ConstCaster;
-typedef Caster<Q_Volatile>       VolatileCaster;
-typedef Caster<Q_CV>             CVCaster;
-typedef Caster<Q_None,     true> MoveCaster;
-typedef Caster<Q_Const,    true> MoveConstCaster;
-typedef Caster<Q_Volatile, true> MoveVolatileCaster;
-typedef Caster<Q_CV,       true> MoveCVCaster;
-
-// A shorter name for 'static_cast'
-template <class QualType, class Tp>
-QualType C_(Tp& v) { return static_cast<QualType>(v); };
-
-//==============================================================================
-// ArgType - A non-copyable type intended to be used as a dummy argument type
-//   to test functions.
-struct ArgType {
-    int value;
-    explicit ArgType(int val = 0) : value(val) {}
-private:
-    ArgType(ArgType const&);
-    ArgType& operator=(ArgType const&);
-};
-
-//==============================================================================
-// DerivedFromBase - A type that derives from it's template argument 'Base'
-template <class Base>
-struct DerivedFromType : public Base {
-    DerivedFromType() : Base() {}
-    template <class Tp>
-    explicit DerivedFromType(Tp const& t) : Base(t) {}
-};
-
-//==============================================================================
-// DerefToType - A type that dereferences to it's template argument 'To'.
-//   The cv-ref qualifiers of the 'DerefToType' object do not propagate
-//   to the resulting 'To' object.
-template <class To>
-struct DerefToType {
-    To object;
-
-    DerefToType() {}
-
-    template <class Up>
-    explicit DerefToType(Up const& val) : object(val) {}
-
-    To& operator*() const volatile { return const_cast<To&>(object); }
-};
-
-//==============================================================================
-// DerefPropToType - A type that dereferences to it's template argument 'To'.
-//   The cv-ref qualifiers of the 'DerefPropToType' object propagate
-//   to the resulting 'To' object.
-template <class To>
-struct DerefPropType {
-    To object;
-
-    DerefPropType() {}
-
-    template <class Up>
-    explicit DerefPropType(Up const& val) : object(val) {}
-
-#if TEST_STD_VER < 11
-    To& operator*() { return object; }
-    To const& operator*() const { return object; }
-    To volatile& operator*() volatile  { return object; }
-    To const volatile& operator*() const volatile { return object; }
-#else
-    To& operator*() & { return object; }
-    To const& operator*() const & { return object; }
-    To volatile& operator*() volatile  & { return object; }
-    To const volatile& operator*() const volatile & { return object; }
-    To&& operator*() && { return static_cast<To &&>(object); }
-    To const&& operator*() const && { return static_cast<To const&&>(object); }
-    To volatile&& operator*() volatile  && { return static_cast<To volatile&&>(object); }
-    To const volatile&& operator*() const volatile && { return static_cast<To const volatile&&>(object); }
-#endif
-};
-
-//==============================================================================
-// MethodID - A type that uniquely identifies a member function for a class.
-//   This type is used to communicate between the member functions being tested
-//   and the tests invoking them.
-// - Test methods should call 'setUncheckedCall()' whenever they are invoked.
-// - Tests consume the unchecked call using checkCall(<return-value>)` to assert
-//   that the method has been called and that the return value of `__invoke`
-//   matches what the method actually returned.
-template <class T>
-struct MethodID {
-    typedef void* IDType;
-
-    static int dummy; // A dummy memory location.
-    static void* id; // The "ID" is the value of this pointer.
-    static bool unchecked_call; // Has a call happened that has not been checked.
-
-    static void*& setUncheckedCall() {
-        assert(unchecked_call == false);
-        unchecked_call = true;
-        return id;
-    }
-
-    static bool checkCalled(void*& return_value) {
-        bool old = unchecked_call;
-        unchecked_call = false;
-        return old && id == return_value && &id == &return_value;
-    }
-};
-
-template <class T> int   MethodID<T>::dummy = 0;
-template <class T> void* MethodID<T>::id = (void*)&MethodID<T>::dummy;
-template <class T> bool  MethodID<T>::unchecked_call = false;
-
-
-//==============================================================================
-// FunctionPtrID - Like MethodID but for free function pointers.
-template <class T, T*>
-struct FunctionPtrID {
-    static int dummy; // A dummy memory location.
-    static void* id; // The "ID" is the value of this pointer.
-    static bool unchecked_call; // Has a call happened that has not been checked.
-
-    static void*& setUncheckedCall() {
-        assert(unchecked_call == false);
-        unchecked_call = true;
-        return id;
-    }
-
-    static bool checkCalled(void*& return_value) {
-        bool old = unchecked_call;
-        unchecked_call = false;
-        return old && id == return_value && &id == &return_value;
-    }
-};
-
-template <class T, T* Ptr> int   FunctionPtrID<T, Ptr>::dummy = 0;
-template <class T, T* Ptr> void* FunctionPtrID<T, Ptr>::id = (void*)&FunctionPtrID<T, Ptr>::dummy;
-template <class T, T* Ptr> bool  FunctionPtrID<T, Ptr>::unchecked_call = false;
-
-//==============================================================================
-// BasicTest - The basic test structure for everything except
-// member object pointers.
-// ID - The "Function Identifier" type used either MethodID or FunctionPtrID.
-// Arity - The Arity of the call signature.
-// ObjectCaster - The object transformation functor type.
-// ArgCaster - The extra argument transformation functor type.
-template <class ID, int Arity, class ObjectCaster = LValueCaster,
-                               class ArgCaster    = LValueCaster>
-struct BasicTest {
-    template <class ObjectT>
-    void runTest(ObjectT& object) {
-        Int<Arity> A;
-        runTestImp(A, object);
-    }
-
-    template <class MethodPtr, class ObjectT>
-    void runTest(MethodPtr ptr, ObjectT& object) {
-        Int<Arity> A;
-        runTestImp(A, ptr, object);
-    }
-
-private:
-    typedef void*& CallRet;
-    ObjectCaster object_cast;
-    ArgCaster arg_cast;
-    ArgType a0, a1, a2;
-
-    //==========================================================================
-    //                       BULLET 1 AND 2 TEST METHODS
-    //==========================================================================
-    template <class MethodPtr, class ObjectT>
-    void runTestImp(Int<0>, MethodPtr ptr, ObjectT& object) {
-        static_assert((std::is_same<
-            decltype(std::__invoke(ptr, object_cast(object)))
-          , CallRet>::value), "");
-        assert(ID::unchecked_call == false);
-        CallRet ret = std::__invoke(ptr, object_cast(object));
-        assert(ID::checkCalled(ret));
-    }
-
-    template <class MethodPtr, class ObjectT>
-    void runTestImp(Int<1>, MethodPtr ptr, ObjectT& object) {
-        static_assert((std::is_same<
-            decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0)))
-          , CallRet>::value), "");
-        assert(ID::unchecked_call == false);
-        CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0));
-        assert(ID::checkCalled(ret));
-    }
-
-    template <class MethodPtr, class ObjectT>
-    void runTestImp(Int<2>, MethodPtr ptr, ObjectT& object) {
-        static_assert((std::is_same<
-            decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)))
-          , CallRet>::value), "");
-        assert(ID::unchecked_call == false);
-        CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1));
-        assert(ID::checkCalled(ret));
-    }
-
-    template <class MethodPtr, class ObjectT>
-    void runTestImp(Int<3>, MethodPtr ptr, ObjectT& object) {
-        static_assert((std::is_same<
-            decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
-          , CallRet>::value), "");
-        assert(ID::unchecked_call == false);
-        CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
-        assert(ID::checkCalled(ret));
-    }
-
-    //==========================================================================
-    //                       BULLET 5 TEST METHODS
-    //==========================================================================
-    template <class ObjectT>
-    void runTestImp(Int<0>, ObjectT& object) {
-        static_assert((std::is_same<
-            decltype(std::__invoke(object_cast(object)))
-          , CallRet>::value), "");
-        assert(ID::unchecked_call == false);
-        CallRet ret = std::__invoke(object_cast(object));
-        assert(ID::checkCalled(ret));
-    }
-
-    template <class ObjectT>
-    void runTestImp(Int<1>, ObjectT& object) {
-        static_assert((std::is_same<
-            decltype(std::__invoke(object_cast(object), arg_cast(a0)))
-          , CallRet>::value), "");
-        assert(ID::unchecked_call == false);
-        CallRet ret = std::__invoke(object_cast(object), arg_cast(a0));
-        assert(ID::checkCalled(ret));
-    }
-
-    template <class ObjectT>
-    void runTestImp(Int<2>, ObjectT& object) {
-        static_assert((std::is_same<
-            decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1)))
-          , CallRet>::value), "");
-        assert(ID::unchecked_call == false);
-        CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1));
-        assert(ID::checkCalled(ret));
-    }
-
-    template <class ObjectT>
-    void runTestImp(Int<3>, ObjectT& object) {
-        static_assert((std::is_same<
-            decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
-          , CallRet>::value), "");
-        assert(ID::unchecked_call == false);
-        CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
-        assert(ID::checkCalled(ret));
-    }
-};
-
-#endif // INVOKE_HELPERS_H
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_nullptr.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_nullptr.pass.cpp
new file mode 100644
index 0000000..f89bde8
--- /dev/null
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_nullptr.pass.cpp
@@ -0,0 +1,247 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// class function<R(ArgTypes...)>
+
+// function(Fp);
+
+// Ensure that __not_null works for all function types.
+// See https://llvm.org/bugs/show_bug.cgi?id=23589
+
+//------------------------------------------------------------------------------
+// TESTING std::function<...>::__not_null(Callable)
+//
+// Concerns:
+//  1) The call __not_null(Callable) is well formed and correct for each
+//     possible 'Callable' type category. These categories include:
+//      1a) function pointers
+//      1b) member function pointer
+//      1c) member data pointer
+//      1d) callable class type
+//      1e) lambdas
+//    Categories 1a, 1b, and 1c are 'Nullable' types. Only objects of these
+//    types can be null. The other categories are not tested here.
+//  3) '__not_null(Callable)' is well formed when the call signature includes
+//      varargs.
+//  4) '__not_null(Callable)' works for Callable types with all aritys less
+//     than or equal to 3 in C++03.
+//  5) '__not_null(Callable)' works when 'Callable' is a member function
+//     pointer to a cv or ref qualified function type.
+//
+// Plan:
+//  1 For categories 1a, 1b and 1c define a set of
+//    'Callable' objects for this category. This set should include examples
+//    of arity 0, 1, 2 and possible 3 including versions with varargs as the
+//    last parameter.
+//
+//  2 For each 'Callable' object in categories 1a, 1b and 1c do the following.
+//
+//    1 Define a type 'std::function<Sig>' as 'F' where 'Sig' is compatible with
+//      the signature of the 'Callable' object.
+//
+//    2 Create an object of type 'F' using a null pointer of type 'Callable'.
+//      Check that 'F.target<Callable>()' is null.
+//
+//    3 Create an object of type 'F' that is not null. Check that
+//      'F.target<Callable>()' is not null and is equal to the original
+//      argument.
+
+#include <functional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+///////////////////////////////////////////////////////////////////////////////
+int foo() { return 42; }
+int foo(int) { return 42; }
+int foo(int, int) { return 42; }
+int foo(int, int, int) { return 42; }
+
+int foo(...) { return 42; }
+int foo(int, ...) { return 42; }
+int foo(int, int, ...) { return 42; }
+int foo(int, int, int, ...) { return 42; }
+
+///////////////////////////////////////////////////////////////////////////////
+struct MemFun03 {
+    int foo() { return 42; }
+    int foo() const { return 42; }
+    int foo() volatile { return 42; }
+    int foo() const volatile { return 42; }
+
+    int foo(int) { return 42; }
+    int foo(int) const { return 42; }
+    int foo(int) volatile { return 42; }
+    int foo(int) const volatile { return 42; }
+
+    int foo(int, int) { return 42; }
+    int foo(int, int) const { return 42; }
+    int foo(int, int) volatile { return 42; }
+    int foo(int, int) const volatile { return 42; }
+
+    int foo(int, int, int) { return 42; }
+    int foo(int, int, int) const { return 42; }
+    int foo(int, int, int) volatile { return 42; }
+    int foo(int, int, int) const volatile { return 42; }
+
+    int foo(...) { return 42; }
+    int foo(...) const { return 42; }
+    int foo(...) volatile { return 42; }
+    int foo(...) const volatile { return 42; }
+
+    int foo(int, ...) { return 42; }
+    int foo(int, ...) const { return 42; }
+    int foo(int, ...) volatile { return 42; }
+    int foo(int, ...) const volatile { return 42; }
+
+    int foo(int, int, ...) { return 42; }
+    int foo(int, int, ...) const { return 42; }
+    int foo(int, int, ...) volatile { return 42; }
+    int foo(int, int, ...) const volatile { return 42; }
+
+    int foo(int, int, int, ...) { return 42; }
+    int foo(int, int, int, ...) const { return 42; }
+    int foo(int, int, int, ...) volatile { return 42; }
+    int foo(int, int, int, ...) const volatile { return 42; }
+};
+
+#if TEST_STD_VER >= 11
+struct MemFun11 {
+    int foo() & { return 42; }
+    int foo() const & { return 42; }
+    int foo() volatile & { return 42; }
+    int foo() const volatile & { return 42; }
+
+    int foo(...) & { return 42; }
+    int foo(...) const & { return 42; }
+    int foo(...) volatile & { return 42; }
+    int foo(...) const volatile & { return 42; }
+
+    int foo() && { return 42; }
+    int foo() const && { return 42; }
+    int foo() volatile && { return 42; }
+    int foo() const volatile && { return 42; }
+
+    int foo(...) && { return 42; }
+    int foo(...) const && { return 42; }
+    int foo(...) volatile && { return 42; }
+    int foo(...) const volatile && { return 42; }
+};
+#endif // TEST_STD_VER >= 11
+
+struct MemData {
+    int foo;
+};
+
+// Create a non-null free function by taking the address of
+// &static_cast<Tp&>(foo);
+template <class Tp>
+struct Creator {
+    static Tp create() {
+        return &foo;
+    }
+};
+
+// Create a non-null member pointer.
+template <class Ret, class Class>
+struct Creator<Ret Class::*> {
+    typedef Ret Class::*ReturnType;
+    static ReturnType create() {
+        return &Class::foo;
+    }
+};
+
+template <class TestFn, class Fn>
+void test_imp() {
+    { // Check that the null value is detected
+        TestFn tf = nullptr;
+        std::function<Fn> f = tf;
+        assert(f.template target<TestFn>() == nullptr);
+    }
+    { // Check that the non-null value is detected.
+        TestFn tf = Creator<TestFn>::create();
+        assert(tf != nullptr);
+        std::function<Fn> f = tf;
+        assert(f.template target<TestFn>() != nullptr);
+        assert(*f.template target<TestFn>() == tf);
+    }
+}
+
+void test_func() {
+    test_imp<int(*)(), int()>();
+    test_imp<int(*)(...), int()>();
+    test_imp<int(*)(int), int(int)>();
+    test_imp<int(*)(int, ...), int(int)>();
+    test_imp<int(*)(int, int), int(int, int)>();
+    test_imp<int(*)(int, int, ...), int(int, int)>();
+    test_imp<int(*)(int, int, int), int(int, int, int)>();
+    test_imp<int(*)(int, int, int, ...), int(int, int, int)>();
+}
+
+void test_mf() {
+    test_imp<int(MemFun03::*)(), int(MemFun03&)>();
+    test_imp<int(MemFun03::*)(...), int(MemFun03&)>();
+    test_imp<int(MemFun03::*)() const, int(MemFun03&)>();
+    test_imp<int(MemFun03::*)(...) const, int(MemFun03&)>();
+    test_imp<int(MemFun03::*)() volatile, int(MemFun03&)>();
+    test_imp<int(MemFun03::*)(...) volatile, int(MemFun03&)>();
+    test_imp<int(MemFun03::*)() const volatile, int(MemFun03&)>();
+    test_imp<int(MemFun03::*)(...) const volatile, int(MemFun03&)>();
+
+    test_imp<int(MemFun03::*)(int), int(MemFun03&, int)>();
+    test_imp<int(MemFun03::*)(int, ...), int(MemFun03&, int)>();
+    test_imp<int(MemFun03::*)(int) const, int(MemFun03&, int)>();
+    test_imp<int(MemFun03::*)(int, ...) const, int(MemFun03&, int)>();
+    test_imp<int(MemFun03::*)(int) volatile, int(MemFun03&, int)>();
+    test_imp<int(MemFun03::*)(int, ...) volatile, int(MemFun03&, int)>();
+    test_imp<int(MemFun03::*)(int) const volatile, int(MemFun03&, int)>();
+    test_imp<int(MemFun03::*)(int, ...) const volatile, int(MemFun03&, int)>();
+
+    test_imp<int(MemFun03::*)(int, int), int(MemFun03&, int, int)>();
+    test_imp<int(MemFun03::*)(int, int, ...), int(MemFun03&, int, int)>();
+    test_imp<int(MemFun03::*)(int, int) const, int(MemFun03&, int, int)>();
+    test_imp<int(MemFun03::*)(int, int, ...) const, int(MemFun03&, int, int)>();
+    test_imp<int(MemFun03::*)(int, int) volatile, int(MemFun03&, int, int)>();
+    test_imp<int(MemFun03::*)(int, int, ...) volatile, int(MemFun03&, int, int)>();
+    test_imp<int(MemFun03::*)(int, int) const volatile, int(MemFun03&, int, int)>();
+    test_imp<int(MemFun03::*)(int, int, ...) const volatile, int(MemFun03&, int, int)>();
+
+#if TEST_STD_VER >= 11
+    test_imp<int(MemFun11::*)() &, int(MemFun11&)>();
+    test_imp<int(MemFun11::*)(...) &, int(MemFun11&)>();
+    test_imp<int(MemFun11::*)() const &, int(MemFun11&)>();
+    test_imp<int(MemFun11::*)(...) const &, int(MemFun11&)>();
+    test_imp<int(MemFun11::*)() volatile &, int(MemFun11&)>();
+    test_imp<int(MemFun11::*)(...) volatile &, int(MemFun11&)>();
+    test_imp<int(MemFun11::*)() const volatile &, int(MemFun11&)>();
+    test_imp<int(MemFun11::*)(...) const volatile &, int(MemFun11&)>();
+
+    test_imp<int(MemFun11::*)() &&, int(MemFun11&&)>();
+    test_imp<int(MemFun11::*)(...) &&, int(MemFun11&&)>();
+    test_imp<int(MemFun11::*)() const &&, int(MemFun11&&)>();
+    test_imp<int(MemFun11::*)(...) const &&, int(MemFun11&&)>();
+    test_imp<int(MemFun11::*)() volatile &&, int(MemFun11&&)>();
+    test_imp<int(MemFun11::*)(...) volatile &&, int(MemFun11&&)>();
+    test_imp<int(MemFun11::*)() const volatile &&, int(MemFun11&&)>();
+    test_imp<int(MemFun11::*)(...) const volatile &&, int(MemFun11&&)>();
+#endif
+}
+
+void test_md() {
+    test_imp<int MemData::*, int(MemData&)>();
+}
+
+int main() {
+    test_func();
+    test_mf();
+    test_md();
+}
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 e9ecfa5..cb45b30 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 main()
 {
+#if TEST_STD_VER <= 14
     {
     std::function<int(int)> f;
     f.assign(A(), test_allocator<A>());
@@ -57,4 +60,5 @@
     assert(f.target<int(*)(int)>() == 0);
     }
     assert(A::count == 0);
+#endif
 }
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/function_types.h b/test/std/utilities/function.objects/func.wrap/func.wrap.func/function_types.h
index 55eb80f..f152654 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/function_types.h
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/function_types.h
@@ -1,3 +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.
+//
+//===----------------------------------------------------------------------===//
+
 #ifndef FUNCTION_TYPES_H
 #define FUNCTION_TYPES_H
 
diff --git a/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.fail.cpp b/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.fail.cpp
index ba46946..a231606 100644
--- a/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.fail.cpp
+++ b/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.fail.cpp
@@ -13,6 +13,8 @@
 
 // reference_wrapper(T&&) = delete;
 
+// XFAIL: c++98, c++03
+
 #include <functional>
 #include <cassert>
 
diff --git a/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.fail.cpp b/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.fail.cpp
index 86a5696..0aad498 100644
--- a/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.fail.cpp
+++ b/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.fail.cpp
@@ -15,6 +15,8 @@
 
 // Don't allow binding to a temp
 
+// XFAIL: c++98, c++03
+
 #include <functional>
 
 struct A {};
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 61e0bfa..5a6a6fb 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>
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 7cd9f15..3e4dec1 100644
--- a/test/std/utilities/function.objects/unord.hash/integral.pass.cpp
+++ b/test/std/utilities/function.objects/unord.hash/integral.pass.cpp
@@ -21,6 +21,7 @@
 #include <functional>
 #include <cassert>
 #include <type_traits>
+#include <cstddef>
 #include <limits>
 
 template <class T>
@@ -57,4 +58,49 @@
     test<unsigned long>();
     test<long long>();
     test<unsigned long long>();
+
+//	LWG #2119
+    test<std::ptrdiff_t>();
+    test<size_t>();
+
+	test<int8_t>();
+	test<int16_t>();
+	test<int32_t>();
+	test<int64_t>();
+
+	test<int_fast8_t>();
+	test<int_fast16_t>();
+	test<int_fast32_t>();
+	test<int_fast64_t>();
+
+	test<int_least8_t>();
+	test<int_least16_t>();
+	test<int_least32_t>();
+	test<int_least64_t>();
+
+    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>();
+	test<uint_fast64_t>();
+
+	test<uint_least8_t>();
+	test<uint_least16_t>();
+	test<uint_least32_t>();
+	test<uint_least64_t>();
+
+    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 8ca5a96..0885314 100644
--- a/test/std/utilities/intseq/intseq.general/integer_seq.pass.cpp
+++ b/test/std/utilities/intseq/intseq.general/integer_seq.pass.cpp
@@ -19,7 +19,7 @@
 #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)... ); }
 
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 a795e90..5c789f5 100644
--- a/test/std/utilities/intseq/intseq.intseq/integer_seq.pass.cpp
+++ b/test/std/utilities/intseq/intseq.intseq/integer_seq.pass.cpp
@@ -19,6 +19,7 @@
 
 #include <utility>
 #include <type_traits>
+#include <cstddef>
 #include <cassert>
 
 int main()
@@ -27,7 +28,7 @@
 
 //  Make a few of sequences
     using int3    = std::integer_sequence<int, 3, 2, 1>;
-    using size1   = std::integer_sequence<size_t, 7>;
+    using size1   = std::integer_sequence<std::size_t, 7>;
     using ushort2 = std::integer_sequence<unsigned short, 4, 6>;
     using bool0   = std::integer_sequence<bool>;
     
@@ -35,7 +36,7 @@
     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, size_t>::value, "size1 type 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" );
diff --git a/test/std/utilities/intseq/intseq.make/make_integer_seq.fail.cpp b/test/std/utilities/intseq/intseq.make/make_integer_seq.fail.cpp
index 2dd6c17..af4a3c4 100644
--- a/test/std/utilities/intseq/intseq.make/make_integer_seq.fail.cpp
+++ b/test/std/utilities/intseq/intseq.make/make_integer_seq.fail.cpp
@@ -12,19 +12,23 @@
 // template<class T, T N>
 //   using make_integer_sequence = integer_sequence<T, 0, 1, ..., N-1>;
 
+// UNSUPPORTED: c++98, c++03, c++11
+
 #include <utility>
 #include <type_traits>
 #include <cassert>
 
+#include "test_macros.h"
+
 int main()
 {
-#if _LIBCPP_STD_VER > 11
+  typedef std::make_integer_sequence<int, -3> MakeSeqT;
 
-    std::make_integer_sequence<int, -3>::value_type i;
-
+  // std::make_integer_sequence is implemented using a compiler builtin if available.
+  // this builtin has different diagnostic messages than the fallback implementation.
+#if TEST_HAS_BUILTIN(__make_integer_seq) && !defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
+    MakeSeqT i; // expected-error@utility:* {{integer sequences must have non-negative sequence length}}
 #else
-
-X
-
-#endif  // _LIBCPP_STD_VER > 11
+    MakeSeqT i; // expected-error@utility:* {{static_assert failed "std::make_integer_sequence must have a non-negative sequence length"}}
+#endif
 }
diff --git a/test/std/utilities/intseq/intseq.make/make_integer_seq.pass.cpp b/test/std/utilities/intseq/intseq.make/make_integer_seq.pass.cpp
index 7e82b94..9bfc5f3 100644
--- a/test/std/utilities/intseq/intseq.make/make_integer_seq.pass.cpp
+++ b/test/std/utilities/intseq/intseq.make/make_integer_seq.pass.cpp
@@ -12,14 +12,14 @@
 // template<class T, T N>
 //   using make_integer_sequence = integer_sequence<T, 0, 1, ..., N-1>;
 
+// UNSUPPORTED: c++98, c++03, c++11
+
 #include <utility>
 #include <type_traits>
 #include <cassert>
 
 int main()
 {
-#if _LIBCPP_STD_VER > 11
-
     static_assert(std::is_same<std::make_integer_sequence<int, 0>, std::integer_sequence<int>>::value, "");
     static_assert(std::is_same<std::make_integer_sequence<int, 1>, std::integer_sequence<int, 0>>::value, "");
     static_assert(std::is_same<std::make_integer_sequence<int, 2>, std::integer_sequence<int, 0, 1>>::value, "");
@@ -29,6 +29,4 @@
     static_assert(std::is_same<std::make_integer_sequence<unsigned long long, 1>, std::integer_sequence<unsigned long long, 0>>::value, "");
     static_assert(std::is_same<std::make_integer_sequence<unsigned long long, 2>, std::integer_sequence<unsigned long long, 0, 1>>::value, "");
     static_assert(std::is_same<std::make_integer_sequence<unsigned long long, 3>, std::integer_sequence<unsigned long long, 0, 1, 2>>::value, "");
-
-#endif  // _LIBCPP_STD_VER > 11
 }
diff --git a/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.fail.cpp b/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.fail.cpp
new file mode 100644
index 0000000..b6431b5
--- /dev/null
+++ b/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.fail.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The 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 T, T N>
+//   using make_integer_sequence = integer_sequence<T, 0, 1, ..., N-1>;
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+#define _LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE
+#include "make_integer_seq.fail.cpp"
diff --git a/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.pass.cpp b/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.pass.cpp
new file mode 100644
index 0000000..c75d20b
--- /dev/null
+++ b/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.pass.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The 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 T, T N>
+//   using make_integer_sequence = integer_sequence<T, 0, 1, ..., N-1>;
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+#define _LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE
+#include "make_integer_seq.pass.cpp"
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 1fa7291..352c7c8 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
@@ -45,12 +45,12 @@
     {
         A<int> a;
         assert(std::allocator_traits<A<int> >::max_size(a) ==
-               std::numeric_limits<std::size_t>::max());
+               std::numeric_limits<std::size_t>::max() / sizeof(int));
     }
     {
         const A<int> a = {};
         assert(std::allocator_traits<A<int> >::max_size(a) ==
-               std::numeric_limits<std::size_t>::max());
+               std::numeric_limits<std::size_t>::max() / sizeof(int));
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
     {
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 20348d2..10fbfe1 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 @@
     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 4b4045a..8365d22 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 @@
     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 085c911..dc7a65e 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,6 +45,15 @@
     struct const_void_pointer {};
 };
 
+
+template <class T>
+struct D
+{
+    typedef T value_type;
+private:
+    typedef void difference_type;
+};
+
 namespace std
 {
 
@@ -59,4 +70,7 @@
     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 60ba094..ff1ae2c 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 @@
     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 604e890..0112ab3 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 @@
     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 1d2b186..64de15c 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 @@
     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 6730d1a..a62336f 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 @@
     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 50611b9..8097a66 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 @@
     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 e9c175f..00ed507 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 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 @@
                    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 74cd347..2c36237 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 @@
     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 0477d99..bd32bc3 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 @@
     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 @@
     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 0000000..dc0bdd0
--- /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.members/construct.pass.cpp b/test/std/utilities/memory/default.allocator/allocator.members/construct.pass.cpp
index 40c44d9..28dadd8 100644
--- a/test/std/utilities/memory/default.allocator/allocator.members/construct.pass.cpp
+++ b/test/std/utilities/memory/default.allocator/allocator.members/construct.pass.cpp
@@ -38,8 +38,6 @@
 #if TEST_STD_VER >= 11
 class move_only
 {
-    int data;
-
     move_only(const move_only&) = delete;
     move_only& operator=(const move_only&)= delete;
 
@@ -49,6 +47,10 @@
 
     move_only() {++move_only_constructed;}
     ~move_only() {--move_only_constructed;}
+
+public:
+    int data; // unused other than to make sizeof(move_only) == sizeof(int).
+              // but public to suppress "-Wunused-private-field"
 };
 #endif // TEST_STD_VER >= 11
 
diff --git a/test/std/utilities/memory/default.allocator/allocator.members/max_size.pass.cpp b/test/std/utilities/memory/default.allocator/allocator.members/max_size.pass.cpp
index 6ec9339..1010938 100644
--- a/test/std/utilities/memory/default.allocator/allocator.members/max_size.pass.cpp
+++ b/test/std/utilities/memory/default.allocator/allocator.members/max_size.pass.cpp
@@ -22,6 +22,6 @@
 int main()
 {
     const std::allocator<int> a;
-    std::size_t M = a.max_size() * sizeof(int);
-    assert(M > 0xFFFF && M <= std::numeric_limits<std::size_t>::max());
+    std::size_t M = a.max_size();
+    assert(M > 0xFFFF && M <= (std::numeric_limits<std::size_t>::max() / sizeof(int)));
 }
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 5a8f7a2..588227f 100644
--- a/test/std/utilities/memory/default.allocator/allocator_pointers.pass.cpp
+++ b/test/std/utilities/memory/default.allocator/allocator_pointers.pass.cpp
@@ -36,7 +36,10 @@
 {
      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 +73,10 @@
 {
      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, "");
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 4efe613..27b2d08 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 @@
     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 0ee1e8c..afa9f7f 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
@@ -40,10 +40,27 @@
 {
 };
 
+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 4a1455c..74c1249 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 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 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 0000000..a371f8e
--- /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 f431335..8bb8183 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <memory>
 
 // template <class InputIterator, class ForwardIterator>
@@ -20,13 +21,15 @@
 struct B
 {
     static int count_;
+    static int population_;
     int data_;
-    explicit B() : data_(1) {}
-    B(const B& b) {if (++count_ == 3) throw 1; data_ = b.data_;}
-    ~B() {data_ = 0;}
+    explicit B() : data_(1) { ++population_; }
+    B(const B& b) {if (++count_ == 3) throw 1; data_ = b.data_; ++population_; }
+    ~B() {data_ = 0; --population_; }
 };
 
 int B::count_ = 0;
+int B::population_ = 0;
 
 struct Nasty
 {
@@ -45,6 +48,7 @@
     char pool[sizeof(B)*N] = {0};
     B* bp = (B*)pool;
     B b[N];
+    assert(B::population_ == N);
     try
     {
         std::uninitialized_copy(b, b+N, bp);
@@ -52,14 +56,15 @@
     }
     catch (...)
     {
-        for (int i = 0; i < N; ++i)
-            assert(bp[i].data_ == 0);
+        assert(B::population_ == N);
     }
     B::count_ = 0;
     std::uninitialized_copy(b, b+2, bp);
     for (int i = 0; i < 2; ++i)
         assert(bp[i].data_ == 1);
+	assert(B::population_ == N + 2);
     }
+
     {
     const int N = 5;
     char pool[sizeof(Nasty)*N] = {0};
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 3b2007b..ae438ef 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <memory>
 
 // template <class InputIterator, class Size, class ForwardIterator>
@@ -20,12 +21,14 @@
 struct B
 {
     static int count_;
+    static int population_;
     int data_;
-    explicit B() : data_(1) {}
-    B(const B& b) {if (++count_ == 3) throw 1; data_ = b.data_;}
-    ~B() {data_ = 0;}
+    explicit B() : data_(1) { ++population_; }
+    B(const B& b) {if (++count_ == 3) throw 1; data_ = b.data_; ++population_; }
+    ~B() {data_ = 0; --population_; }
 };
 
+int B::population_ = 0;
 int B::count_ = 0;
 
 struct Nasty
@@ -45,6 +48,7 @@
     char pool[sizeof(B)*N] = {0};
     B* bp = (B*)pool;
     B b[N];
+    assert(B::population_ == N);
     try
     {
         std::uninitialized_copy_n(b, 5, bp);
@@ -52,14 +56,15 @@
     }
     catch (...)
     {
-        for (int i = 0; i < N; ++i)
-            assert(bp[i].data_ == 0);
+        assert(B::population_ == N);
     }
     B::count_ = 0;
     std::uninitialized_copy_n(b, 2, bp);
     for (int i = 0; i < 2; ++i)
         assert(bp[i].data_ == 1);
+    assert(B::population_ == N + 2);
     }
+
     {
     const int N = 5;
     char pool[sizeof(Nasty)*N] = {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 d2b1dfa..22aa8b9 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <memory>
 
 // template <class ForwardIterator, class Size, class T>
@@ -19,13 +20,15 @@
 struct B
 {
     static int count_;
+    static int population_;
     int data_;
-    explicit B() : data_(1) {}
-    B(const B& b) {if (++count_ == 3) throw 1; data_ = b.data_;}
-    ~B() {data_ = 0;}
+    explicit B() : data_(1) { ++population_; }
+    B(const B& b) {if (++count_ == 3) throw 1; data_ = b.data_; ++population_; }
+    ~B() {data_ = 0; --population_; }
 };
 
 int B::count_ = 0;
+int B::population_ = 0;
 
 struct Nasty
 {
@@ -43,6 +46,7 @@
     const int N = 5;
     char pool[sizeof(B)*N] = {0};
     B* bp = (B*)pool;
+    assert(B::population_ == 0);
     try
     {
         std::uninitialized_fill_n(bp, 5, B());
@@ -50,14 +54,14 @@
     }
     catch (...)
     {
-        for (int i = 0; i < N; ++i)
-            assert(bp[i].data_ == 0);
+        assert(B::population_ == 0);
     }
     B::count_ = 0;
     B* r = std::uninitialized_fill_n(bp, 2, B());
     assert(r == bp + 2);
     for (int i = 0; i < 2; ++i)
         assert(bp[i].data_ == 1);
+    assert(B::population_ == 2);
     }
     {
     {
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 47cabdf..95c45dd 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <memory>
 
 // template <class ForwardIterator, class T>
@@ -20,13 +21,15 @@
 struct B
 {
     static int count_;
+    static int population_;
     int data_;
-    explicit B() : data_(1) {}
-    B(const B& b) {if (++count_ == 3) throw 1; data_ = b.data_;}
-    ~B() {data_ = 0;}
+    explicit B() : data_(1) { ++population_; }
+    B(const B& b) {if (++count_ == 3) throw 1; data_ = b.data_; ++population_; }
+    ~B() {data_ = 0; --population_; }
 };
 
 int B::count_ = 0;
+int B::population_ = 0;
 
 struct Nasty
 {
@@ -44,6 +47,7 @@
     const int N = 5;
     char pool[sizeof(B)*N] = {0};
     B* bp = (B*)pool;
+    assert(B::population_ == 0);
     try
     {
         std::uninitialized_fill(bp, bp+N, B());
@@ -51,13 +55,13 @@
     }
     catch (...)
     {
-        for (int i = 0; i < N; ++i)
-            assert(bp[i].data_ == 0);
+        assert(B::population_ == 0);
     }
     B::count_ = 0;
     std::uninitialized_fill(bp, bp+2, B());
     for (int i = 0; i < 2; ++i)
         assert(bp[i].data_ == 1);
+    assert(B::population_ == 2);
     }
     {
     const int N = 5;
diff --git a/test/std/utilities/memory/storage.iterator/raw_storag_iterator.pass.cpp b/test/std/utilities/memory/storage.iterator/raw_storag_iterator.pass.cpp
deleted file mode 100644
index f77d6c7..0000000
--- a/test/std/utilities/memory/storage.iterator/raw_storag_iterator.pass.cpp
+++ /dev/null
@@ -1,44 +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.
-//
-//===----------------------------------------------------------------------===//
-
-// raw_storage_iterator
-
-#include <memory>
-#include <type_traits>
-#include <cassert>
-
-int A_constructed = 0;
-
-struct A
-{
-    int data_;
-public:
-    explicit A(int i) : data_(i) {++A_constructed;}
-
-    A(const A& a) : data_(a.data_)  {++A_constructed;}
-    ~A() {--A_constructed; data_ = 0;}
-
-    bool operator==(int i) const {return data_ == i;}
-};
-
-int main()
-{
-    typedef std::aligned_storage<3*sizeof(A), std::alignment_of<A>::value>::type
-            Storage;
-    Storage buffer;
-    std::raw_storage_iterator<A*, A> it((A*)&buffer);
-    assert(A_constructed == 0);
-    for (int i = 0; i < 3; ++i)
-    {
-        *it++ = A(i+1);
-        A* ap = (A*)&buffer + i;
-        assert(*ap == i+1);
-        assert(A_constructed == i+1);
-    }
-}
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
similarity index 100%
rename from test/std/utilities/memory/storage.iterator/raw_storag_iterator.base.pass.cpp
rename to test/std/utilities/memory/storage.iterator/raw_storage_iterator.base.pass.cpp
diff --git a/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp
new file mode 100644
index 0000000..9148024
--- /dev/null
+++ b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.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.
+//
+//===----------------------------------------------------------------------===//
+
+// raw_storage_iterator
+
+#include <memory>
+#include <type_traits>
+#include <cassert>
+
+#include <MoveOnly.h>
+
+int A_constructed = 0;
+
+struct A
+{
+    int data_;
+public:
+    explicit A(int i) : data_(i) {++A_constructed;}
+
+    A(const A& a) : data_(a.data_)  {++A_constructed;}
+    ~A() {--A_constructed; data_ = 0;}
+
+    bool operator==(int i) const {return data_ == i;}
+};
+
+int main()
+{
+    {
+    typedef A S;
+    typedef std::aligned_storage<3*sizeof(S), std::alignment_of<S>::value>::type
+            Storage;
+    Storage buffer;
+    std::raw_storage_iterator<S*, S> it((S*)&buffer);
+    assert(A_constructed == 0);
+    for (int i = 0; i < 3; ++i)
+    {
+        *it++ = S(i+1);
+        S* ap = (S*)&buffer + i;
+        assert(*ap == i+1);
+        assert(A_constructed == i+1);
+    }
+    }
+#if _LIBCPP_STD_VER >= 14
+    {
+    typedef MoveOnly S;
+    typedef std::aligned_storage<3*sizeof(S), std::alignment_of<S>::value>::type
+            Storage;
+    Storage buffer;
+    std::raw_storage_iterator<S*, S> it((S*)&buffer);
+    S m{1};
+    *it++ = std::move(m);
+    assert(m.get() == 0); // moved from
+    S *ap = (S*) &buffer;
+    assert(ap->get() == 1); // original value
+    }
+#endif
+}
diff --git a/test/std/utilities/memory/unique.ptr/deleter.h b/test/std/utilities/memory/unique.ptr/deleter.h
index ab13c65..1d8e19d 100644
--- a/test/std/utilities/memory/unique.ptr/deleter.h
+++ b/test/std/utilities/memory/unique.ptr/deleter.h
@@ -112,7 +112,6 @@
 
     ~Deleter() {assert(state_ >= 0); state_ = -1;}
 
-private:
     template <class U>
         Deleter(Deleter<U> d,
             typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
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 0000000..a611b1a
--- /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 2d62bcc..2b0b5f0 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 @@
     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.single/pointer_type.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/pointer_type.pass.cpp
index 8721062..380f2e1 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 @@
     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.single/unique.ptr.single.asgn/move01.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move01.fail.cpp
index 57724ae..87cfb72 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move01.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move01.fail.cpp
@@ -14,25 +14,16 @@
 // Test unique_ptr move assignment
 
 #include <memory>
-#include <cassert>
+
+#include "test_macros.h"
 
 // Can't copy from lvalue
-
-struct A
-{
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    ~A() {--count;}
-};
-
-int A::count = 0;
-
 int main()
 {
-    {
-    std::unique_ptr<A> s(new A);
-    std::unique_ptr<A> s2;
-    s2 = s;
-    }
+    std::unique_ptr<int> s, s2;
+#if TEST_STD_VER >= 11
+    s2 = s; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+#else
+    s2 = s; // expected-error {{'operator=' is a private member}}
+#endif
 }
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move02.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move02.fail.cpp
index 5046fd8..9cea12b 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move02.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move02.fail.cpp
@@ -14,25 +14,20 @@
 // Test unique_ptr move assignment
 
 #include <memory>
-#include <cassert>
+
+#include "test_macros.h"
 
 // Can't copy from const lvalue
 
-struct A
-{
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    ~A() {--count;}
-};
-
-int A::count = 0;
-
 int main()
 {
-    {
-    const std::unique_ptr<A> s(new A);
-    std::unique_ptr<A> s2;
-    s2 = s;
-    }
+    const std::unique_ptr<int> s(new int);
+    std::unique_ptr<int> s2;
+#if TEST_STD_VER >= 11
+    s2 = s; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+#else
+    // NOTE: The error says "constructor" because the assignment operator takes
+    // 's' by value and attempts to copy construct it.
+    s2 = s; // expected-error {{no matching constructor for initialization}}
+#endif
 }
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move03.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move03.fail.cpp
index aa4fdb8..05a057f 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move03.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move03.fail.cpp
@@ -14,43 +14,20 @@
 // Test unique_ptr move assignment
 
 #include <memory>
-#include <cassert>
+
+#include "test_macros.h"
+
+struct Deleter {
+    void operator()(int* p) {delete p;}
+};
 
 // Can't copy from lvalue
-
-struct A
-{
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    ~A() {--count;}
-};
-
-int A::count = 0;
-
-class Deleter
-{
-    int state_;
-
-public:
-
-    Deleter() : state_(5) {}
-
-    int state() const {return state_;}
-
-    void operator()(A* p) {delete p;}
-};
-
 int main()
 {
-    {
-    std::unique_ptr<A, Deleter> s(new A);
-    A* p = s.get();
-    std::unique_ptr<A, Deleter> s2;
-    s2 = s;
-    assert(s2.get() == p);
-    assert(s.get() == 0);
-    assert(A::count == 1);
-    }
-    assert(A::count == 0);
+    std::unique_ptr<int, Deleter> s, s2;
+#if TEST_STD_VER >= 11
+    s2 = s; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+#else
+    s2 = s; // expected-error {{'operator=' is a private member}}
+#endif
 }
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move04.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move04.fail.cpp
index e0d7c89..24703ec 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move04.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move04.fail.cpp
@@ -11,46 +11,26 @@
 
 // unique_ptr
 
-// Test unique_ptr move ctor
+// Test unique_ptr move assignment
 
 #include <memory>
-#include <cassert>
 
-// test move ctor.  Can't copy from const lvalue
+#include "test_macros.h"
 
-struct A
-{
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    ~A() {--count;}
+struct Deleter {
+    void operator()(int* p) {delete p;}
 };
 
-int A::count = 0;
-
-class Deleter
-{
-    int state_;
-
-public:
-
-    Deleter() : state_(5) {}
-
-    int state() const {return state_;}
-
-    void operator()(A* p) {delete p;}
-};
-
+// Can't copy from a const lvalue
 int main()
 {
-    {
-    const std::unique_ptr<A, Deleter> s(new A);
-    A* p = s.get();
-    std::unique_ptr<A, Deleter> s2;
-    s2 = s;
-    assert(s2.get() == p);
-    assert(s.get() == 0);
-    assert(A::count == 1);
-    }
-    assert(A::count == 0);
+    const std::unique_ptr<int, Deleter> s(new int);
+    std::unique_ptr<int, Deleter> s2;
+#if TEST_STD_VER >= 11
+    s2 = s; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+#else
+    // NOTE: The error says "constructor" because the assignment operator takes
+    // 's' by value and attempts to copy construct it.
+    s2 = s; // expected-error {{no matching constructor for initialization}}
+#endif
 }
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert.pass.cpp
new file mode 100644
index 0000000..4c4a320
--- /dev/null
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// Test unique_ptr converting move assignment
+
+#include <memory>
+#include <utility>
+#include <cassert>
+
+#include "../../deleter.h"
+
+struct A
+{
+    static int count;
+    A() {++count;}
+    A(const A&) {++count;}
+    virtual ~A() {--count;}
+};
+
+int A::count = 0;
+
+struct B
+    : public A
+{
+    static int count;
+    B() {++count;}
+    B(const B&) {++count;}
+    virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+
+template <class APtr, class BPtr>
+void testAssign(APtr& aptr, BPtr& bptr) {
+    A* p = bptr.get();
+    assert(A::count == 2);
+    aptr = std::move(bptr);
+    assert(aptr.get() == p);
+    assert(bptr.get() == 0);
+    assert(A::count == 1);
+    assert(B::count == 1);
+}
+
+template <class LHS, class RHS>
+void checkDeleter(LHS& lhs, RHS& rhs, int LHSState, int RHSState) {
+    assert(lhs.get_deleter().state() == LHSState);
+    assert(rhs.get_deleter().state() == RHSState);
+}
+
+int main()
+{
+    {
+        std::unique_ptr<B> bptr(new B);
+        std::unique_ptr<A> aptr(new A);
+        testAssign(aptr, bptr);
+    }
+    assert(A::count == 0);
+    assert(B::count == 0);
+    {
+        Deleter<B> del(42);
+        std::unique_ptr<B, Deleter<B> > bptr(new B, std::move(del));
+        std::unique_ptr<A, Deleter<A> > aptr(new A);
+        testAssign(aptr, bptr);
+        checkDeleter(aptr, bptr, 42, 0);
+    }
+    assert(A::count == 0);
+    assert(B::count == 0);
+    {
+        CDeleter<A> adel(6);
+        CDeleter<B> bdel(42);
+        std::unique_ptr<B, CDeleter<B>&> bptr(new B, bdel);
+        std::unique_ptr<A, CDeleter<A>&> aptr(new A, adel);
+        testAssign(aptr, bptr);
+        checkDeleter(aptr, bptr, 42, 42);
+    }
+    assert(A::count == 0);
+    assert(B::count == 0);
+}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert01.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert01.fail.cpp
index 3fd2cbc..816a598 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert01.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert01.fail.cpp
@@ -14,44 +14,29 @@
 // Test unique_ptr converting move assignment
 
 #include <memory>
-#include <utility>
-#include <cassert>
 
-// Can't assign from lvalue
+#include "test_macros.h"
 
 struct A
 {
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    virtual ~A() {--count;}
+    A() {}
+    virtual ~A() {}
 };
 
-int A::count = 0;
-
-struct B
-    : public A
+struct B : public A
 {
-    static int count;
-    B() {++count;}
-    B(const B&) {++count;}
-    virtual ~B() {--count;}
 };
 
-int B::count = 0;
-
+// Can't assign from lvalue
 int main()
 {
-    {
-    std::unique_ptr<B> s(new B);
-    A* p = s.get();
+    std::unique_ptr<B> s;
     std::unique_ptr<A> s2;
-    s2 = s;
-    assert(s2.get() == p);
-    assert(s.get() == 0);
-    assert(A::count == 1);
-    assert(B::count == 1);
-    }
-    assert(A::count == 0);
-    assert(B::count == 0);
+#if TEST_STD_VER >= 11
+    s2 = s; // expected-error {{no viable overloaded '='}}
+#else
+    // NOTE: The move-semantic emulation creates an ambiguous overload set
+    // so that assignment from an lvalue does not compile
+    s2 = s; // expected-error {{use of overloaded operator '=' is ambiguous}}
+#endif
 }
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert01.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert01.pass.cpp
deleted file mode 100644
index 989f594..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert01.pass.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr converting move assignment
-
-#include <memory>
-#include <utility>
-#include <cassert>
-
-struct A
-{
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
-    : public A
-{
-    static int count;
-    B() {++count;}
-    B(const B&) {++count;}
-    virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-int main()
-{
-    {
-    std::unique_ptr<B> s(new B);
-    A* p = s.get();
-    std::unique_ptr<A> s2(new A);
-    assert(A::count == 2);
-    s2 = std::move(s);
-    assert(s2.get() == p);
-    assert(s.get() == 0);
-    assert(A::count == 1);
-    assert(B::count == 1);
-    }
-    assert(A::count == 0);
-    assert(B::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert02.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert02.fail.cpp
index 0f90060..1ddf1d8 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert02.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert02.fail.cpp
@@ -14,48 +14,30 @@
 // Test unique_ptr converting move assignment
 
 #include <memory>
-#include <utility>
-#include <cassert>
 
+#include "test_macros.h"
 #include "../../deleter.h"
 
-// Can't assign from lvalue
-
 struct A
 {
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    virtual ~A() {--count;}
+    A() {}
+    virtual ~A() {}
 };
 
-int A::count = 0;
-
-struct B
-    : public A
+struct B : public A
 {
-    static int count;
-    B() {++count;}
-    B(const B&) {++count;}
-    virtual ~B() {--count;}
 };
 
-int B::count = 0;
-
+// Can't assign from lvalue
 int main()
 {
-    {
-    std::unique_ptr<B, Deleter<B> > s(new B);
-    A* p = s.get();
+    std::unique_ptr<B, Deleter<B> > s;
     std::unique_ptr<A, Deleter<A> > s2;
-    s2 = s;
-    assert(s2.get() == p);
-    assert(s.get() == 0);
-    assert(A::count == 1);
-    assert(B::count == 1);
-    assert(s2.get_deleter().state() == 5);
-    assert(s.get_deleter().state() == 0);
-    }
-    assert(A::count == 0);
-    assert(B::count == 0);
+#if TEST_STD_VER >= 11
+    s2 = s; // expected-error {{no viable overloaded '='}}
+#else
+    // NOTE: The move-semantic emulation creates an ambiguous overload set
+    // so that assignment from an lvalue does not compile
+    s2 = s; // expected-error {{use of overloaded operator '=' is ambiguous}}
+#endif
 }
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert02.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert02.pass.cpp
deleted file mode 100644
index a448c77..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert02.pass.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr converting move assignment
-
-#include <memory>
-#include <utility>
-#include <cassert>
-
-#include "../../deleter.h"
-
-struct A
-{
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
-    : public A
-{
-    static int count;
-    B() {++count;}
-    B(const B&) {++count;}
-    virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-int main()
-{
-    {
-    std::unique_ptr<B, Deleter<B> > s(new B, Deleter<B>(5));
-    A* p = s.get();
-    std::unique_ptr<A, Deleter<A> > s2(new A);
-    assert(A::count == 2);
-    s2 = std::move(s);
-    assert(s2.get() == p);
-    assert(s.get() == 0);
-    assert(A::count == 1);
-    assert(B::count == 1);
-    assert(s2.get_deleter().state() == 5);
-    assert(s.get_deleter().state() == 0);
-    }
-    assert(A::count == 0);
-    assert(B::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert03.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert03.fail.cpp
index f35af9f..570c1c4 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert03.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert03.fail.cpp
@@ -16,47 +16,32 @@
 // Can't assign from lvalue
 
 #include <memory>
-#include <utility>
-#include <cassert>
 
+#include "test_macros.h"
 #include "../../deleter.h"
 
 struct A
 {
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    virtual ~A() {--count;}
+    A() {}
+    virtual ~A() {}
 };
 
-int A::count = 0;
-
-struct B
-    : public A
+struct B : public A
 {
-    static int count;
-    B() {++count;}
-    B(const B&) {++count;}
-    virtual ~B() {--count;}
 };
 
-int B::count = 0;
-
+// Can't assign from lvalue
 int main()
 {
-    {
-    Deleter<B> db(5);
-    std::unique_ptr<B, Deleter<B>&> s(new B, db);
-    A* p = s.get();
-    Deleter<A> da(6);
-    std::unique_ptr<A, Deleter<A>&> s2(new A, da);
-    s2 = s;
-    assert(s2.get() == p);
-    assert(s.get() == 0);
-    assert(A::count == 1);
-    assert(B::count == 1);
-    assert(s2.get_deleter().state() == 5);
-    }
-    assert(A::count == 0);
-    assert(B::count == 0);
+    Deleter<B> db;
+    std::unique_ptr<B, Deleter<B>& > s(new B, db);
+    Deleter<A> da;
+    std::unique_ptr<A, Deleter<A> &> s2(new A, da);
+#if TEST_STD_VER >= 11
+    s2 = s; // expected-error {{no viable overloaded '='}}
+#else
+    // NOTE: The move-semantic emulation creates an ambiguous overload set
+    // so that assignment from an lvalue does not compile
+    s2 = s; // expected-error {{use of overloaded operator '=' is ambiguous}}
+#endif
 }
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert03.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert03.pass.cpp
deleted file mode 100644
index 9aea81a..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert03.pass.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr converting move assignment
-
-// test converting move assignment with reference deleters
-
-#include <memory>
-#include <utility>
-#include <cassert>
-
-#include "../../deleter.h"
-
-struct A
-{
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
-    : public A
-{
-    static int count;
-    B() {++count;}
-    B(const B&) {++count;}
-    virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-int main()
-{
-    {
-    CDeleter<B> db(5);
-    std::unique_ptr<B, CDeleter<B>&> s(new B, db);
-    A* p = s.get();
-    CDeleter<A> da(6);
-    std::unique_ptr<A, CDeleter<A>&> s2(new A, da);
-    s2 = std::move(s);
-    assert(s2.get() == p);
-    assert(s.get() == 0);
-    assert(A::count == 1);
-    assert(B::count == 1);
-    assert(s.get_deleter().state() == 5);
-    assert(s2.get_deleter().state() == 5);
-    }
-    assert(A::count == 0);
-    assert(B::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert04.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert04.fail.cpp
index dba901b..2ebc33d 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert04.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert04.fail.cpp
@@ -14,44 +14,30 @@
 // Test unique_ptr converting move assignment
 
 #include <memory>
-#include <utility>
-#include <cassert>
 
-// Can't assign from const lvalue
+#include "test_macros.h"
+#include "../../deleter.h"
 
 struct A
 {
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    virtual ~A() {--count;}
+    A() {}
+    virtual ~A() {}
 };
 
-int A::count = 0;
-
-struct B
-    : public A
+struct B : public A
 {
-    static int count;
-    B() {++count;}
-    B(const B&) {++count;}
-    virtual ~B() {--count;}
 };
 
-int B::count = 0;
-
+// Can't assign from lvalue
 int main()
 {
-    {
     const std::unique_ptr<B> s(new B);
-    A* p = s.get();
     std::unique_ptr<A> s2;
-    s2 = s;
-    assert(s2.get() == p);
-    assert(s.get() == 0);
-    assert(A::count == 1);
-    assert(B::count == 1);
-    }
-    assert(A::count == 0);
-    assert(B::count == 0);
+#if TEST_STD_VER >= 11
+    s2 = s; // expected-error {{no viable overloaded '='}}
+#else
+    // NOTE: The error says "constructor" because the assignment operator takes
+    // 's' by value and attempts to copy construct it.
+    s2 = s; // expected-error {{no matching constructor for initialization}}
+#endif
 }
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert13.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert13.fail.cpp
index 56ab43c..4126484 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert13.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.asgn/move_convert13.fail.cpp
@@ -32,5 +32,5 @@
 {
     std::unique_ptr<A[], Deleter> s;
     std::unique_ptr<A, Deleter> s2;
-    s2 = std::move(s);
+    s2 = std::move(s); // expected-error {{no viable overloaded '='}}
 }
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/auto_pointer.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/auto_pointer.pass.cpp
index 1ce1838..7c3ac46 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/auto_pointer.pass.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/auto_pointer.pass.cpp
@@ -7,17 +7,21 @@
 //
 //===----------------------------------------------------------------------===//
 
+// libc++ cannot safely provide the auto_ptr constructor without rvalue
+// references.
+// XFAIL: c++98, c++03
+
 // <memory>
 
 // unique_ptr
 
-// Test unique_ptr(pointer) ctor
+// template <class U> unique_ptr(auto_ptr<U>&&) noexcept
 
 #include <memory>
 #include <utility>
 #include <cassert>
 
-// template <class U> explicit unique_ptr(auto_ptr<U>&);
+#include "test_macros.h"
 
 struct A
 {
@@ -65,4 +69,12 @@
     }
     assert(A::count == 0);
     assert(B::count == 0);
+#if TEST_STD_VER >= 11
+    {
+        static_assert(std::is_nothrow_constructible<
+            std::unique_ptr<A>,
+            std::auto_ptr<B>&&
+        >::value, "");
+    }
+#endif
 }
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert.pass.cpp
index 7136253..f00fcfe 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert.pass.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert.pass.cpp
@@ -18,6 +18,7 @@
 // XFAIL: c++98, c++03
 
 
+
 #include <memory>
 #include <type_traits>
 #include <utility>
@@ -50,126 +51,121 @@
 
 int B::count = 0;
 
-template <class OrigPtr, class NewPtr>
-void checkDeleter(OrigPtr& O, NewPtr& N, int OrigState, int NewState) {
-    typedef typename NewPtr::deleter_type NewDel;
-    if (std::is_reference<NewDel>::value) {
-      O.get_deleter().set_state(42);
-      assert(O.get_deleter().state() == 42);
-      assert(N.get_deleter().state() == 42);
-      O.get_deleter().set_state(99);
-      assert(O.get_deleter().state() == 99);
-      assert(N.get_deleter().state() == 99);
-    } else {
-      // TODO(EricWF) Enable this?
-      // assert(OrigState != NewState);
-      assert(O.get_deleter().state() == OrigState);
-      assert(N.get_deleter().state() == NewState);
-    }
+
+template <class LHS, class RHS>
+void checkReferenceDeleter(LHS& lhs, RHS& rhs) {
+    typedef typename LHS::deleter_type NewDel;
+    static_assert(std::is_reference<NewDel>::value, "");
+    rhs.get_deleter().set_state(42);
+    assert(rhs.get_deleter().state() == 42);
+    assert(lhs.get_deleter().state() == 42);
+    lhs.get_deleter().set_state(99);
+    assert(lhs.get_deleter().state() == 99);
+    assert(rhs.get_deleter().state() == 99);
 }
 
-template <class APtr, class BPtr>
-void testMoveConvertExplicit()
-{
-    { // Test explicit constructor
-        BPtr s(new B);
-        A* p = s.get();
-        APtr s2(std::move(s));
-        assert(s2.get() == p);
-        assert(s.get() == 0);
-        assert(A::count == 1);
-        assert(B::count == 1);
-    }
+template <class LHS, class RHS>
+void checkDeleter(LHS& lhs, RHS& rhs, int LHSVal, int RHSVal) {
+    assert(lhs.get_deleter().state() == LHSVal);
+    assert(rhs.get_deleter().state() == RHSVal);
+}
+
+template <class LHS, class RHS>
+void checkCtor(LHS& lhs, RHS& rhs, A* RHSVal) {
+    assert(lhs.get() == RHSVal);
+    assert(rhs.get() == nullptr);
+    assert(A::count == 1);
+    assert(B::count == 1);
+}
+
+void checkNoneAlive() {
     assert(A::count == 0);
     assert(B::count == 0);
 }
 
-template <class APtr, class BPtr>
-void testMoveConvertImplicit() {
-
-    { // Test implicit constructor
-        BPtr s(new B);
-        A* p = s.get();
-        APtr s2 = std::move(s);
-        assert(s2.get() == p);
-        assert(s.get() == 0);
-        assert(A::count == 1);
-        assert(B::count == 1);
-    }
-    assert(A::count == 0);
-    assert(B::count == 0);
-}
-
-template <class APtr, class BPtr, class Deleter>
-#if TEST_STD_VER >= 11
-void testMoveConvertExplicit(Deleter&& del) {
-#else
-void testMoveConvert(Deleter& del) {
-#endif
-    int old_val = del.state();
-    { // Test Explicit constructor
-        BPtr s(new B, std::forward<Deleter>(del));
-        A* p = s.get();
-        APtr s2(std::move(s));
-        assert(s2.get() == p);
-        assert(s.get() == 0);
-        checkDeleter(s, s2, del.state(), old_val);
-        assert(A::count == 1);
-        assert(B::count == 1);
-    }
-    assert(A::count == 0);
-    assert(B::count == 0);
-}
-
-
-template <class APtr, class BPtr, class Deleter>
-#if TEST_STD_VER >= 11
-void testMoveConvertImplicit(Deleter&& del) {
-#else
-void testMoveConvertImplicit(Deleter& del) {
-#endif
-    int old_val = del.state();
-    { // Test Implicit constructor
-        BPtr s(new B, std::forward<Deleter>(del));
-        A* p = s.get();
-        APtr s2 = std::move(s);
-        assert(s2.get() == p);
-        assert(s.get() == 0);
-        checkDeleter(s, s2, del.state(), old_val);
-        assert(A::count == 1);
-        assert(B::count == 1);
-    }
-    assert(A::count == 0);
-    assert(B::count == 0);
-}
 int main()
 {
     {
         typedef std::unique_ptr<A> APtr;
         typedef std::unique_ptr<B> BPtr;
-        testMoveConvertExplicit<APtr, BPtr>();
-        testMoveConvertImplicit<APtr, BPtr>();
+        { // explicit
+            BPtr b(new B);
+            A* p = b.get();
+            APtr a(std::move(b));
+            checkCtor(a, b, p);
+        }
+        checkNoneAlive();
+        { // implicit
+            BPtr b(new B);
+            A* p = b.get();
+            APtr a = std::move(b);
+            checkCtor(a, b, p);
+        }
+        checkNoneAlive();
     }
-    {
+    { // test with moveable deleters
         typedef std::unique_ptr<A, Deleter<A> > APtr;
         typedef std::unique_ptr<B, Deleter<B> > BPtr;
-        Deleter<B> del(5);
-        testMoveConvertExplicit<APtr, BPtr>(std::move(del));
-        del.set_state(5);
-        testMoveConvertImplicit<APtr, BPtr>(std::move(del));
+        {
+            Deleter<B> del(5);
+            BPtr b(new B, std::move(del));
+            A* p = b.get();
+            APtr a(std::move(b));
+            checkCtor(a, b, p);
+            checkDeleter(a, b, 5, 0);
+        }
+        checkNoneAlive();
+        {
+            Deleter<B> del(5);
+            BPtr b(new B, std::move(del));
+            A* p = b.get();
+            APtr a = std::move(b);
+            checkCtor(a, b, p);
+            checkDeleter(a, b, 5, 0);
+        }
+        checkNoneAlive();
+
     }
-    {
+    { // test with reference deleters
         typedef std::unique_ptr<A, NCDeleter<A>& > APtr;
         typedef std::unique_ptr<B, NCDeleter<A>& > BPtr;
         NCDeleter<A> del(5);
-        testMoveConvertExplicit<APtr, BPtr>(del);
-        testMoveConvertImplicit<APtr, BPtr>(del);
+        {
+            BPtr b(new B, del);
+            A* p = b.get();
+            APtr a(std::move(b));
+            checkCtor(a, b, p);
+            checkReferenceDeleter(a, b);
+        }
+        checkNoneAlive();
+        {
+            BPtr b(new B, del);
+            A* p = b.get();
+            APtr a = std::move(b);
+            checkCtor(a, b, p);
+            checkReferenceDeleter(a, b);
+        }
+        checkNoneAlive();
     }
     {
         typedef std::unique_ptr<A, CDeleter<A> > APtr;
         typedef std::unique_ptr<B, CDeleter<B>& > BPtr;
         CDeleter<B> del(5);
-        testMoveConvertImplicit<APtr, BPtr>(del);
-        testMoveConvertExplicit<APtr, BPtr>(del);
+        {
+            BPtr b(new B, del);
+            A* p = b.get();
+            APtr a(std::move(b));
+            checkCtor(a, b, p);
+            checkDeleter(a, b, 5, 5);
+        }
+        checkNoneAlive();
+        {
+            BPtr b(new B, del);
+            A* p = b.get();
+            APtr a = std::move(b);
+            checkCtor(a, b, p);
+            checkDeleter(a, b, 5, 5);
+        }
+        checkNoneAlive();
     }
 }
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter04.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter04.fail.cpp
index 7cacd1f..ad64b5e 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter04.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter04.fail.cpp
@@ -7,49 +7,24 @@
 //
 //===----------------------------------------------------------------------===//
 
+// Without rvalue references it is impossible to detect when a rvalue deleter
+// is given.
+// XFAIL: c++98, c++03
+
 // <memory>
 
 // unique_ptr
 
-// Test unique_ptr(pointer) ctor
-
-#include <memory>
-#include <cassert>
-
 // unique_ptr<T, const D&>(pointer, D()) should not compile
 
-struct A
-{
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    ~A() {--count;}
-};
+#include <memory>
 
-int A::count = 0;
-
-class Deleter
-{
-    int state_;
-
-public:
-
-    Deleter() : state_(5) {}
-
-    int state() const {return state_;}
-    void set_state(int s) {state_ = s;}
-
-    void operator()(A* p) const {delete p;}
+struct Deleter {
+    void operator()(int* p) const {delete p;}
 };
 
 int main()
 {
-    {
-    A* p = new A;
-    assert(A::count == 1);
-    std::unique_ptr<A, const Deleter&> s(p, Deleter());
-    assert(s.get() == p);
-    assert(s.get_deleter().state() == 5);
-    }
-    assert(A::count == 0);
+    // expected-error@memory:* {{static_assert failed "rvalue deleter bound to reference"}}
+    std::unique_ptr<int, const Deleter&> s((int*)nullptr, Deleter()); // expected-note {{requested here}}
 }
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 44b746f..c525137 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 @@
 
 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 @@
     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.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 b2e61fa..f174851 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,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <memory>
 
 // template<class Y> explicit shared_ptr(auto_ptr<Y>&& r);
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp
index ab2c73e..41aeb04 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <memory>
 
 // template<class D, class A> shared_ptr(nullptr_t, D d, A a);
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 97d3f69..6a79a8e 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <memory>
 
 // shared_ptr
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp
index 4220993..c728477 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <memory>
 
 // template<class Y, class D, class A> shared_ptr(Y* p, D d, A 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 ead0816..982313b 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <memory>
 
 // shared_ptr
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 041fe9a..2e761d7 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <memory>
 
 // template<class Y> explicit shared_ptr(Y* p);
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 5e09d9a..c62fcd6 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
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <memory>
 
 // template <class Y, class D> explicit shared_ptr(unique_ptr<Y, D>&&r);
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp
index a9d8aff..35a7d07 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // <memory>
 
 // shared_ptr
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 aa77dab..3e4a99e 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 @@
     }
     assert(A::count == 0);
     assert(test_allocator<A>::alloc_count == 0);
-#if __cplusplus >= 201103L
     {
     int i = 67;
     char c = 'e';
@@ -74,5 +75,4 @@
     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
similarity index 98%
rename from test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp
rename to test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_cxx03.pass.cpp
index 8dcd50e..f6350c7 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>
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 d091ae9..bf1719c 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,9 +30,28 @@
 //     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>
+// {
+//     template<class T, class U>
+//         bool operator()(shared_ptr<T> const&, shared_ptr<U> const&) const;
+//     template<class T, class U>
+//         bool operator()(shared_ptr<T> const&, weak_ptr<U> const&) const;
+//     template<class T, class U>
+//         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;
+// };
 
 #include <memory>
 #include <cassert>
+#include <set>
+#include "test_macros.h"
+
+struct X {};
 
 int main()
 {
@@ -79,4 +98,25 @@
     assert(cs(w1, p3) || cs(w3, p1));
     assert(cs(w3, p1) == cs(w3, p2));
     }
+#if TEST_STD_VER > 14
+    {
+    std::shared_ptr<int> sp1;
+    std::shared_ptr<void> sp2;
+    std::shared_ptr<long> sp3;
+    std::weak_ptr<int> wp1;
+
+    std::owner_less<> cmp;
+    cmp(sp1, sp2);
+    cmp(sp1, wp1);
+    cmp(sp1, sp3);
+    cmp(wp1, sp1);
+    cmp(wp1, wp1);
+    }
+    {
+    // test heterogeneous lookups 
+    std::set<std::shared_ptr<X>, std::owner_less<>> s;
+    std::shared_ptr<void> vp;
+    s.find(vp);
+    }
+#endif
 }
diff --git a/test/std/utilities/meta/meta.logical/conjunction.pass.cpp b/test/std/utilities/meta/meta.logical/conjunction.pass.cpp
new file mode 100644
index 0000000..dce58ec
--- /dev/null
+++ b/test/std/utilities/meta/meta.logical/conjunction.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, c++11, c++14
+// type_traits
+
+// template<class... B> struct conjunction;                           // C++17
+// template<class... B> 
+//   constexpr bool conjunction_v = conjunction<B...>::value;         // C++17
+
+#include <type_traits>
+#include <cassert>
+
+struct True  { static constexpr bool value = true; };
+struct False { static constexpr bool value = false; };
+
+int main()
+{
+    static_assert ( std::conjunction<>::value, "" );
+    static_assert ( std::conjunction<std::true_type >::value, "" );
+    static_assert (!std::conjunction<std::false_type>::value, "" );
+
+    static_assert ( std::conjunction_v<>, "" );
+    static_assert ( std::conjunction_v<std::true_type >, "" );
+    static_assert (!std::conjunction_v<std::false_type>, "" );
+
+    static_assert ( std::conjunction<std::true_type,  std::true_type >::value, "" );
+    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 >, "" );
+    static_assert (!std::conjunction_v<std::false_type, std::false_type>, "" );
+
+    static_assert ( std::conjunction<std::true_type,  std::true_type,  std::true_type >::value, "" );
+    static_assert (!std::conjunction<std::true_type,  std::false_type, std::true_type >::value, "" );
+    static_assert (!std::conjunction<std::false_type, std::true_type,  std::true_type >::value, "" );
+    static_assert (!std::conjunction<std::false_type, std::false_type, std::true_type >::value, "" );
+    static_assert (!std::conjunction<std::true_type,  std::true_type,  std::false_type>::value, "" );
+    static_assert (!std::conjunction<std::true_type,  std::false_type, std::false_type>::value, "" );
+    static_assert (!std::conjunction<std::false_type, std::true_type,  std::false_type>::value, "" );
+    static_assert (!std::conjunction<std::false_type, std::false_type, std::false_type>::value, "" );
+
+    static_assert ( std::conjunction_v<std::true_type,  std::true_type,  std::true_type >, "" );
+    static_assert (!std::conjunction_v<std::true_type,  std::false_type, std::true_type >, "" );
+    static_assert (!std::conjunction_v<std::false_type, std::true_type,  std::true_type >, "" );
+    static_assert (!std::conjunction_v<std::false_type, std::false_type, std::true_type >, "" );
+    static_assert (!std::conjunction_v<std::true_type,  std::true_type,  std::false_type>, "" );
+    static_assert (!std::conjunction_v<std::true_type,  std::false_type, std::false_type>, "" );
+    static_assert (!std::conjunction_v<std::false_type, std::true_type,  std::false_type>, "" );
+    static_assert (!std::conjunction_v<std::false_type, std::false_type, std::false_type>, "" );
+
+    static_assert ( std::conjunction<True >::value, "" );
+    static_assert (!std::conjunction<False>::value, "" );
+
+    static_assert ( std::conjunction_v<True >, "" );
+    static_assert (!std::conjunction_v<False>, "" );
+}
diff --git a/test/std/utilities/meta/meta.logical/disjunction.pass.cpp b/test/std/utilities/meta/meta.logical/disjunction.pass.cpp
new file mode 100644
index 0000000..13cd934
--- /dev/null
+++ b/test/std/utilities/meta/meta.logical/disjunction.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, c++11, c++14
+// type_traits
+
+// template<class... B> struct disjunction;                           // C++17
+// template<class... B> 
+//   constexpr bool disjunction_v = disjunction<B...>::value;         // C++17
+
+#include <type_traits>
+#include <cassert>
+
+struct True  { static constexpr bool value = true; };
+struct False { static constexpr bool value = false; };
+
+int main()
+{
+    static_assert (!std::disjunction<>::value, "" );
+    static_assert ( std::disjunction<std::true_type >::value, "" );
+    static_assert (!std::disjunction<std::false_type>::value, "" );
+
+    static_assert (!std::disjunction_v<>, "" );
+    static_assert ( std::disjunction_v<std::true_type >, "" );
+    static_assert (!std::disjunction_v<std::false_type>, "" );
+
+    static_assert ( std::disjunction<std::true_type,  std::true_type >::value, "" );
+    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 >, "" );
+    static_assert (!std::disjunction_v<std::false_type, std::false_type>, "" );
+
+    static_assert ( std::disjunction<std::true_type,  std::true_type,  std::true_type >::value, "" );
+    static_assert ( std::disjunction<std::true_type,  std::false_type, std::true_type >::value, "" );
+    static_assert ( std::disjunction<std::false_type, std::true_type,  std::true_type >::value, "" );
+    static_assert ( std::disjunction<std::false_type, std::false_type, std::true_type >::value, "" );
+    static_assert ( std::disjunction<std::true_type,  std::true_type,  std::false_type>::value, "" );
+    static_assert ( std::disjunction<std::true_type,  std::false_type, std::false_type>::value, "" );
+    static_assert ( std::disjunction<std::false_type, std::true_type,  std::false_type>::value, "" );
+    static_assert (!std::disjunction<std::false_type, std::false_type, std::false_type>::value, "" );
+
+    static_assert ( std::disjunction_v<std::true_type,  std::true_type,  std::true_type >, "" );
+    static_assert ( std::disjunction_v<std::true_type,  std::false_type, std::true_type >, "" );
+    static_assert ( std::disjunction_v<std::false_type, std::true_type,  std::true_type >, "" );
+    static_assert ( std::disjunction_v<std::false_type, std::false_type, std::true_type >, "" );
+    static_assert ( std::disjunction_v<std::true_type,  std::true_type,  std::false_type>, "" );
+    static_assert ( std::disjunction_v<std::true_type,  std::false_type, std::false_type>, "" );
+    static_assert ( std::disjunction_v<std::false_type, std::true_type,  std::false_type>, "" );
+    static_assert (!std::disjunction_v<std::false_type, std::false_type, std::false_type>, "" );
+
+    static_assert ( std::disjunction<True >::value, "" );
+    static_assert (!std::disjunction<False>::value, "" );
+
+    static_assert ( std::disjunction_v<True >, "" );
+    static_assert (!std::disjunction_v<False>, "" );
+}
diff --git a/test/std/utilities/meta/meta.logical/negation.pass.cpp b/test/std/utilities/meta/meta.logical/negation.pass.cpp
new file mode 100644
index 0000000..76ff6c5
--- /dev/null
+++ b/test/std/utilities/meta/meta.logical/negation.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, c++11, c++14
+// type_traits
+
+// template<class B> struct negation;                        // C++17
+// template<class B> 
+//   constexpr bool negation_v = negation<B>::value;         // C++17
+
+#include <type_traits>
+#include <cassert>
+
+struct True  { static constexpr bool value = true; };
+struct False { static constexpr bool value = false; };
+
+int main()
+{
+    static_assert (!std::negation<std::true_type >::value, "" );
+    static_assert ( std::negation<std::false_type>::value, "" );
+
+    static_assert (!std::negation_v<std::true_type >, "" );
+    static_assert ( std::negation_v<std::false_type>, "" );
+
+    static_assert (!std::negation<True >::value, "" );
+    static_assert ( std::negation<False>::value, "" );
+
+    static_assert (!std::negation_v<True >, "" );
+    static_assert ( std::negation_v<False>, "" );
+
+    static_assert ( std::negation<std::negation<std::true_type >>::value, "" );
+    static_assert (!std::negation<std::negation<std::false_type>>::value, "" );
+}
diff --git a/test/std/utilities/meta/meta.rel/is_base_of.pass.cpp b/test/std/utilities/meta/meta.rel/is_base_of.pass.cpp
index 0f90ae5..4b17a9f 100644
--- a/test/std/utilities/meta/meta.rel/is_base_of.pass.cpp
+++ b/test/std/utilities/meta/meta.rel/is_base_of.pass.cpp
@@ -13,6 +13,8 @@
 
 #include <type_traits>
 
+#include "test_macros.h"
+
 template <class T, class U>
 void test_is_base_of()
 {
@@ -20,6 +22,12 @@
     static_assert((std::is_base_of<const T, U>::value), "");
     static_assert((std::is_base_of<T, const U>::value), "");
     static_assert((std::is_base_of<const T, const U>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((std::is_base_of_v<T, U>), "");
+    static_assert((std::is_base_of_v<const T, U>), "");
+    static_assert((std::is_base_of_v<T, const U>), "");
+    static_assert((std::is_base_of_v<const T, const U>), "");
+#endif
 }
 
 template <class T, class U>
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 0000000..328b818
--- /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 429fb33..92f7a5d 100644
--- a/test/std/utilities/meta/meta.rel/is_convertible.pass.cpp
+++ b/test/std/utilities/meta/meta.rel/is_convertible.pass.cpp
@@ -12,6 +12,7 @@
 // is_convertible
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T, class U>
 void test_is_convertible()
@@ -20,6 +21,12 @@
     static_assert((std::is_convertible<const T, U>::value), "");
     static_assert((std::is_convertible<T, const U>::value), "");
     static_assert((std::is_convertible<const T, const U>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((std::is_convertible_v<T, U>), "");
+    static_assert((std::is_convertible_v<const T, U>), "");
+    static_assert((std::is_convertible_v<T, const U>), "");
+    static_assert((std::is_convertible_v<const T, const U>), "");
+#endif
 }
 
 template <class T, class U>
@@ -29,15 +36,31 @@
     static_assert((!std::is_convertible<const T, U>::value), "");
     static_assert((!std::is_convertible<T, const U>::value), "");
     static_assert((!std::is_convertible<const T, const U>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((!std::is_convertible_v<T, U>), "");
+    static_assert((!std::is_convertible_v<const T, U>), "");
+    static_assert((!std::is_convertible_v<T, const U>), "");
+    static_assert((!std::is_convertible_v<const T, const U>), "");
+#endif
 }
 
 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
@@ -50,12 +73,19 @@
     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> ();
@@ -86,6 +116,16 @@
     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> ();
@@ -95,17 +135,37 @@
 
     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> ();
@@ -126,6 +186,9 @@
     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> ();
@@ -188,8 +251,11 @@
     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_convertible_fallback.pass.cpp b/test/std/utilities/meta/meta.rel/is_convertible_fallback.pass.cpp
index bd35ef6..5a607f3 100644
--- a/test/std/utilities/meta/meta.rel/is_convertible_fallback.pass.cpp
+++ b/test/std/utilities/meta/meta.rel/is_convertible_fallback.pass.cpp
@@ -13,6 +13,14 @@
 
 // Test the fallback implementation.
 
+// libc++ provides a fallback implementation of the compiler trait
+// `__is_convertible` with the same name when clang doesn't.
+// Because this test forces the use of the fallback even when clang provides
+// it causing a keyword incompatibility.
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wkeyword-compat"
+#endif
+
 #define _LIBCPP_USE_IS_CONVERTIBLE_FALLBACK
 #include "is_convertible.pass.cpp"
 
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 0000000..5cadc0b
--- /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.rel/is_same.pass.cpp b/test/std/utilities/meta/meta.rel/is_same.pass.cpp
index 7250d6c..9db3673 100644
--- a/test/std/utilities/meta/meta.rel/is_same.pass.cpp
+++ b/test/std/utilities/meta/meta.rel/is_same.pass.cpp
@@ -13,13 +13,21 @@
 
 #include <type_traits>
 
+#include "test_macros.h"
+
 template <class T, class U>
 void test_is_same()
 {
-    static_assert((std::is_same<T, U>::value), "");
+    static_assert(( std::is_same<T, U>::value), "");
     static_assert((!std::is_same<const T, U>::value), "");
     static_assert((!std::is_same<T, const U>::value), "");
-    static_assert((std::is_same<const T, const U>::value), "");
+    static_assert(( std::is_same<const T, const U>::value), "");
+#if TEST_STD_VER > 14
+    static_assert(( std::is_same_v<T, U>), "");
+    static_assert((!std::is_same_v<const T, U>), "");
+    static_assert((!std::is_same_v<T, const U>), "");
+    static_assert(( std::is_same_v<const T, const U>), "");
+#endif
 }
 
 template <class T, class U>
@@ -29,6 +37,12 @@
     static_assert((std::is_same<const T, U>::value), "");
     static_assert((std::is_same<T, const U>::value), "");
     static_assert((std::is_same<const T, const U>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((std::is_same_v<T, U>), "");
+    static_assert((std::is_same_v<const T, U>), "");
+    static_assert((std::is_same_v<T, const U>), "");
+    static_assert((std::is_same_v<const T, const U>), "");
+#endif
 }
 
 template <class T, class U>
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 c87e99c..a53bed9 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
@@ -12,12 +12,14 @@
 // aligned_storage
 
 #include <type_traits>
+#include <cstddef>       // for std::max_align_t
+#include "test_macros.h"
 
 int main()
 {
     {
     typedef std::aligned_storage<10, 1 >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<10, 1>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 1, "");
@@ -25,7 +27,7 @@
     }
     {
     typedef std::aligned_storage<10, 2 >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<10, 2>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 2, "");
@@ -33,7 +35,7 @@
     }
     {
     typedef std::aligned_storage<10, 4 >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<10, 4>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 4, "");
@@ -41,7 +43,7 @@
     }
     {
     typedef std::aligned_storage<10, 8 >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<10, 8>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 8, "");
@@ -49,7 +51,7 @@
     }
     {
     typedef std::aligned_storage<10, 16 >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<10, 16>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 16, "");
@@ -57,7 +59,7 @@
     }
     {
     typedef std::aligned_storage<10, 32 >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<10, 32>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 32, "");
@@ -65,7 +67,7 @@
     }
     {
     typedef std::aligned_storage<20, 32 >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<20, 32>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 32, "");
@@ -73,7 +75,7 @@
     }
     {
     typedef std::aligned_storage<40, 32 >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<40, 32>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 32, "");
@@ -81,7 +83,7 @@
     }
     {
     typedef std::aligned_storage<12, 16 >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<12, 16>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 16, "");
@@ -89,7 +91,7 @@
     }
     {
     typedef std::aligned_storage<1>::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<1>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 1, "");
@@ -97,7 +99,7 @@
     }
     {
     typedef std::aligned_storage<2>::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<2>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 2, "");
@@ -105,7 +107,7 @@
     }
     {
     typedef std::aligned_storage<3>::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<3>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 2, "");
@@ -113,7 +115,7 @@
     }
     {
     typedef std::aligned_storage<4>::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<4>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 4, "");
@@ -121,7 +123,7 @@
     }
     {
     typedef std::aligned_storage<5>::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<5>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 4, "");
@@ -129,7 +131,7 @@
     }
     {
     typedef std::aligned_storage<7>::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<7>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 4, "");
@@ -137,7 +139,7 @@
     }
     {
     typedef std::aligned_storage<8>::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<8>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 8, "");
@@ -145,7 +147,7 @@
     }
     {
     typedef std::aligned_storage<9>::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<9>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 8, "");
@@ -153,7 +155,7 @@
     }
     {
     typedef std::aligned_storage<15>::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<15>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 8, "");
@@ -167,7 +169,7 @@
 #endif
     {
     typedef std::aligned_storage<16>::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<16>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == alignof(std::max_align_t),
@@ -176,7 +178,7 @@
     }
     {
     typedef std::aligned_storage<17>::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<17>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == alignof(std::max_align_t),
@@ -185,7 +187,7 @@
     }
     {
     typedef std::aligned_storage<10>::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert(std::is_same<std::aligned_storage_t<10>, T1>::value, "" );
 #endif
     static_assert(std::alignment_of<T1>::value == 8, "");
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp
index 91bf7e7..e861125 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp
@@ -13,11 +13,39 @@
 
 #include <type_traits>
 
+#include "test_macros.h"
+
+struct E {};
+
+template <class T>
+struct X { explicit X(T const&){} };
+
+template <class T>
+struct S { explicit S(T const&){} };
+
+namespace std
+{
+    template <typename T>
+    struct common_type<T, ::S<T> >
+    {
+        typedef S<T> type;
+    };
+}
+
+#if TEST_STD_VER >= 11
+template <class T, class U, class = void>
+struct no_common_type : std::true_type {};
+
+template <class T, class U>
+struct no_common_type<T, U, typename std::conditional<false,
+    typename std::common_type<T, U>::type, void>::type> : std::false_type {};
+#endif // TEST_STD_VER >= 11
+
 int main()
 {
     static_assert((std::is_same<std::common_type<int>::type, int>::value), "");
     static_assert((std::is_same<std::common_type<char>::type, char>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert((std::is_same<std::common_type_t<int>,   int>::value), "");
     static_assert((std::is_same<std::common_type_t<char>, char>::value), "");
 #endif
@@ -29,7 +57,7 @@
 
     static_assert((std::is_same<std::common_type<int,           int>::type, int>::value), "");
     static_assert((std::is_same<std::common_type<int,     const int>::type, int>::value), "");
-    
+
     static_assert((std::is_same<std::common_type<long,       const int>::type, long>::value), "");
     static_assert((std::is_same<std::common_type<const long,       int>::type, long>::value), "");
     static_assert((std::is_same<std::common_type<long,    volatile int>::type, long>::value), "");
@@ -38,15 +66,37 @@
 
     static_assert((std::is_same<std::common_type<double, char>::type, double>::value), "");
     static_assert((std::is_same<std::common_type<short, char>::type, int>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert((std::is_same<std::common_type_t<double, char>, double>::value), "");
     static_assert((std::is_same<std::common_type_t<short, char>, int>::value), "");
 #endif
 
     static_assert((std::is_same<std::common_type<double, char, long long>::type, double>::value), "");
     static_assert((std::is_same<std::common_type<unsigned, char, long long>::type, long long>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
     static_assert((std::is_same<std::common_type_t<double, char, long long>, double>::value), "");
     static_assert((std::is_same<std::common_type_t<unsigned, char, long long>, long long>::value), "");
 #endif
+
+    static_assert((std::is_same<std::common_type<               void>::type, void>::value), "");
+    static_assert((std::is_same<std::common_type<const          void>::type, void>::value), "");
+    static_assert((std::is_same<std::common_type<      volatile void>::type, void>::value), "");
+    static_assert((std::is_same<std::common_type<const volatile void>::type, void>::value), "");
+
+    static_assert((std::is_same<std::common_type<void,       const void>::type, void>::value), "");
+    static_assert((std::is_same<std::common_type<const void,       void>::type, void>::value), "");
+    static_assert((std::is_same<std::common_type<void,    volatile void>::type, void>::value), "");
+    static_assert((std::is_same<std::common_type<volatile void,    void>::type, void>::value), "");
+    static_assert((std::is_same<std::common_type<const void, const void>::type, void>::value), "");
+
+#if TEST_STD_VER >= 11
+    static_assert((no_common_type<void, int>::value), "");
+    static_assert((no_common_type<int, void>::value), "");
+    static_assert((no_common_type<int, E>::value), "");
+    static_assert((no_common_type<int, X<int> >::value), "");
+#endif // TEST_STD_VER >= 11
+
+    static_assert((std::is_same<std::common_type<int, S<int> >::type, S<int> >::value), "");
+    static_assert((std::is_same<std::common_type<int, S<int>, S<int> >::type, S<int> >::value), "");
+    static_assert((std::is_same<std::common_type<int, int, S<int> >::type, S<int> >::value), "");
 }
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 5a925bb..fc01b22 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 @@
     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 @@
 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 @@
 #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 @@
     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 @@
     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 @@
     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 6996cdd..8cb5853 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 F {};
+struct FD : public F {};
+struct NotDerived {};
 
 template <class T, class U>
 void test_result_of_imp()
@@ -31,10 +35,15 @@
 #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 @@
     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 @@
     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.ptr/add_pointer.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.ptr/add_pointer.pass.cpp
index 76d0f12..56acfc4 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 @@
     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 9cecd39..cccbb60 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 8150ce0..c82c282 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,18 +10,41 @@
 // 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
 }
 
+template <class F>
+void test_function0()
+{
+    static_assert((std::is_same<typename std::add_lvalue_reference<F>::type, F&>::value), "");
+#if TEST_STD_VER > 11
+    static_assert((std::is_same<std::add_lvalue_reference_t<F>, F&>::value), "");
+#endif
+}
+
+template <class F>
+void test_function1()
+{
+    static_assert((std::is_same<typename std::add_lvalue_reference<F>::type, F>::value), "");
+#if TEST_STD_VER > 11
+    static_assert((std::is_same<std::add_lvalue_reference_t<F>, F>::value), "");
+#endif
+}
+
+struct Foo {};
+
 int main()
 {
     test_add_lvalue_reference<void, void>();
@@ -31,4 +54,26 @@
     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()>();
+#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 e8f08fd..fc147c3 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 @@
 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 @@
     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 f9ebc37..e335bd1 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/alignment_of.pass.cpp b/test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp
index 6ea1cac..0f55db6 100644
--- a/test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp
+++ b/test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp
@@ -14,6 +14,8 @@
 #include <type_traits>
 #include <cstdint>
 
+#include "test_macros.h"
+
 template <class T, unsigned A>
 void test_alignment_of()
 {
@@ -21,6 +23,12 @@
     static_assert( std::alignment_of<const T>::value == A, "");
     static_assert( std::alignment_of<volatile T>::value == A, "");
     static_assert( std::alignment_of<const volatile T>::value == A, "");
+#if TEST_STD_VER > 14
+    static_assert( std::alignment_of_v<T> == A, "");
+    static_assert( std::alignment_of_v<const T> == A, "");
+    static_assert( std::alignment_of_v<volatile T> == A, "");
+    static_assert( std::alignment_of_v<const volatile T> == A, "");
+#endif
 }
 
 class Class
diff --git a/test/std/utilities/meta/meta.unary.prop.query/extent.pass.cpp b/test/std/utilities/meta/meta.unary.prop.query/extent.pass.cpp
index a99dc69..39a7c2b 100644
--- a/test/std/utilities/meta/meta.unary.prop.query/extent.pass.cpp
+++ b/test/std/utilities/meta/meta.unary.prop.query/extent.pass.cpp
@@ -13,6 +13,8 @@
 
 #include <type_traits>
 
+#include "test_macros.h"
+
 template <class T, unsigned A>
 void test_extent()
 {
@@ -20,6 +22,12 @@
     static_assert((std::extent<const T>::value == A), "");
     static_assert((std::extent<volatile T>::value == A), "");
     static_assert((std::extent<const volatile T>::value == A), "");
+#if TEST_STD_VER > 14
+    static_assert((std::extent_v<T> == A), "");
+    static_assert((std::extent_v<const T> == A), "");
+    static_assert((std::extent_v<volatile T> == A), "");
+    static_assert((std::extent_v<const volatile T> == A), "");
+#endif
 }
 
 template <class T, unsigned A>
@@ -29,6 +37,12 @@
     static_assert((std::extent<const T, 1>::value == A), "");
     static_assert((std::extent<volatile T, 1>::value == A), "");
     static_assert((std::extent<const volatile T, 1>::value == A), "");
+#if TEST_STD_VER > 14
+    static_assert((std::extent_v<T, 1> == A), "");
+    static_assert((std::extent_v<const T, 1> == A), "");
+    static_assert((std::extent_v<volatile T, 1> == A), "");
+    static_assert((std::extent_v<const volatile T, 1> == A), "");
+#endif
 }
 
 class Class
diff --git a/test/std/utilities/meta/meta.unary.prop.query/rank.pass.cpp b/test/std/utilities/meta/meta.unary.prop.query/rank.pass.cpp
index 06f66a9..755269d 100644
--- a/test/std/utilities/meta/meta.unary.prop.query/rank.pass.cpp
+++ b/test/std/utilities/meta/meta.unary.prop.query/rank.pass.cpp
@@ -13,6 +13,8 @@
 
 #include <type_traits>
 
+#include "test_macros.h"
+
 template <class T, unsigned A>
 void test_rank()
 {
@@ -20,6 +22,12 @@
     static_assert( std::rank<const T>::value == A, "");
     static_assert( std::rank<volatile T>::value == A, "");
     static_assert( std::rank<const volatile T>::value == A, "");
+#if TEST_STD_VER > 14
+    static_assert( std::rank_v<T> == A, "");
+    static_assert( std::rank_v<const T> == A, "");
+    static_assert( std::rank_v<volatile T> == A, "");
+    static_assert( std::rank_v<const volatile T> == A, "");
+#endif
 }
 
 class Class
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 5deeeff..ccec65f 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
@@ -11,11 +11,11 @@
 
 // void_t
 
-#include <type_traits>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
 
-#if _LIBCPP_STD_VER <= 14
-int main () {}
-#else
+// XFAIL: gcc-5.1 gcc-5.2
+
+#include <type_traits>
 
 template <class T>
 void test1()
@@ -66,4 +66,3 @@
 
     static_assert( std::is_same<void, std::void_t<int, double const &, Class, volatile int[], void>>::value, "");
 }
-#endif
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 f4dd356..db91182 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,14 @@
 typedef char array[3];
 typedef const char const_array[3];
 typedef char incomplete_array[];
+struct incomplete_type;
 
 int main()
 {
     test_array<array>();
     test_array<const_array>();
     test_array<incomplete_array>();
+
+//  LWG#2581
+    static_assert(!std::is_array<incomplete_type>::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 ac5d6e5..164e922 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,12 @@
 {
 };
 
+struct incomplete_type;
+
 int main()
 {
     test_class<Class>();
+
+//  LWG#2581
+    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 7c9c78f..519d441 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 @@
 }
 
 enum Enum {zero, one};
+struct incomplete_type;
 
 int main()
 {
     test_enum<Enum>();
+
+//  LWG#2581
+    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 2866449..207d9e5 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 @@
     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#2581
+    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 b1df4f2..e3b0799 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 @@
 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 @@
     test<__VA_ARGS__ volatile &&>();      \
     test<__VA_ARGS__ const volatile &&>()
 
+struct incomplete_type;
 
 int main()
 {
@@ -75,7 +77,7 @@
     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 @@
     TEST_REF_QUALIFIED( int (double, ...) );
     TEST_REF_QUALIFIED( int (double, char, ...) );
 #endif
+
+//  LWG#2581
+    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 f68ed3e..e9cd36b 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 @@
     test_integral_imp<const volatile T>();
 }
 
+struct incomplete_type;
+
 int main()
 {
     test_integral<bool>();
@@ -62,4 +65,7 @@
     test_integral<__int128_t>();
     test_integral<__uint128_t>();
 #endif
+
+//  LWG#2581
+    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
new file mode 100644
index 0000000..5285886
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_array.pass.cpp
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_array
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t 
+#include "test_macros.h"
+
+template <class T>
+void test_is_array()
+{
+    static_assert( std::is_array<T>::value, "");
+    static_assert( std::is_array<const T>::value, "");
+    static_assert( std::is_array<volatile T>::value, "");
+    static_assert( std::is_array<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_array_v<T>, "");
+    static_assert( std::is_array_v<const T>, "");
+    static_assert( std::is_array_v<volatile T>, "");
+    static_assert( std::is_array_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_array()
+{
+    static_assert(!std::is_array<T>::value, "");
+    static_assert(!std::is_array<const T>::value, "");
+    static_assert(!std::is_array<volatile T>::value, "");
+    static_assert(!std::is_array<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_array_v<T>, "");
+    static_assert(!std::is_array_v<const T>, "");
+    static_assert(!std::is_array_v<volatile T>, "");
+    static_assert(!std::is_array_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+int main()
+{
+    test_is_array<char[3]>();
+    test_is_array<char[]>();
+    test_is_array<Union[]>();
+
+    test_is_not_array<std::nullptr_t>();
+    test_is_not_array<void>();
+    test_is_not_array<int&>();
+    test_is_not_array<int&&>();
+    test_is_not_array<int*>();
+    test_is_not_array<double>();
+    test_is_not_array<const int*>();
+    test_is_not_array<Enum>();
+    test_is_not_array<Union>();
+    test_is_not_array<FunctionPtr>();
+    test_is_not_array<Empty>();
+    test_is_not_array<bit_zero>();
+    test_is_not_array<NotEmpty>();
+    test_is_not_array<incomplete_type>();  //  LWG#2581
+}
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
new file mode 100644
index 0000000..3c1a218
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_class.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_class
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_class()
+{
+    static_assert( std::is_class<T>::value, "");
+    static_assert( std::is_class<const T>::value, "");
+    static_assert( std::is_class<volatile T>::value, "");
+    static_assert( std::is_class<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_class_v<T>, "");
+    static_assert( std::is_class_v<const T>, "");
+    static_assert( std::is_class_v<volatile T>, "");
+    static_assert( std::is_class_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_class()
+{
+    static_assert(!std::is_class<T>::value, "");
+    static_assert(!std::is_class<const T>::value, "");
+    static_assert(!std::is_class<volatile T>::value, "");
+    static_assert(!std::is_class<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_class_v<T>, "");
+    static_assert(!std::is_class_v<const T>, "");
+    static_assert(!std::is_class_v<volatile T>, "");
+    static_assert(!std::is_class_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+int main()
+{
+    test_is_class<Empty>();
+    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
+    test_is_not_class<std::nullptr_t>();
+#endif
+    test_is_not_class<void>();
+    test_is_not_class<int>();
+    test_is_not_class<int&>();
+#if TEST_STD_VER >= 11
+    test_is_not_class<int&&>();
+#endif
+    test_is_not_class<int*>();
+    test_is_not_class<double>();
+    test_is_not_class<const int*>();
+    test_is_not_class<char[3]>();
+    test_is_not_class<char[]>();
+    test_is_not_class<Enum>();
+    test_is_not_class<Union>();
+    test_is_not_class<FunctionPtr>();
+}
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
new file mode 100644
index 0000000..2603bdf
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_enum.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_enum
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_enum()
+{
+    static_assert( std::is_enum<T>::value, "");
+    static_assert( std::is_enum<const T>::value, "");
+    static_assert( std::is_enum<volatile T>::value, "");
+    static_assert( std::is_enum<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_enum_v<T>, "");
+    static_assert( std::is_enum_v<const T>, "");
+    static_assert( std::is_enum_v<volatile T>, "");
+    static_assert( std::is_enum_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_enum()
+{
+    static_assert(!std::is_enum<T>::value, "");
+    static_assert(!std::is_enum<const T>::value, "");
+    static_assert(!std::is_enum<volatile T>::value, "");
+    static_assert(!std::is_enum<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_enum_v<T>, "");
+    static_assert(!std::is_enum_v<const T>, "");
+    static_assert(!std::is_enum_v<volatile T>, "");
+    static_assert(!std::is_enum_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+int main()
+{
+    test_is_enum<Enum>();
+
+    test_is_not_enum<std::nullptr_t>();
+    test_is_not_enum<void>();
+    test_is_not_enum<int>();
+    test_is_not_enum<int&>();
+    test_is_not_enum<int&&>();
+    test_is_not_enum<int*>();
+    test_is_not_enum<double>();
+    test_is_not_enum<const int*>();
+    test_is_not_enum<char[3]>();
+    test_is_not_enum<char[]>();
+    test_is_not_enum<Union>();
+    test_is_not_enum<Empty>();
+    test_is_not_enum<bit_zero>();
+    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
new file mode 100644
index 0000000..7e19c06
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_floating_point.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_floating_point
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_floating_point()
+{
+    static_assert( std::is_floating_point<T>::value, "");
+    static_assert( std::is_floating_point<const T>::value, "");
+    static_assert( std::is_floating_point<volatile T>::value, "");
+    static_assert( std::is_floating_point<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_floating_point_v<T>, "");
+    static_assert( std::is_floating_point_v<const T>, "");
+    static_assert( std::is_floating_point_v<volatile T>, "");
+    static_assert( std::is_floating_point_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_floating_point()
+{
+    static_assert(!std::is_floating_point<T>::value, "");
+    static_assert(!std::is_floating_point<const T>::value, "");
+    static_assert(!std::is_floating_point<volatile T>::value, "");
+    static_assert(!std::is_floating_point<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_floating_point_v<T>, "");
+    static_assert(!std::is_floating_point_v<const T>, "");
+    static_assert(!std::is_floating_point_v<volatile T>, "");
+    static_assert(!std::is_floating_point_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+int main()
+{
+    test_is_floating_point<float>();
+    test_is_floating_point<double>();
+    test_is_floating_point<long double>();
+
+    test_is_not_floating_point<short>();
+    test_is_not_floating_point<unsigned short>();
+    test_is_not_floating_point<int>();
+    test_is_not_floating_point<unsigned int>();
+    test_is_not_floating_point<long>();
+    test_is_not_floating_point<unsigned long>();
+
+    test_is_not_floating_point<std::nullptr_t>();
+    test_is_not_floating_point<void>();
+    test_is_not_floating_point<int&>();
+    test_is_not_floating_point<int&&>();
+    test_is_not_floating_point<int*>();
+    test_is_not_floating_point<const int*>();
+    test_is_not_floating_point<char[3]>();
+    test_is_not_floating_point<char[]>();
+    test_is_not_floating_point<Union>();
+    test_is_not_floating_point<Empty>();
+    test_is_not_floating_point<bit_zero>();
+    test_is_not_floating_point<NotEmpty>();
+    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
new file mode 100644
index 0000000..cb5849f
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_function.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_function
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_function()
+{
+    static_assert( std::is_function<T>::value, "");
+    static_assert( std::is_function<const T>::value, "");
+    static_assert( std::is_function<volatile T>::value, "");
+    static_assert( std::is_function<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_function_v<T>, "");
+    static_assert( std::is_function_v<const T>, "");
+    static_assert( std::is_function_v<volatile T>, "");
+    static_assert( std::is_function_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_function()
+{
+    static_assert(!std::is_function<T>::value, "");
+    static_assert(!std::is_function<const T>::value, "");
+    static_assert(!std::is_function<volatile T>::value, "");
+    static_assert(!std::is_function<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_function_v<T>, "");
+    static_assert(!std::is_function_v<const T>, "");
+    static_assert(!std::is_function_v<volatile T>, "");
+    static_assert(!std::is_function_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+int main()
+{
+	test_is_function<void(void)>();
+	test_is_function<int(int)>();
+	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>();
+    test_is_not_function<int&>();
+    test_is_not_function<int&&>();
+    test_is_not_function<int*>();
+    test_is_not_function<double>();
+    test_is_not_function<char[3]>();
+    test_is_not_function<char[]>();
+    test_is_not_function<Union>();
+    test_is_not_function<Enum>();
+    test_is_not_function<FunctionPtr>(); // function pointer is not a function
+    test_is_not_function<Empty>();
+    test_is_not_function<bit_zero>();
+    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
new file mode 100644
index 0000000..0999762
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_integral
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_integral()
+{
+    static_assert( std::is_integral<T>::value, "");
+    static_assert( std::is_integral<const T>::value, "");
+    static_assert( std::is_integral<volatile T>::value, "");
+    static_assert( std::is_integral<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_integral_v<T>, "");
+    static_assert( std::is_integral_v<const T>, "");
+    static_assert( std::is_integral_v<volatile T>, "");
+    static_assert( std::is_integral_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_integral()
+{
+    static_assert(!std::is_integral<T>::value, "");
+    static_assert(!std::is_integral<const T>::value, "");
+    static_assert(!std::is_integral<volatile T>::value, "");
+    static_assert(!std::is_integral<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_integral_v<T>, "");
+    static_assert(!std::is_integral_v<const T>, "");
+    static_assert(!std::is_integral_v<volatile T>, "");
+    static_assert(!std::is_integral_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+
+int main()
+{
+    test_is_integral<short>();
+    test_is_integral<unsigned short>();
+    test_is_integral<int>();
+    test_is_integral<unsigned int>();
+    test_is_integral<long>();
+    test_is_integral<unsigned long>();
+    test_is_integral<bool>();
+    test_is_integral<char>();
+    test_is_integral<signed char>();
+    test_is_integral<unsigned char>();
+    test_is_integral<wchar_t>();
+
+    test_is_not_integral<std::nullptr_t>();
+    test_is_not_integral<void>();
+    test_is_not_integral<int&>();
+    test_is_not_integral<int&&>();
+    test_is_not_integral<int*>();
+    test_is_not_integral<double>();
+    test_is_not_integral<const int*>();
+    test_is_not_integral<char[3]>();
+    test_is_not_integral<char[]>();
+    test_is_not_integral<Union>();
+    test_is_not_integral<Enum>();
+    test_is_not_integral<FunctionPtr>();
+    test_is_not_integral<Empty>();
+    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
new file mode 100644
index 0000000..41b8d44
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_lvalue_reference.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_lvalue_reference
+
+// UNSUPPORTED: c++98, c++03
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_lvalue_reference()
+{
+    static_assert( std::is_lvalue_reference<T>::value, "");
+    static_assert( std::is_lvalue_reference<const T>::value, "");
+    static_assert( std::is_lvalue_reference<volatile T>::value, "");
+    static_assert( std::is_lvalue_reference<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_lvalue_reference_v<T>, "");
+    static_assert( std::is_lvalue_reference_v<const T>, "");
+    static_assert( std::is_lvalue_reference_v<volatile T>, "");
+    static_assert( std::is_lvalue_reference_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_lvalue_reference()
+{
+    static_assert(!std::is_lvalue_reference<T>::value, "");
+    static_assert(!std::is_lvalue_reference<const T>::value, "");
+    static_assert(!std::is_lvalue_reference<volatile T>::value, "");
+    static_assert(!std::is_lvalue_reference<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_lvalue_reference_v<T>, "");
+    static_assert(!std::is_lvalue_reference_v<const T>, "");
+    static_assert(!std::is_lvalue_reference_v<volatile T>, "");
+    static_assert(!std::is_lvalue_reference_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+int main()
+{
+    test_is_lvalue_reference<int&>();
+
+    test_is_not_lvalue_reference<std::nullptr_t>();
+    test_is_not_lvalue_reference<void>();
+    test_is_not_lvalue_reference<int>();
+    test_is_not_lvalue_reference<int*>();
+    test_is_not_lvalue_reference<int&&>();
+    test_is_not_lvalue_reference<double>();
+    test_is_not_lvalue_reference<const int*>();
+    test_is_not_lvalue_reference<char[3]>();
+    test_is_not_lvalue_reference<char[]>();
+    test_is_not_lvalue_reference<Union>();
+    test_is_not_lvalue_reference<Enum>();
+    test_is_not_lvalue_reference<FunctionPtr>();
+    test_is_not_lvalue_reference<Empty>();
+    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
new file mode 100644
index 0000000..9498edc
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_object_pointer.pass.cpp
@@ -0,0 +1,99 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The 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_member_object_pointer
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_member_object_pointer()
+{
+    static_assert( std::is_member_object_pointer<T>::value, "");
+    static_assert( std::is_member_object_pointer<const T>::value, "");
+    static_assert( std::is_member_object_pointer<volatile T>::value, "");
+    static_assert( std::is_member_object_pointer<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_member_object_pointer_v<T>, "");
+    static_assert( std::is_member_object_pointer_v<const T>, "");
+    static_assert( std::is_member_object_pointer_v<volatile T>, "");
+    static_assert( std::is_member_object_pointer_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_member_object_pointer()
+{
+    static_assert(!std::is_member_object_pointer<T>::value, "");
+    static_assert(!std::is_member_object_pointer<const T>::value, "");
+    static_assert(!std::is_member_object_pointer<volatile T>::value, "");
+    static_assert(!std::is_member_object_pointer<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_member_object_pointer_v<T>, "");
+    static_assert(!std::is_member_object_pointer_v<const T>, "");
+    static_assert(!std::is_member_object_pointer_v<volatile T>, "");
+    static_assert(!std::is_member_object_pointer_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+
+int main()
+{
+    test_is_member_object_pointer<int Abstract::*>();
+    test_is_member_object_pointer<double NotEmpty::*>();
+    test_is_member_object_pointer<FunctionPtr Empty::*>();
+
+    test_is_not_member_object_pointer<std::nullptr_t>();
+    test_is_not_member_object_pointer<void>();
+    test_is_not_member_object_pointer<int>();
+    test_is_not_member_object_pointer<int&>();
+    test_is_not_member_object_pointer<int&&>();
+    test_is_not_member_object_pointer<int*>();
+    test_is_not_member_object_pointer<double>();
+    test_is_not_member_object_pointer<const int*>();
+    test_is_not_member_object_pointer<char[3]>();
+    test_is_not_member_object_pointer<char[]>();
+    test_is_not_member_object_pointer<Union>();
+    test_is_not_member_object_pointer<Enum>();
+    test_is_not_member_object_pointer<FunctionPtr>();
+    test_is_not_member_object_pointer<Empty>();
+    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
new file mode 100644
index 0000000..d4043f4
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_pointer.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_member_pointer
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_member_pointer()
+{
+    static_assert( std::is_member_pointer<T>::value, "");
+    static_assert( std::is_member_pointer<const T>::value, "");
+    static_assert( std::is_member_pointer<volatile T>::value, "");
+    static_assert( std::is_member_pointer<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_member_pointer_v<T>, "");
+    static_assert( std::is_member_pointer_v<const T>, "");
+    static_assert( std::is_member_pointer_v<volatile T>, "");
+    static_assert( std::is_member_pointer_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_member_pointer()
+{
+    static_assert(!std::is_member_pointer<T>::value, "");
+    static_assert(!std::is_member_pointer<const T>::value, "");
+    static_assert(!std::is_member_pointer<volatile T>::value, "");
+    static_assert(!std::is_member_pointer<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_member_pointer_v<T>, "");
+    static_assert(!std::is_member_pointer_v<const T>, "");
+    static_assert(!std::is_member_pointer_v<volatile T>, "");
+    static_assert(!std::is_member_pointer_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+
+int main()
+{
+    test_is_member_pointer<int Abstract::*>();
+    test_is_member_pointer<double NotEmpty::*>();
+    test_is_member_pointer<FunctionPtr Empty::*>();
+    test_is_member_pointer<void (Empty::*)()>();
+
+    test_is_not_member_pointer<std::nullptr_t>();
+    test_is_not_member_pointer<void>();
+    test_is_not_member_pointer<int>();
+    test_is_not_member_pointer<int&>();
+    test_is_not_member_pointer<int&&>();
+    test_is_not_member_pointer<int*>();
+    test_is_not_member_pointer<double>();
+    test_is_not_member_pointer<const int*>();
+    test_is_not_member_pointer<char[3]>();
+    test_is_not_member_pointer<char[]>();
+    test_is_not_member_pointer<Union>();
+    test_is_not_member_pointer<Enum>();
+    test_is_not_member_pointer<FunctionPtr>();
+    test_is_not_member_pointer<Empty>();
+    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
new file mode 100644
index 0000000..f575763
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_null_pointer.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_null_pointer
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_null_pointer()
+{
+    static_assert( std::is_null_pointer<T>::value, "");
+    static_assert( std::is_null_pointer<const T>::value, "");
+    static_assert( std::is_null_pointer<volatile T>::value, "");
+    static_assert( std::is_null_pointer<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_null_pointer_v<T>, "");
+    static_assert( std::is_null_pointer_v<const T>, "");
+    static_assert( std::is_null_pointer_v<volatile T>, "");
+    static_assert( std::is_null_pointer_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_null_pointer()
+{
+    static_assert(!std::is_null_pointer<T>::value, "");
+    static_assert(!std::is_null_pointer<const T>::value, "");
+    static_assert(!std::is_null_pointer<volatile T>::value, "");
+    static_assert(!std::is_null_pointer<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_null_pointer_v<T>, "");
+    static_assert(!std::is_null_pointer_v<const T>, "");
+    static_assert(!std::is_null_pointer_v<volatile T>, "");
+    static_assert(!std::is_null_pointer_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+int main()
+{
+    test_is_null_pointer<std::nullptr_t>();
+
+    test_is_not_null_pointer<void>();
+    test_is_not_null_pointer<int>();
+    test_is_not_null_pointer<int&>();
+    test_is_not_null_pointer<int&&>();
+    test_is_not_null_pointer<int*>();
+    test_is_not_null_pointer<double>();
+    test_is_not_null_pointer<const int*>();
+    test_is_not_null_pointer<char[3]>();
+    test_is_not_null_pointer<char[]>();
+    test_is_not_null_pointer<Union>();
+    test_is_not_null_pointer<Enum>();
+    test_is_not_null_pointer<FunctionPtr>();
+    test_is_not_null_pointer<Empty>();
+    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
new file mode 100644
index 0000000..257719e
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_pointer.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_pointer
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_pointer()
+{
+    static_assert( std::is_pointer<T>::value, "");
+    static_assert( std::is_pointer<const T>::value, "");
+    static_assert( std::is_pointer<volatile T>::value, "");
+    static_assert( std::is_pointer<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_pointer_v<T>, "");
+    static_assert( std::is_pointer_v<const T>, "");
+    static_assert( std::is_pointer_v<volatile T>, "");
+    static_assert( std::is_pointer_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_pointer()
+{
+    static_assert(!std::is_pointer<T>::value, "");
+    static_assert(!std::is_pointer<const T>::value, "");
+    static_assert(!std::is_pointer<volatile T>::value, "");
+    static_assert(!std::is_pointer<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_pointer_v<T>, "");
+    static_assert(!std::is_pointer_v<const T>, "");
+    static_assert(!std::is_pointer_v<volatile T>, "");
+    static_assert(!std::is_pointer_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+int main()
+{
+    test_is_pointer<void*>();
+    test_is_pointer<int*>();
+    test_is_pointer<const int*>();
+    test_is_pointer<Abstract*>();
+    test_is_pointer<FunctionPtr>();
+
+    test_is_not_pointer<std::nullptr_t>();
+    test_is_not_pointer<void>();
+    test_is_not_pointer<int&>();
+    test_is_not_pointer<int&&>();
+    test_is_not_pointer<double>();
+    test_is_not_pointer<char[3]>();
+    test_is_not_pointer<char[]>();
+    test_is_not_pointer<Union>();
+    test_is_not_pointer<Enum>();
+    test_is_not_pointer<Empty>();
+    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
new file mode 100644
index 0000000..8963937
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_rvalue_reference.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_rvalue_reference
+
+// UNSUPPORTED: c++98, c++03
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_rvalue_reference()
+{
+    static_assert( std::is_rvalue_reference<T>::value, "");
+    static_assert( std::is_rvalue_reference<const T>::value, "");
+    static_assert( std::is_rvalue_reference<volatile T>::value, "");
+    static_assert( std::is_rvalue_reference<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_rvalue_reference_v<T>, "");
+    static_assert( std::is_rvalue_reference_v<const T>, "");
+    static_assert( std::is_rvalue_reference_v<volatile T>, "");
+    static_assert( std::is_rvalue_reference_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_rvalue_reference()
+{
+    static_assert(!std::is_rvalue_reference<T>::value, "");
+    static_assert(!std::is_rvalue_reference<const T>::value, "");
+    static_assert(!std::is_rvalue_reference<volatile T>::value, "");
+    static_assert(!std::is_rvalue_reference<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_rvalue_reference_v<T>, "");
+    static_assert(!std::is_rvalue_reference_v<const T>, "");
+    static_assert(!std::is_rvalue_reference_v<volatile T>, "");
+    static_assert(!std::is_rvalue_reference_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+int main()
+{
+    test_is_rvalue_reference<int&&>();
+
+    test_is_not_rvalue_reference<std::nullptr_t>();
+    test_is_not_rvalue_reference<void>();
+    test_is_not_rvalue_reference<int>();
+    test_is_not_rvalue_reference<int*>();
+    test_is_not_rvalue_reference<int&>();
+    test_is_not_rvalue_reference<double>();
+    test_is_not_rvalue_reference<const int*>();
+    test_is_not_rvalue_reference<char[3]>();
+    test_is_not_rvalue_reference<char[]>();
+    test_is_not_rvalue_reference<Union>();
+    test_is_not_rvalue_reference<Enum>();
+    test_is_not_rvalue_reference<FunctionPtr>();
+    test_is_not_rvalue_reference<Empty>();
+    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
new file mode 100644
index 0000000..415d9a7
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_union.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_union
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_union()
+{
+    static_assert( std::is_union<T>::value, "");
+    static_assert( std::is_union<const T>::value, "");
+    static_assert( std::is_union<volatile T>::value, "");
+    static_assert( std::is_union<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_union_v<T>, "");
+    static_assert( std::is_union_v<const T>, "");
+    static_assert( std::is_union_v<volatile T>, "");
+    static_assert( std::is_union_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_union()
+{
+    static_assert(!std::is_union<T>::value, "");
+    static_assert(!std::is_union<const T>::value, "");
+    static_assert(!std::is_union<volatile T>::value, "");
+    static_assert(!std::is_union<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_union_v<T>, "");
+    static_assert(!std::is_union_v<const T>, "");
+    static_assert(!std::is_union_v<volatile T>, "");
+    static_assert(!std::is_union_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+int main()
+{
+    test_is_union<Union>();
+
+    test_is_not_union<std::nullptr_t>();
+    test_is_not_union<void>();
+    test_is_not_union<int>();
+    test_is_not_union<int&>();
+    test_is_not_union<int&&>();
+    test_is_not_union<int*>();
+    test_is_not_union<double>();
+    test_is_not_union<const int*>();
+    test_is_not_union<char[3]>();
+    test_is_not_union<char[]>();
+    test_is_not_union<Enum>();
+    test_is_not_union<FunctionPtr>();
+    test_is_not_union<Empty>();
+    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
new file mode 100644
index 0000000..952a5b7
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_void.pass.cpp
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_void
+
+#include <type_traits>
+#include <cstddef>        // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_void()
+{
+    static_assert( std::is_void<T>::value, "");
+    static_assert( std::is_void<const T>::value, "");
+    static_assert( std::is_void<volatile T>::value, "");
+    static_assert( std::is_void<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_void_v<T>, "");
+    static_assert( std::is_void_v<const T>, "");
+    static_assert( std::is_void_v<volatile T>, "");
+    static_assert( std::is_void_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_void()
+{
+    static_assert(!std::is_void<T>::value, "");
+    static_assert(!std::is_void<const T>::value, "");
+    static_assert(!std::is_void<volatile T>::value, "");
+    static_assert(!std::is_void<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_void_v<T>, "");
+    static_assert(!std::is_void_v<const T>, "");
+    static_assert(!std::is_void_v<volatile T>, "");
+    static_assert(!std::is_void_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+struct incomplete_type;
+
+typedef void (*FunctionPtr)();
+
+int main()
+{
+    test_is_void<void>();
+
+    test_is_not_void<int>();
+    test_is_not_void<int*>();
+    test_is_not_void<int&>();
+    test_is_not_void<int&&>();
+    test_is_not_void<double>();
+    test_is_not_void<const int*>();
+    test_is_not_void<char[3]>();
+    test_is_not_void<char[]>();
+    test_is_not_void<Union>();
+    test_is_not_void<Empty>();
+    test_is_not_void<bit_zero>();
+    test_is_not_void<NotEmpty>();
+    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 3b6ccad..4e7bdbf 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 @@
     static_assert(!std::is_function<T>::value, "");
 }
 
+struct incomplete_type;
+
 int main()
 {
     test_lvalue_ref<int&>();
     test_lvalue_ref<const int&>();
+
+//  LWG#2581
+    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 6f546ef..49db6ab 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 @@
 {
 };
 
+struct incomplete_type;
+
 int main()
 {
     test_member_function_pointer<void (Class::*)()>();
@@ -133,4 +135,7 @@
     test_member_function_pointer<void (Class::*)(int,...) const volatile &&>();
     test_member_function_pointer<void (Class::*)(int, char,...) const volatile &&>();
 #endif
+
+//  LWG#2581
+    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 e13e586..7afc88f 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 @@
 {
 };
 
+struct incomplete_type;
+
 int main()
 {
     test_member_function_pointer<void (Class::*)()>();
@@ -73,4 +75,7 @@
     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#2581
+    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 4e6699c..4102f99 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 @@
 {
 };
 
+struct incomplete_type;
+
 int main()
 {
     test_member_object_pointer<int Class::*>();
+
+//  LWG#2581
+    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 691e353..aad9e34 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
@@ -13,8 +13,10 @@
 //  is_null_pointer
 
 #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()
 {
@@ -43,9 +45,14 @@
     test_nullptr_imp<const volatile T>();
 }
 
+struct incomplete_type;
+
 int main()
 {
     test_nullptr<std::nullptr_t>();
+
+//  LWG#2581
+    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 7073c10..72c8e36 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 @@
     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#2581
+    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 7964424..9451a91 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 @@
     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#2581
+    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 6cabb71..5f57323 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 @@
     double __;
 };
 
+struct incomplete_type;
+
 int main()
 {
     test_union<Union>();
+
+//  LWG#2581
+    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 f20bcf8..f176366 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 @@
     test_void_imp<const volatile T>();
 }
 
+struct incomplete_type;
+
 int main()
 {
     test_void<void>();
+
+//  LWG#2581
+    static_assert(!std::is_void<incomplete_type>::value, "");
 }
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
new file mode 100644
index 0000000..a3f18d5
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_arithmetic.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_arithmetic
+
+#include <type_traits>
+#include <cstddef>         // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_arithmetic()
+{
+    static_assert( std::is_arithmetic<T>::value, "");
+    static_assert( std::is_arithmetic<const T>::value, "");
+    static_assert( std::is_arithmetic<volatile T>::value, "");
+    static_assert( std::is_arithmetic<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_arithmetic_v<T>, "");
+    static_assert( std::is_arithmetic_v<const T>, "");
+    static_assert( std::is_arithmetic_v<volatile T>, "");
+    static_assert( std::is_arithmetic_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_arithmetic()
+{
+    static_assert(!std::is_arithmetic<T>::value, "");
+    static_assert(!std::is_arithmetic<const T>::value, "");
+    static_assert(!std::is_arithmetic<volatile T>::value, "");
+    static_assert(!std::is_arithmetic<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_arithmetic_v<T>, "");
+    static_assert(!std::is_arithmetic_v<const T>, "");
+    static_assert(!std::is_arithmetic_v<volatile T>, "");
+    static_assert(!std::is_arithmetic_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+
+typedef void (*FunctionPtr)();
+
+
+int main()
+{
+    test_is_arithmetic<short>();
+    test_is_arithmetic<unsigned short>();
+    test_is_arithmetic<int>();
+    test_is_arithmetic<unsigned int>();
+    test_is_arithmetic<long>();
+    test_is_arithmetic<unsigned long>();
+    test_is_arithmetic<bool>();
+    test_is_arithmetic<char>();
+    test_is_arithmetic<signed char>();
+    test_is_arithmetic<unsigned char>();
+    test_is_arithmetic<wchar_t>();
+    test_is_arithmetic<double>();
+
+    test_is_not_arithmetic<std::nullptr_t>();
+    test_is_not_arithmetic<void>();
+    test_is_not_arithmetic<int&>();
+    test_is_not_arithmetic<int&&>();
+    test_is_not_arithmetic<int*>();
+    test_is_not_arithmetic<const int*>();
+    test_is_not_arithmetic<char[3]>();
+    test_is_not_arithmetic<char[]>();
+    test_is_not_arithmetic<Union>();
+    test_is_not_arithmetic<Enum>();
+    test_is_not_arithmetic<FunctionPtr>();
+    test_is_not_arithmetic<Empty>();
+    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
new file mode 100644
index 0000000..6a1798a
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_compound.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_compound
+
+#include <type_traits>
+#include <cstddef>         // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_compound()
+{
+    static_assert( std::is_compound<T>::value, "");
+    static_assert( std::is_compound<const T>::value, "");
+    static_assert( std::is_compound<volatile T>::value, "");
+    static_assert( std::is_compound<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_compound_v<T>, "");
+    static_assert( std::is_compound_v<const T>, "");
+    static_assert( std::is_compound_v<volatile T>, "");
+    static_assert( std::is_compound_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_compound()
+{
+    static_assert(!std::is_compound<T>::value, "");
+    static_assert(!std::is_compound<const T>::value, "");
+    static_assert(!std::is_compound<volatile T>::value, "");
+    static_assert(!std::is_compound<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_compound_v<T>, "");
+    static_assert(!std::is_compound_v<const T>, "");
+    static_assert(!std::is_compound_v<volatile T>, "");
+    static_assert(!std::is_compound_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+
+typedef void (*FunctionPtr)();
+
+
+int main()
+{
+    test_is_compound<char[3]>();
+    test_is_compound<char[]>();
+    test_is_compound<void *>();
+    test_is_compound<FunctionPtr>();
+    test_is_compound<int&>();
+    test_is_compound<int&&>();
+    test_is_compound<Union>();
+    test_is_compound<Empty>();
+    test_is_compound<bit_zero>();
+    test_is_compound<int*>();
+    test_is_compound<const int*>();
+    test_is_compound<Enum>();
+    test_is_compound<NotEmpty>();
+    test_is_compound<Abstract>();
+
+    test_is_not_compound<std::nullptr_t>();
+    test_is_not_compound<void>();
+    test_is_not_compound<int>();
+    test_is_not_compound<double>();
+}
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
new file mode 100644
index 0000000..e16337e
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_fundamental.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_fundamental
+
+#include <type_traits>
+#include <cstddef>         // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_fundamental()
+{
+    static_assert( std::is_fundamental<T>::value, "");
+    static_assert( std::is_fundamental<const T>::value, "");
+    static_assert( std::is_fundamental<volatile T>::value, "");
+    static_assert( std::is_fundamental<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_fundamental_v<T>, "");
+    static_assert( std::is_fundamental_v<const T>, "");
+    static_assert( std::is_fundamental_v<volatile T>, "");
+    static_assert( std::is_fundamental_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_fundamental()
+{
+    static_assert(!std::is_fundamental<T>::value, "");
+    static_assert(!std::is_fundamental<const T>::value, "");
+    static_assert(!std::is_fundamental<volatile T>::value, "");
+    static_assert(!std::is_fundamental<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_fundamental_v<T>, "");
+    static_assert(!std::is_fundamental_v<const T>, "");
+    static_assert(!std::is_fundamental_v<volatile T>, "");
+    static_assert(!std::is_fundamental_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+
+typedef void (*FunctionPtr)();
+
+
+int main()
+{
+    test_is_fundamental<std::nullptr_t>();
+    test_is_fundamental<void>();
+    test_is_fundamental<short>();
+    test_is_fundamental<unsigned short>();
+    test_is_fundamental<int>();
+    test_is_fundamental<unsigned int>();
+    test_is_fundamental<long>();
+    test_is_fundamental<unsigned long>();
+    test_is_fundamental<long long>();
+    test_is_fundamental<unsigned long long>();
+    test_is_fundamental<bool>();
+    test_is_fundamental<char>();
+    test_is_fundamental<signed char>();
+    test_is_fundamental<unsigned char>();
+    test_is_fundamental<wchar_t>();
+    test_is_fundamental<double>();
+	test_is_fundamental<float>();
+	test_is_fundamental<double>();
+	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 *>();
+    test_is_not_fundamental<FunctionPtr>();
+    test_is_not_fundamental<int&>();
+    test_is_not_fundamental<int&&>();
+    test_is_not_fundamental<Union>();
+    test_is_not_fundamental<Empty>();
+    test_is_not_fundamental<bit_zero>();
+    test_is_not_fundamental<int*>();
+    test_is_not_fundamental<const int*>();
+    test_is_not_fundamental<Enum>();
+    test_is_not_fundamental<NotEmpty>();
+    test_is_not_fundamental<Abstract>();
+}
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
new file mode 100644
index 0000000..890da65
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_member_pointer.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_member_pointer
+
+#include <type_traits>
+#include <cstddef>         // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_member_pointer()
+{
+    static_assert( std::is_member_pointer<T>::value, "");
+    static_assert( std::is_member_pointer<const T>::value, "");
+    static_assert( std::is_member_pointer<volatile T>::value, "");
+    static_assert( std::is_member_pointer<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_member_pointer_v<T>, "");
+    static_assert( std::is_member_pointer_v<const T>, "");
+    static_assert( std::is_member_pointer_v<volatile T>, "");
+    static_assert( std::is_member_pointer_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_member_pointer()
+{
+    static_assert(!std::is_member_pointer<T>::value, "");
+    static_assert(!std::is_member_pointer<const T>::value, "");
+    static_assert(!std::is_member_pointer<volatile T>::value, "");
+    static_assert(!std::is_member_pointer<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_member_pointer_v<T>, "");
+    static_assert(!std::is_member_pointer_v<const T>, "");
+    static_assert(!std::is_member_pointer_v<volatile T>, "");
+    static_assert(!std::is_member_pointer_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+
+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. 
+
+    test_is_member_pointer<int Empty::*>();
+    test_is_member_pointer<void (Empty::*)(int)>();
+
+    test_is_not_member_pointer<std::nullptr_t>();
+    test_is_not_member_pointer<void>();
+    test_is_not_member_pointer<void *>();
+    test_is_not_member_pointer<int>();
+    test_is_not_member_pointer<int*>();
+    test_is_not_member_pointer<const int*>();
+    test_is_not_member_pointer<int&>();
+    test_is_not_member_pointer<int&&>();
+    test_is_not_member_pointer<double>();
+    test_is_not_member_pointer<char[3]>();
+    test_is_not_member_pointer<char[]>();
+    test_is_not_member_pointer<Union>();
+    test_is_not_member_pointer<Empty>();
+    test_is_not_member_pointer<bit_zero>();
+    test_is_not_member_pointer<NotEmpty>();
+    test_is_not_member_pointer<Abstract>();
+    test_is_not_member_pointer<int(int)>();
+    test_is_not_member_pointer<Enum>();
+    test_is_not_member_pointer<FunctionPtr>();
+}
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
new file mode 100644
index 0000000..ff7dda3
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_object.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_object
+
+#include <type_traits>
+#include <cstddef>         // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_object()
+{
+    static_assert( std::is_object<T>::value, "");
+    static_assert( std::is_object<const T>::value, "");
+    static_assert( std::is_object<volatile T>::value, "");
+    static_assert( std::is_object<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_object_v<T>, "");
+    static_assert( std::is_object_v<const T>, "");
+    static_assert( std::is_object_v<volatile T>, "");
+    static_assert( std::is_object_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_object()
+{
+    static_assert(!std::is_object<T>::value, "");
+    static_assert(!std::is_object<const T>::value, "");
+    static_assert(!std::is_object<volatile T>::value, "");
+    static_assert(!std::is_object<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_object_v<T>, "");
+    static_assert(!std::is_object_v<const T>, "");
+    static_assert(!std::is_object_v<volatile T>, "");
+    static_assert(!std::is_object_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+
+typedef void (*FunctionPtr)();
+
+
+int main()
+{
+// 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>();
+    test_is_object<void *>();
+    test_is_object<char[3]>();
+    test_is_object<char[]>();
+    test_is_object<int>();
+    test_is_object<int*>();
+    test_is_object<Union>();
+    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<NotEmpty>();
+    test_is_object<Abstract>();
+    test_is_object<FunctionPtr>();
+    test_is_object<int Empty::*>();
+    test_is_object<void (Empty::*)(int)>();
+
+    test_is_not_object<void>();
+    test_is_not_object<int&>();
+    test_is_not_object<int&&>();
+    test_is_not_object<int(int)>();
+}
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
new file mode 100644
index 0000000..e56c8f7
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_reference.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_reference
+
+#include <type_traits>
+#include <cstddef>         // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_reference()
+{
+    static_assert( std::is_reference<T>::value, "");
+    static_assert( std::is_reference<const T>::value, "");
+    static_assert( std::is_reference<volatile T>::value, "");
+    static_assert( std::is_reference<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_reference_v<T>, "");
+    static_assert( std::is_reference_v<const T>, "");
+    static_assert( std::is_reference_v<volatile T>, "");
+    static_assert( std::is_reference_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_reference()
+{
+    static_assert(!std::is_reference<T>::value, "");
+    static_assert(!std::is_reference<const T>::value, "");
+    static_assert(!std::is_reference<volatile T>::value, "");
+    static_assert(!std::is_reference<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_reference_v<T>, "");
+    static_assert(!std::is_reference_v<const T>, "");
+    static_assert(!std::is_reference_v<volatile T>, "");
+    static_assert(!std::is_reference_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+
+typedef void (*FunctionPtr)();
+
+
+int main()
+{
+    test_is_reference<int&>();
+#if TEST_STD_VER >= 11
+    test_is_reference<int&&>();
+#endif
+
+    test_is_not_reference<std::nullptr_t>();
+    test_is_not_reference<void>();
+    test_is_not_reference<int>();
+    test_is_not_reference<double>();
+    test_is_not_reference<char[3]>();
+    test_is_not_reference<char[]>();
+    test_is_not_reference<void *>();
+    test_is_not_reference<FunctionPtr>();
+    test_is_not_reference<Union>();
+    test_is_not_reference<Empty>();
+    test_is_not_reference<bit_zero>();
+    test_is_not_reference<int*>();
+    test_is_not_reference<const int*>();
+    test_is_not_reference<Enum>();
+    test_is_not_reference<NotEmpty>();
+    test_is_not_reference<Abstract>();
+    test_is_not_reference<int(int)>();
+    test_is_not_reference<int Empty::*>();
+    test_is_not_reference<void (Empty::*)(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
new file mode 100644
index 0000000..2b412a6
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_scalar.pass.cpp
@@ -0,0 +1,111 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The 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_scalar
+
+#include <type_traits>
+#include <cstddef>         // for std::nullptr_t
+#include "test_macros.h"
+
+template <class T>
+void test_is_scalar()
+{
+    static_assert( std::is_scalar<T>::value, "");
+    static_assert( std::is_scalar<const T>::value, "");
+    static_assert( std::is_scalar<volatile T>::value, "");
+    static_assert( std::is_scalar<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_scalar_v<T>, "");
+    static_assert( std::is_scalar_v<const T>, "");
+    static_assert( std::is_scalar_v<volatile T>, "");
+    static_assert( std::is_scalar_v<const volatile T>, "");
+#endif
+}
+
+template <class T>
+void test_is_not_scalar()
+{
+    static_assert(!std::is_scalar<T>::value, "");
+    static_assert(!std::is_scalar<const T>::value, "");
+    static_assert(!std::is_scalar<volatile T>::value, "");
+    static_assert(!std::is_scalar<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_scalar_v<T>, "");
+    static_assert(!std::is_scalar_v<const T>, "");
+    static_assert(!std::is_scalar_v<volatile T>, "");
+    static_assert(!std::is_scalar_v<const volatile T>, "");
+#endif
+}
+
+class Empty
+{
+};
+
+class NotEmpty
+{
+    virtual ~NotEmpty();
+};
+
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+
+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. 
+
+    test_is_scalar<std::nullptr_t>();
+    test_is_scalar<short>();
+    test_is_scalar<unsigned short>();
+    test_is_scalar<int>();
+    test_is_scalar<unsigned int>();
+    test_is_scalar<long>();
+    test_is_scalar<unsigned long>();
+    test_is_scalar<bool>();
+    test_is_scalar<char>();
+    test_is_scalar<signed char>();
+    test_is_scalar<unsigned char>();
+    test_is_scalar<wchar_t>();
+    test_is_scalar<double>();
+    test_is_scalar<int*>();
+    test_is_scalar<const int*>();
+    test_is_scalar<int Empty::*>();
+    test_is_scalar<void (Empty::*)(int)>();
+    test_is_scalar<Enum>();
+    test_is_scalar<FunctionPtr>();
+
+    test_is_not_scalar<void>();
+    test_is_not_scalar<int&>();
+    test_is_not_scalar<int&&>();
+    test_is_not_scalar<char[3]>();
+    test_is_not_scalar<char[]>();
+    test_is_not_scalar<Union>();
+    test_is_not_scalar<Empty>();
+    test_is_not_scalar<bit_zero>();
+    test_is_not_scalar<NotEmpty>();
+    test_is_not_scalar<Abstract>();
+    test_is_not_scalar<int(int)>();
+}
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 685d30d..3602013 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
@@ -20,6 +20,12 @@
     static_assert( std::has_virtual_destructor<const T>::value, "");
     static_assert( std::has_virtual_destructor<volatile T>::value, "");
     static_assert( std::has_virtual_destructor<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::has_virtual_destructor_v<T>, "");
+    static_assert( std::has_virtual_destructor_v<const T>, "");
+    static_assert( std::has_virtual_destructor_v<volatile T>, "");
+    static_assert( std::has_virtual_destructor_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -29,6 +35,12 @@
     static_assert(!std::has_virtual_destructor<const T>::value, "");
     static_assert(!std::has_virtual_destructor<volatile T>::value, "");
     static_assert(!std::has_virtual_destructor<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::has_virtual_destructor_v<T>, "");
+    static_assert(!std::has_virtual_destructor_v<const T>, "");
+    static_assert(!std::has_virtual_destructor_v<volatile T>, "");
+    static_assert(!std::has_virtual_destructor_v<const volatile T>, "");
+#endif
 }
 
 class Empty
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_abstract.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_abstract.pass.cpp
index f2a8c23..a54adf1 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_abstract.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_abstract.pass.cpp
@@ -12,6 +12,7 @@
 // is_abstract
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_abstract()
@@ -20,6 +21,12 @@
     static_assert( std::is_abstract<const T>::value, "");
     static_assert( std::is_abstract<volatile T>::value, "");
     static_assert( std::is_abstract<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_abstract_v<T>, "");
+    static_assert( std::is_abstract_v<const T>, "");
+    static_assert( std::is_abstract_v<volatile T>, "");
+    static_assert( std::is_abstract_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -29,6 +36,12 @@
     static_assert(!std::is_abstract<const T>::value, "");
     static_assert(!std::is_abstract<volatile T>::value, "");
     static_assert(!std::is_abstract<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_abstract_v<T>, "");
+    static_assert(!std::is_abstract_v<const T>, "");
+    static_assert(!std::is_abstract_v<volatile T>, "");
+    static_assert(!std::is_abstract_v<const volatile T>, "");
+#endif
 }
 
 class Empty
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 d33019b..c0f6bb9 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
@@ -12,6 +12,7 @@
 // is_assignable
 
 #include <type_traits>
+#include "test_macros.h"
 
 struct A
 {
@@ -26,12 +27,18 @@
 void test_is_assignable()
 {
     static_assert(( std::is_assignable<T, U>::value), "");
+#if TEST_STD_VER > 14
+    static_assert(  std::is_assignable_v<T, U>, "");
+#endif
 }
 
 template <class T, class U>
 void test_is_not_assignable()
 {
     static_assert((!std::is_assignable<T, U>::value), "");
+#if TEST_STD_VER > 14
+    static_assert( !std::is_assignable_v<T, U>, "");
+#endif
 }
 
 struct 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 72f2ff4..7f63ae4 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
@@ -12,6 +12,7 @@
 // is_const
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_const()
@@ -20,6 +21,12 @@
     static_assert( std::is_const<const T>::value, "");
     static_assert(!std::is_const<volatile T>::value, "");
     static_assert( std::is_const<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_const_v<T>, "");
+    static_assert( std::is_const_v<const T>, "");
+    static_assert(!std::is_const_v<volatile T>, "");
+    static_assert( std::is_const_v<const volatile T>, "");
+#endif
 }
 
 int main()
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 2b8f7ef..57a73ca 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,11 +8,14 @@
 //===----------------------------------------------------------------------===//
 
 // type_traits
+// XFAIL: apple-clang-6.0
+//	The Apple-6 compiler gets is_constructible<void ()> wrong.
 
 // template <class T, class... Args>
 //   struct is_constructible;
 
 #include <type_traits>
+#include "test_macros.h"
 
 struct A
 {
@@ -38,30 +41,45 @@
 void test_is_constructible()
 {
     static_assert( (std::is_constructible<T>::value), "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_constructible_v<T>, "");
+#endif
 }
 
 template <class T, class A0>
 void test_is_constructible()
 {
-    static_assert( (std::is_constructible<T, A0>::value), "");
+    static_assert(( std::is_constructible<T, A0>::value), "");
+#if TEST_STD_VER > 14
+    static_assert(( std::is_constructible_v<T, A0>), "");
+#endif
 }
 
 template <class T, class A0, class A1>
 void test_is_constructible()
 {
-    static_assert( (std::is_constructible<T, A0, A1>::value), "");
+    static_assert(( std::is_constructible<T, A0, A1>::value), "");
+#if TEST_STD_VER > 14
+    static_assert(( std::is_constructible_v<T, A0, A1>), "");
+#endif
 }
 
 template <class T>
 void test_is_not_constructible()
 {
     static_assert((!std::is_constructible<T>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((!std::is_constructible_v<T>), "");
+#endif
 }
 
 template <class T, class A0>
 void test_is_not_constructible()
 {
     static_assert((!std::is_constructible<T, A0>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((!std::is_constructible_v<T, A0>), "");
+#endif
 }
 
 int main()
@@ -83,4 +101,13 @@
     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_VERS > 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 c43d594..421f865 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
@@ -12,17 +12,24 @@
 // is_copy_assignable
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_copy_assignable()
 {
     static_assert(( std::is_copy_assignable<T>::value), "");
+#if TEST_STD_VER > 14
+    static_assert(( std::is_copy_assignable_v<T>), "");
+#endif
 }
 
 template <class T>
 void test_is_not_copy_assignable()
 {
     static_assert((!std::is_copy_assignable<T>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((!std::is_copy_assignable_v<T>), "");
+#endif
 }
 
 class Empty
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 f878a50..fe2e014 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
@@ -12,17 +12,24 @@
 // is_copy_constructible
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_copy_constructible()
 {
     static_assert( std::is_copy_constructible<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_copy_constructible_v<T>, "");
+#endif
 }
 
 template <class T>
 void test_is_not_copy_constructible()
 {
     static_assert(!std::is_copy_constructible<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_copy_constructible_v<T>, "");
+#endif
 }
 
 class Empty
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 c8d5c42..7b46eea 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
@@ -12,6 +12,7 @@
 // is_default_constructible
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_default_constructible()
@@ -20,6 +21,12 @@
     static_assert( std::is_default_constructible<const T>::value, "");
     static_assert( std::is_default_constructible<volatile T>::value, "");
     static_assert( std::is_default_constructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_default_constructible_v<T>, "");
+    static_assert( std::is_default_constructible_v<const T>, "");
+    static_assert( std::is_default_constructible_v<volatile T>, "");
+    static_assert( std::is_default_constructible_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -29,6 +36,12 @@
     static_assert(!std::is_default_constructible<const T>::value, "");
     static_assert(!std::is_default_constructible<volatile T>::value, "");
     static_assert(!std::is_default_constructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_default_constructible_v<T>, "");
+    static_assert(!std::is_default_constructible_v<const T>, "");
+    static_assert(!std::is_default_constructible_v<volatile T>, "");
+    static_assert(!std::is_default_constructible_v<const volatile T>, "");
+#endif
 }
 
 class Empty
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 fae9557..60d607a 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
@@ -12,7 +12,6 @@
 // is_destructible
 
 #include <type_traits>
-
 #include "test_macros.h"
 
 template <class T>
@@ -22,6 +21,12 @@
     static_assert( std::is_destructible<const T>::value, "");
     static_assert( std::is_destructible<volatile T>::value, "");
     static_assert( std::is_destructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_destructible_v<T>, "");
+    static_assert( std::is_destructible_v<const T>, "");
+    static_assert( std::is_destructible_v<volatile T>, "");
+    static_assert( std::is_destructible_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -31,6 +36,12 @@
     static_assert(!std::is_destructible<const T>::value, "");
     static_assert(!std::is_destructible<volatile T>::value, "");
     static_assert(!std::is_destructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_destructible_v<T>, "");
+    static_assert(!std::is_destructible_v<const T>, "");
+    static_assert(!std::is_destructible_v<volatile T>, "");
+    static_assert(!std::is_destructible_v<const volatile T>, "");
+#endif
 }
 
 class Empty {};
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_empty.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_empty.pass.cpp
index 47af3c4..410c1db 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_empty.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_empty.pass.cpp
@@ -12,6 +12,7 @@
 // is_empty
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_empty()
@@ -20,6 +21,12 @@
     static_assert( std::is_empty<const T>::value, "");
     static_assert( std::is_empty<volatile T>::value, "");
     static_assert( std::is_empty<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_empty_v<T>, "");
+    static_assert( std::is_empty_v<const T>, "");
+    static_assert( std::is_empty_v<volatile T>, "");
+    static_assert( std::is_empty_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -29,6 +36,12 @@
     static_assert(!std::is_empty<const T>::value, "");
     static_assert(!std::is_empty<volatile T>::value, "");
     static_assert(!std::is_empty<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_empty_v<T>, "");
+    static_assert(!std::is_empty_v<const T>, "");
+    static_assert(!std::is_empty_v<volatile T>, "");
+    static_assert(!std::is_empty_v<const volatile T>, "");
+#endif
 }
 
 class Empty
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 cf32196..baf85e3 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
@@ -12,6 +12,7 @@
 // is_final
 
 #include <type_traits>
+#include "test_macros.h"
 
 #if _LIBCPP_STD_VER > 11
 
@@ -26,6 +27,12 @@
     static_assert( std::is_final<const T>::value, "");
     static_assert( std::is_final<volatile T>::value, "");
     static_assert( std::is_final<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_final_v<T>, "");
+    static_assert( std::is_final_v<const T>, "");
+    static_assert( std::is_final_v<volatile T>, "");
+    static_assert( std::is_final_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -35,6 +42,12 @@
     static_assert(!std::is_final<const T>::value, "");
     static_assert(!std::is_final<volatile T>::value, "");
     static_assert(!std::is_final<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_final_v<T>, "");
+    static_assert(!std::is_final_v<const T>, "");
+    static_assert(!std::is_final_v<volatile T>, "");
+    static_assert(!std::is_final_v<const volatile T>, "");
+#endif
 }
 
 int main ()
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.pass.cpp
index ce781cd..59aa5e2 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.pass.cpp
@@ -12,35 +12,94 @@
 // is_literal_type
 
 #include <type_traits>
+#include <cstddef>       // for std::nullptr_t
+#include "test_macros.h"
 
 template <class T>
 void test_is_literal_type()
 {
     static_assert( std::is_literal_type<T>::value, "");
+    static_assert( std::is_literal_type<const T>::value, "");
+    static_assert( std::is_literal_type<volatile T>::value, "");
+    static_assert( std::is_literal_type<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_literal_type_v<T>, "");
+    static_assert( std::is_literal_type_v<const T>, "");
+    static_assert( std::is_literal_type_v<volatile T>, "");
+    static_assert( std::is_literal_type_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
 void test_is_not_literal_type()
 {
     static_assert(!std::is_literal_type<T>::value, "");
+    static_assert(!std::is_literal_type<const T>::value, "");
+    static_assert(!std::is_literal_type<volatile T>::value, "");
+    static_assert(!std::is_literal_type<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_literal_type_v<T>, "");
+    static_assert(!std::is_literal_type_v<const T>, "");
+    static_assert(!std::is_literal_type_v<volatile T>, "");
+    static_assert(!std::is_literal_type_v<const volatile T>, "");
+#endif
 }
 
-struct A
+class Empty
 {
 };
 
-struct B
+class NotEmpty
 {
-    B();
+    virtual ~NotEmpty();
 };
 
+union Union {};
+
+struct bit_zero
+{
+    int :  0;
+};
+
+class Abstract
+{
+    virtual ~Abstract() = 0;
+};
+
+enum Enum {zero, one};
+
+typedef void (*FunctionPtr)();
+
 int main()
 {
-    test_is_literal_type<int> ();
-    test_is_literal_type<const int> ();
-    test_is_literal_type<int&> ();
-    test_is_literal_type<volatile int&> ();
-    test_is_literal_type<A> ();
+#if TEST_STD_VER >= 11
+    test_is_literal_type<std::nullptr_t>();
+#endif
 
-    test_is_not_literal_type<B> ();
+// Before C++14, void was not a literal type
+// In C++14, cv-void is is a literal type
+#if TEST_STD_VER < 14
+    test_is_not_literal_type<void>();
+#else
+    test_is_literal_type<void>();
+#endif
+
+    test_is_literal_type<int>();
+    test_is_literal_type<int*>();
+    test_is_literal_type<const int*>();
+    test_is_literal_type<int&>();
+#if TEST_STD_VER >= 11
+    test_is_literal_type<int&&>();
+#endif
+    test_is_literal_type<double>();
+    test_is_literal_type<char[3]>();
+    test_is_literal_type<char[]>();
+    test_is_literal_type<Empty>();
+    test_is_literal_type<bit_zero>();
+    test_is_literal_type<Union>();
+    test_is_literal_type<Enum>();
+    test_is_literal_type<FunctionPtr>();
+
+    test_is_not_literal_type<NotEmpty>();
+    test_is_not_literal_type<Abstract>();
 }
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_assignable.pass.cpp
index a89ee7d..613c112 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_assignable.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_assignable.pass.cpp
@@ -12,17 +12,24 @@
 // is_move_assignable
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_move_assignable()
 {
-    static_assert( std::is_move_assignable<T>::value, "");
+    static_assert(( std::is_move_assignable<T>::value), "");
+#if TEST_STD_VER > 14
+    static_assert(( std::is_move_assignable_v<T>), "");
+#endif
 }
 
 template <class T>
 void test_is_not_move_assignable()
 {
-    static_assert(!std::is_move_assignable<T>::value, "");
+    static_assert((!std::is_move_assignable<T>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((!std::is_move_assignable_v<T>), "");
+#endif
 }
 
 class Empty
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_constructible.pass.cpp
index 7409eba..07c283b 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_constructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_constructible.pass.cpp
@@ -12,17 +12,24 @@
 // is_move_constructible
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_move_constructible()
 {
     static_assert( std::is_move_constructible<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_move_constructible_v<T>, "");
+#endif
 }
 
 template <class T>
 void test_is_not_move_constructible()
 {
     static_assert(!std::is_move_constructible<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_move_constructible_v<T>, "");
+#endif
 }
 
 class Empty
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_assignable.pass.cpp
index 8fff5f8..9d629dc 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_assignable.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_assignable.pass.cpp
@@ -12,17 +12,24 @@
 // is_nothrow_assignable
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T, class U>
 void test_is_nothrow_assignable()
 {
     static_assert(( std::is_nothrow_assignable<T, U>::value), "");
+#if TEST_STD_VER > 14
+    static_assert(( std::is_nothrow_assignable_v<T, U>), "");
+#endif
 }
 
 template <class T, class U>
 void test_is_not_nothrow_assignable()
 {
     static_assert((!std::is_nothrow_assignable<T, U>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((!std::is_nothrow_assignable_v<T, U>), "");
+#endif
 }
 
 struct A
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 fe0b567..c778a5d 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
@@ -13,35 +13,51 @@
 //   struct is_nothrow_constructible;
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_nothrow_constructible()
 {
     static_assert(( std::is_nothrow_constructible<T>::value), "");
+#if TEST_STD_VER > 14
+    static_assert(( std::is_nothrow_constructible_v<T>), "");
+#endif
 }
 
 template <class T, class A0>
 void test_is_nothrow_constructible()
 {
     static_assert(( std::is_nothrow_constructible<T, A0>::value), "");
+#if TEST_STD_VER > 14
+    static_assert(( std::is_nothrow_constructible_v<T, A0>), "");
+#endif
 }
 
 template <class T>
 void test_is_not_nothrow_constructible()
 {
     static_assert((!std::is_nothrow_constructible<T>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((!std::is_nothrow_constructible_v<T>), "");
+#endif
 }
 
 template <class T, class A0>
 void test_is_not_nothrow_constructible()
 {
     static_assert((!std::is_nothrow_constructible<T, A0>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((!std::is_nothrow_constructible_v<T, A0>), "");
+#endif
 }
 
 template <class T, class A0, class A1>
 void test_is_not_nothrow_constructible()
 {
     static_assert((!std::is_nothrow_constructible<T, A0, A1>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((!std::is_nothrow_constructible_v<T, A0, A1>), "");
+#endif
 }
 
 class Empty
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_copy_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_copy_assignable.pass.cpp
index d843803..01c9bd0 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_copy_assignable.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_copy_assignable.pass.cpp
@@ -12,17 +12,24 @@
 // is_nothrow_copy_assignable
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_has_nothrow_assign()
 {
     static_assert( std::is_nothrow_copy_assignable<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_nothrow_copy_assignable_v<T>, "");
+#endif
 }
 
 template <class T>
 void test_has_not_nothrow_assign()
 {
     static_assert(!std::is_nothrow_copy_assignable<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_nothrow_copy_assignable_v<T>, "");
+#endif
 }
 
 class Empty
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_copy_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_copy_constructible.pass.cpp
index 99fce65..9dbdc4e 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_copy_constructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_copy_constructible.pass.cpp
@@ -12,12 +12,17 @@
 // is_nothrow_copy_constructible
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_nothrow_copy_constructible()
 {
     static_assert( std::is_nothrow_copy_constructible<T>::value, "");
     static_assert( std::is_nothrow_copy_constructible<const T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_nothrow_copy_constructible_v<T>, "");
+    static_assert( std::is_nothrow_copy_constructible_v<const T>, "");
+#endif
 }
 
 template <class T>
@@ -27,6 +32,12 @@
     static_assert(!std::is_nothrow_copy_constructible<const T>::value, "");
     static_assert(!std::is_nothrow_copy_constructible<volatile T>::value, "");
     static_assert(!std::is_nothrow_copy_constructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_nothrow_copy_constructible_v<T>, "");
+    static_assert(!std::is_nothrow_copy_constructible_v<const T>, "");
+    static_assert(!std::is_nothrow_copy_constructible_v<volatile T>, "");
+    static_assert(!std::is_nothrow_copy_constructible_v<const volatile T>, "");
+#endif
 }
 
 class Empty
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_default_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_default_constructible.pass.cpp
index 1550dff..c89ac89 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_default_constructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_default_constructible.pass.cpp
@@ -12,6 +12,7 @@
 // is_nothrow_default_constructible
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_nothrow_default_constructible()
@@ -20,6 +21,12 @@
     static_assert( std::is_nothrow_default_constructible<const T>::value, "");
     static_assert( std::is_nothrow_default_constructible<volatile T>::value, "");
     static_assert( std::is_nothrow_default_constructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_nothrow_default_constructible_v<T>, "");
+    static_assert( std::is_nothrow_default_constructible_v<const T>, "");
+    static_assert( std::is_nothrow_default_constructible_v<volatile T>, "");
+    static_assert( std::is_nothrow_default_constructible_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -29,6 +36,12 @@
     static_assert(!std::is_nothrow_default_constructible<const T>::value, "");
     static_assert(!std::is_nothrow_default_constructible<volatile T>::value, "");
     static_assert(!std::is_nothrow_default_constructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_nothrow_default_constructible_v<T>, "");
+    static_assert(!std::is_nothrow_default_constructible_v<const T>, "");
+    static_assert(!std::is_nothrow_default_constructible_v<volatile T>, "");
+    static_assert(!std::is_nothrow_default_constructible_v<const volatile T>, "");
+#endif
 }
 
 class Empty
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 5827c92..42c9807 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
@@ -12,7 +12,6 @@
 // is_nothrow_destructible
 
 #include <type_traits>
-
 #include "test_macros.h"
 
 template <class T>
@@ -22,6 +21,12 @@
     static_assert( std::is_nothrow_destructible<const T>::value, "");
     static_assert( std::is_nothrow_destructible<volatile T>::value, "");
     static_assert( std::is_nothrow_destructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_nothrow_destructible_v<T>, "");
+    static_assert( std::is_nothrow_destructible_v<const T>, "");
+    static_assert( std::is_nothrow_destructible_v<volatile T>, "");
+    static_assert( std::is_nothrow_destructible_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -31,6 +36,12 @@
     static_assert(!std::is_nothrow_destructible<const T>::value, "");
     static_assert(!std::is_nothrow_destructible<volatile T>::value, "");
     static_assert(!std::is_nothrow_destructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_nothrow_destructible_v<T>, "");
+    static_assert(!std::is_nothrow_destructible_v<const T>, "");
+    static_assert(!std::is_nothrow_destructible_v<volatile T>, "");
+    static_assert(!std::is_nothrow_destructible_v<const volatile T>, "");
+#endif
 }
 
 
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_move_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_move_assignable.pass.cpp
index fe51e43..11852f6 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_move_assignable.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_move_assignable.pass.cpp
@@ -12,17 +12,24 @@
 // has_nothrow_move_assign
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_has_nothrow_assign()
 {
     static_assert( std::is_nothrow_move_assignable<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_nothrow_move_assignable_v<T>, "");
+#endif
 }
 
 template <class T>
 void test_has_not_nothrow_assign()
 {
     static_assert(!std::is_nothrow_move_assignable<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_nothrow_move_assignable_v<T>, "");
+#endif
 }
 
 class Empty
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_move_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_move_constructible.pass.cpp
index f5a42af..b93dbb6 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_move_constructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_move_constructible.pass.cpp
@@ -12,12 +12,17 @@
 // has_nothrow_move_constructor
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_nothrow_move_constructible()
 {
     static_assert( std::is_nothrow_move_constructible<T>::value, "");
     static_assert( std::is_nothrow_move_constructible<const T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_nothrow_move_constructible_v<T>, "");
+    static_assert( std::is_nothrow_move_constructible_v<const T>, "");
+#endif
 }
 
 template <class T>
@@ -27,6 +32,12 @@
     static_assert(!std::is_nothrow_move_constructible<const T>::value, "");
     static_assert(!std::is_nothrow_move_constructible<volatile T>::value, "");
     static_assert(!std::is_nothrow_move_constructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_nothrow_move_constructible_v<T>, "");
+    static_assert(!std::is_nothrow_move_constructible_v<const T>, "");
+    static_assert(!std::is_nothrow_move_constructible_v<volatile T>, "");
+    static_assert(!std::is_nothrow_move_constructible_v<const volatile T>, "");
+#endif
 }
 
 class Empty
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 0000000..2465987
--- /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&&) {}
+};
+
+} // 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 0000000..54c0a04
--- /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 presense 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_pod.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_pod.pass.cpp
index 4ec1ae9..2ca2b86 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_pod.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_pod.pass.cpp
@@ -12,6 +12,7 @@
 // is_pod
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_pod()
@@ -20,6 +21,12 @@
     static_assert( std::is_pod<const T>::value, "");
     static_assert( std::is_pod<volatile T>::value, "");
     static_assert( std::is_pod<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_pod_v<T>, "");
+    static_assert( std::is_pod_v<const T>, "");
+    static_assert( std::is_pod_v<volatile T>, "");
+    static_assert( std::is_pod_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -29,6 +36,12 @@
     static_assert(!std::is_pod<const T>::value, "");
     static_assert(!std::is_pod<volatile T>::value, "");
     static_assert(!std::is_pod<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_pod_v<T>, "");
+    static_assert(!std::is_pod_v<const T>, "");
+    static_assert(!std::is_pod_v<volatile T>, "");
+    static_assert(!std::is_pod_v<const volatile T>, "");
+#endif
 }
 
 class Class
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 6e82cdd..b66e7a2 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
@@ -12,6 +12,7 @@
 // is_polymorphic
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_polymorphic()
@@ -20,6 +21,12 @@
     static_assert( std::is_polymorphic<const T>::value, "");
     static_assert( std::is_polymorphic<volatile T>::value, "");
     static_assert( std::is_polymorphic<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_polymorphic_v<T>, "");
+    static_assert( std::is_polymorphic_v<const T>, "");
+    static_assert( std::is_polymorphic_v<volatile T>, "");
+    static_assert( std::is_polymorphic_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -29,6 +36,12 @@
     static_assert(!std::is_polymorphic<const T>::value, "");
     static_assert(!std::is_polymorphic<volatile T>::value, "");
     static_assert(!std::is_polymorphic<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_polymorphic_v<T>, "");
+    static_assert(!std::is_polymorphic_v<const T>, "");
+    static_assert(!std::is_polymorphic_v<volatile T>, "");
+    static_assert(!std::is_polymorphic_v<const volatile T>, "");
+#endif
 }
 
 class Empty
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 479c252..94bf7fb 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
@@ -12,6 +12,7 @@
 // is_signed
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_signed()
@@ -20,6 +21,12 @@
     static_assert( std::is_signed<const T>::value, "");
     static_assert( std::is_signed<volatile T>::value, "");
     static_assert( std::is_signed<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_signed_v<T>, "");
+    static_assert( std::is_signed_v<const T>, "");
+    static_assert( std::is_signed_v<volatile T>, "");
+    static_assert( std::is_signed_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -29,6 +36,12 @@
     static_assert(!std::is_signed<const T>::value, "");
     static_assert(!std::is_signed<volatile T>::value, "");
     static_assert(!std::is_signed<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_signed_v<T>, "");
+    static_assert(!std::is_signed_v<const T>, "");
+    static_assert(!std::is_signed_v<volatile T>, "");
+    static_assert(!std::is_signed_v<const volatile T>, "");
+#endif
 }
 
 class Class
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_standard_layout.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_standard_layout.pass.cpp
index 668c4cd..6e601c1 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_standard_layout.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_standard_layout.pass.cpp
@@ -12,6 +12,7 @@
 // is_standard_layout
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_standard_layout()
@@ -20,6 +21,12 @@
     static_assert( std::is_standard_layout<const T>::value, "");
     static_assert( std::is_standard_layout<volatile T>::value, "");
     static_assert( std::is_standard_layout<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_standard_layout_v<T>, "");
+    static_assert( std::is_standard_layout_v<const T>, "");
+    static_assert( std::is_standard_layout_v<volatile T>, "");
+    static_assert( std::is_standard_layout_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -29,6 +36,12 @@
     static_assert(!std::is_standard_layout<const T>::value, "");
     static_assert(!std::is_standard_layout<volatile T>::value, "");
     static_assert(!std::is_standard_layout<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_standard_layout_v<T>, "");
+    static_assert(!std::is_standard_layout_v<const T>, "");
+    static_assert(!std::is_standard_layout_v<volatile T>, "");
+    static_assert(!std::is_standard_layout_v<const volatile T>, "");
+#endif
 }
 
 template <class T1, class T2>
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 0000000..43a0a4f
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler 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&&) {}
+
+} // namespace MyNS
+
+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 for presense 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 0000000..cfe5906
--- /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[42][50];
+    {
+        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 + 42, 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 0000000..9d470c1
--- /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_trivial.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivial.pass.cpp
index af38699..2d2df14 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivial.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivial.pass.cpp
@@ -12,6 +12,7 @@
 // is_trivial
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_trivial()
@@ -20,6 +21,12 @@
     static_assert( std::is_trivial<const T>::value, "");
     static_assert( std::is_trivial<volatile T>::value, "");
     static_assert( std::is_trivial<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_trivial_v<T>, "");
+    static_assert( std::is_trivial_v<const T>, "");
+    static_assert( std::is_trivial_v<volatile T>, "");
+    static_assert( std::is_trivial_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -29,6 +36,12 @@
     static_assert(!std::is_trivial<const T>::value, "");
     static_assert(!std::is_trivial<volatile T>::value, "");
     static_assert(!std::is_trivial<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_trivial_v<T>, "");
+    static_assert(!std::is_trivial_v<const T>, "");
+    static_assert(!std::is_trivial_v<volatile T>, "");
+    static_assert(!std::is_trivial_v<const volatile T>, "");
+#endif
 }
 
 struct A {};
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 735d05f..a9b538b 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,18 +11,27 @@
 
 // is_trivially_assignable
 
+// XFAIL: gcc-4.9
+
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T, class U>
 void test_is_trivially_assignable()
 {
     static_assert(( std::is_trivially_assignable<T, U>::value), "");
+#if TEST_STD_VER > 14
+    static_assert(( std::is_trivially_assignable_v<T, U>), "");
+#endif
 }
 
 template <class T, class U>
 void test_is_not_trivially_assignable()
 {
     static_assert((!std::is_trivially_assignable<T, U>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((!std::is_trivially_assignable_v<T, U>), "");
+#endif
 }
 
 struct A
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_constructible.pass.cpp
index 4171d4d..212245f 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_constructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_constructible.pass.cpp
@@ -13,35 +13,51 @@
 //   struct is_trivially_constructible;
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_trivially_constructible()
 {
     static_assert(( std::is_trivially_constructible<T>::value), "");
+#if TEST_STD_VER > 14
+    static_assert(( std::is_trivially_constructible_v<T>), "");
+#endif
 }
 
 template <class T, class A0>
 void test_is_trivially_constructible()
 {
     static_assert(( std::is_trivially_constructible<T, A0>::value), "");
+#if TEST_STD_VER > 14
+    static_assert(( std::is_trivially_constructible_v<T, A0>), "");
+#endif
 }
 
 template <class T>
 void test_is_not_trivially_constructible()
 {
     static_assert((!std::is_trivially_constructible<T>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((!std::is_trivially_constructible_v<T>), "");
+#endif
 }
 
 template <class T, class A0>
 void test_is_not_trivially_constructible()
 {
     static_assert((!std::is_trivially_constructible<T, A0>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((!std::is_trivially_constructible_v<T, A0>), "");
+#endif
 }
 
 template <class T, class A0, class A1>
 void test_is_not_trivially_constructible()
 {
     static_assert((!std::is_trivially_constructible<T, A0, A1>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((!std::is_trivially_constructible_v<T, A0, A1>), "");
+#endif
 }
 
 struct A
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 7d72565..966573c 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,18 +11,27 @@
 
 // is_trivially_copy_assignable
 
+// XFAIL: gcc-4.9
+
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_has_trivially_copy_assignable()
 {
     static_assert( std::is_trivially_copy_assignable<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_trivially_copy_assignable_v<T>, "");
+#endif
 }
 
 template <class T>
 void test_has_not_trivially_copy_assignable()
 {
     static_assert(!std::is_trivially_copy_assignable<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_trivially_copy_assignable_v<T>, "");
+#endif
 }
 
 class Empty
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 6bd78ec..2922f22 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,13 +11,20 @@
 
 // is_trivially_copy_constructible
 
+// XFAIL: gcc-4.9
+
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_trivially_copy_constructible()
 {
     static_assert( std::is_trivially_copy_constructible<T>::value, "");
     static_assert( std::is_trivially_copy_constructible<const T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_trivially_copy_constructible_v<T>, "");
+    static_assert( std::is_trivially_copy_constructible_v<const T>, "");
+#endif
 }
 
 template <class T>
@@ -25,6 +32,10 @@
 {
     static_assert(!std::is_trivially_copy_constructible<T>::value, "");
     static_assert(!std::is_trivially_copy_constructible<const T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_trivially_copy_constructible_v<T>, "");
+    static_assert(!std::is_trivially_copy_constructible_v<const T>, "");
+#endif
 }
 
 class Empty
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 d658823..42ecdb3 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,8 +11,11 @@
 
 // is_trivially_copyable
 
+// XFAIL: gcc-4.9
+
 #include <type_traits>
 #include <cassert>
+#include "test_macros.h"
 
 template <class T>
 void test_is_trivially_copyable()
@@ -21,6 +24,12 @@
     static_assert( std::is_trivially_copyable<const T>::value, "");
     static_assert(!std::is_trivially_copyable<volatile T>::value, "");
     static_assert(!std::is_trivially_copyable<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_trivially_copyable_v<T>, "");
+    static_assert( std::is_trivially_copyable_v<const T>, "");
+    static_assert(!std::is_trivially_copyable_v<volatile T>, "");
+    static_assert(!std::is_trivially_copyable_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -30,6 +39,12 @@
     static_assert(!std::is_trivially_copyable<const T>::value, "");
     static_assert(!std::is_trivially_copyable<volatile T>::value, "");
     static_assert(!std::is_trivially_copyable<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_trivially_copyable_v<T>, "");
+    static_assert(!std::is_trivially_copyable_v<const T>, "");
+    static_assert(!std::is_trivially_copyable_v<volatile T>, "");
+    static_assert(!std::is_trivially_copyable_v<const volatile T>, "");
+#endif
 }
 
 struct A
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_default_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_default_constructible.pass.cpp
index 1f63401..2d36715 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_default_constructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_default_constructible.pass.cpp
@@ -12,6 +12,7 @@
 // is_trivially_default_constructible
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_trivially_default_constructible()
@@ -20,6 +21,12 @@
     static_assert( std::is_trivially_default_constructible<const T>::value, "");
     static_assert( std::is_trivially_default_constructible<volatile T>::value, "");
     static_assert( std::is_trivially_default_constructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_trivially_default_constructible_v<T>, "");
+    static_assert( std::is_trivially_default_constructible_v<const T>, "");
+    static_assert( std::is_trivially_default_constructible_v<volatile T>, "");
+    static_assert( std::is_trivially_default_constructible_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -29,6 +36,12 @@
     static_assert(!std::is_trivially_default_constructible<const T>::value, "");
     static_assert(!std::is_trivially_default_constructible<volatile T>::value, "");
     static_assert(!std::is_trivially_default_constructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_trivially_default_constructible_v<T>, "");
+    static_assert(!std::is_trivially_default_constructible_v<const T>, "");
+    static_assert(!std::is_trivially_default_constructible_v<volatile T>, "");
+    static_assert(!std::is_trivially_default_constructible_v<const volatile T>, "");
+#endif
 }
 
 class Empty
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 0908f8b..9e25070 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
@@ -12,7 +12,6 @@
 // is_trivially_destructible
 
 #include <type_traits>
-
 #include "test_macros.h"
 
 template <class T>
@@ -22,6 +21,12 @@
     static_assert( std::is_trivially_destructible<const T>::value, "");
     static_assert( std::is_trivially_destructible<volatile T>::value, "");
     static_assert( std::is_trivially_destructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_trivially_destructible_v<T>, "");
+    static_assert( std::is_trivially_destructible_v<const T>, "");
+    static_assert( std::is_trivially_destructible_v<volatile T>, "");
+    static_assert( std::is_trivially_destructible_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -31,6 +36,12 @@
     static_assert(!std::is_trivially_destructible<const T>::value, "");
     static_assert(!std::is_trivially_destructible<volatile T>::value, "");
     static_assert(!std::is_trivially_destructible<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_trivially_destructible_v<T>, "");
+    static_assert(!std::is_trivially_destructible_v<const T>, "");
+    static_assert(!std::is_trivially_destructible_v<volatile T>, "");
+    static_assert(!std::is_trivially_destructible_v<const volatile T>, "");
+#endif
 }
 
 struct PublicDestructor           { public:     ~PublicDestructor() {}};
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 c3fc7ac..9a27c73 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,18 +11,27 @@
 
 // is_trivially_move_assignable
 
+// XFAIL: gcc-4.9
+
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_has_trivial_assign()
 {
     static_assert( std::is_trivially_move_assignable<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_trivially_move_assignable_v<T>, "");
+#endif
 }
 
 template <class T>
 void test_has_not_trivial_assign()
 {
     static_assert(!std::is_trivially_move_assignable<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_trivially_move_assignable_v<T>, "");
+#endif
 }
 
 class Empty
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 54cb5e8..941ff31 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,18 +11,27 @@
 
 // is_trivially_move_constructible
 
+// XFAIL: gcc-4.9
+
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_trivially_move_constructible()
 {
     static_assert( std::is_trivially_move_constructible<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_trivially_move_constructible_v<T>, "");
+#endif
 }
 
 template <class T>
 void test_has_not_trivial_move_constructor()
 {
     static_assert(!std::is_trivially_move_constructible<T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_trivially_move_constructible_v<T>, "");
+#endif
 }
 
 class Empty
@@ -53,7 +62,7 @@
     A(const A&);
 };
 
-#if __has_feature(cxx_defaulted_functions)
+#if TEST_STD_VER >= 11
 
 struct MoveOnly1
 {
@@ -82,7 +91,7 @@
     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 dfdb155..9ca4243 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
@@ -12,6 +12,7 @@
 // is_unsigned
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_unsigned()
@@ -20,6 +21,12 @@
     static_assert( std::is_unsigned<const T>::value, "");
     static_assert( std::is_unsigned<volatile T>::value, "");
     static_assert( std::is_unsigned<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert( std::is_unsigned_v<T>, "");
+    static_assert( std::is_unsigned_v<const T>, "");
+    static_assert( std::is_unsigned_v<volatile T>, "");
+    static_assert( std::is_unsigned_v<const volatile T>, "");
+#endif
 }
 
 template <class T>
@@ -29,6 +36,12 @@
     static_assert(!std::is_unsigned<const T>::value, "");
     static_assert(!std::is_unsigned<volatile T>::value, "");
     static_assert(!std::is_unsigned<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_unsigned_v<T>, "");
+    static_assert(!std::is_unsigned_v<const T>, "");
+    static_assert(!std::is_unsigned_v<volatile T>, "");
+    static_assert(!std::is_unsigned_v<const volatile T>, "");
+#endif
 }
 
 class Class
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 f6805bc..36697a3 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
@@ -12,6 +12,7 @@
 // is_volatile
 
 #include <type_traits>
+#include "test_macros.h"
 
 template <class T>
 void test_is_volatile()
@@ -20,6 +21,12 @@
     static_assert(!std::is_volatile<const T>::value, "");
     static_assert( std::is_volatile<volatile T>::value, "");
     static_assert( std::is_volatile<const volatile T>::value, "");
+#if TEST_STD_VER > 14
+    static_assert(!std::is_volatile_v<T>, "");
+    static_assert(!std::is_volatile_v<const T>, "");
+    static_assert( std::is_volatile_v<volatile T>, "");
+    static_assert( std::is_volatile_v<const volatile T>, "");
+#endif
 }
 
 int main()
diff --git a/test/std/utilities/ratio/ratio.comparison/ratio_equal.pass.cpp b/test/std/utilities/ratio/ratio.comparison/ratio_equal.pass.cpp
index 78027f7..9331b70 100644
--- a/test/std/utilities/ratio/ratio.comparison/ratio_equal.pass.cpp
+++ b/test/std/utilities/ratio/ratio.comparison/ratio_equal.pass.cpp
@@ -11,46 +11,57 @@
 
 #include <ratio>
 
+#include "test_macros.h"
+
+template <class Rat1, class Rat2, bool result>
+void test()
+{
+    static_assert((result == std::ratio_equal<Rat1, Rat2>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((result == std::ratio_equal_v<Rat1, Rat2>), "");
+#endif
+}
+
 int main()
 {
     {
     typedef std::ratio<1, 1> R1;
     typedef std::ratio<1, 1> R2;
-    static_assert((std::ratio_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((std::ratio_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((std::ratio_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R1;
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R2;
-    static_assert((std::ratio_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<1, 1> R1;
     typedef std::ratio<1, -1> R2;
-    static_assert((!std::ratio_equal<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((!std::ratio_equal<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((!std::ratio_equal<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R1;
     typedef std::ratio<1, -0x7FFFFFFFFFFFFFFFLL> R2;
-    static_assert((!std::ratio_equal<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
 }
diff --git a/test/std/utilities/ratio/ratio.comparison/ratio_greater.pass.cpp b/test/std/utilities/ratio/ratio.comparison/ratio_greater.pass.cpp
index 9182a9e..7f7a740 100644
--- a/test/std/utilities/ratio/ratio.comparison/ratio_greater.pass.cpp
+++ b/test/std/utilities/ratio/ratio.comparison/ratio_greater.pass.cpp
@@ -11,46 +11,57 @@
 
 #include <ratio>
 
+#include "test_macros.h"
+
+template <class Rat1, class Rat2, bool result>
+void test()
+{
+    static_assert((result == std::ratio_greater<Rat1, Rat2>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((result == std::ratio_greater_v<Rat1, Rat2>), "");
+#endif
+}
+
 int main()
 {
     {
     typedef std::ratio<1, 1> R1;
     typedef std::ratio<1, 1> R2;
-    static_assert((!std::ratio_greater<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((!std::ratio_greater<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((!std::ratio_greater<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R1;
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R2;
-    static_assert((!std::ratio_greater<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<1, 1> R1;
     typedef std::ratio<1, -1> R2;
-    static_assert((std::ratio_greater<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((std::ratio_greater<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((!std::ratio_greater<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R1;
     typedef std::ratio<1, -0x7FFFFFFFFFFFFFFFLL> R2;
-    static_assert((std::ratio_greater<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
 }
diff --git a/test/std/utilities/ratio/ratio.comparison/ratio_greater_equal.pass.cpp b/test/std/utilities/ratio/ratio.comparison/ratio_greater_equal.pass.cpp
index a1f5a18..db78557 100644
--- a/test/std/utilities/ratio/ratio.comparison/ratio_greater_equal.pass.cpp
+++ b/test/std/utilities/ratio/ratio.comparison/ratio_greater_equal.pass.cpp
@@ -11,46 +11,57 @@
 
 #include <ratio>
 
+#include "test_macros.h"
+
+template <class Rat1, class Rat2, bool result>
+void test()
+{
+    static_assert((result == std::ratio_greater_equal<Rat1, Rat2>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((result == std::ratio_greater_equal_v<Rat1, Rat2>), "");
+#endif
+}
+
 int main()
 {
     {
     typedef std::ratio<1, 1> R1;
     typedef std::ratio<1, 1> R2;
-    static_assert((std::ratio_greater_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((std::ratio_greater_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((std::ratio_greater_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R1;
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R2;
-    static_assert((std::ratio_greater_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<1, 1> R1;
     typedef std::ratio<1, -1> R2;
-    static_assert((std::ratio_greater_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((std::ratio_greater_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((!std::ratio_greater_equal<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R1;
     typedef std::ratio<1, -0x7FFFFFFFFFFFFFFFLL> R2;
-    static_assert((std::ratio_greater_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
 }
diff --git a/test/std/utilities/ratio/ratio.comparison/ratio_less.pass.cpp b/test/std/utilities/ratio/ratio.comparison/ratio_less.pass.cpp
index db53ab0..a428be2 100644
--- a/test/std/utilities/ratio/ratio.comparison/ratio_less.pass.cpp
+++ b/test/std/utilities/ratio/ratio.comparison/ratio_less.pass.cpp
@@ -11,76 +11,87 @@
 
 #include <ratio>
 
+#include "test_macros.h"
+
+template <class Rat1, class Rat2, bool result>
+void test()
+{
+    static_assert((result == std::ratio_less<Rat1, Rat2>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((result == std::ratio_less_v<Rat1, Rat2>), "");
+#endif
+}
+
 int main()
 {
     {
     typedef std::ratio<1, 1> R1;
     typedef std::ratio<1, 1> R2;
-    static_assert((!std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((!std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((!std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R1;
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R2;
-    static_assert((!std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<1, 1> R1;
     typedef std::ratio<1, -1> R2;
-    static_assert((!std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((!std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R1;
     typedef std::ratio<1, -0x7FFFFFFFFFFFFFFFLL> R2;
-    static_assert((!std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFELL> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFDLL, 0x7FFFFFFFFFFFFFFCLL> R2;
-    static_assert((std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFDLL, 0x7FFFFFFFFFFFFFFCLL> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFELL> R2;
-    static_assert((!std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<-0x7FFFFFFFFFFFFFFDLL, 0x7FFFFFFFFFFFFFFCLL> R1;
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFELL> R2;
-    static_assert((std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFELL> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFELL, 0x7FFFFFFFFFFFFFFDLL> R2;
-    static_assert((std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<641981, 1339063> R1;
     typedef std::ratio<1291640, 2694141LL> R2;
-    static_assert((!std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<1291640, 2694141LL> R1;
     typedef std::ratio<641981, 1339063> R2;
-    static_assert((std::ratio_less<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
 }
diff --git a/test/std/utilities/ratio/ratio.comparison/ratio_less_equal.pass.cpp b/test/std/utilities/ratio/ratio.comparison/ratio_less_equal.pass.cpp
index 5b148f0..7b224ab 100644
--- a/test/std/utilities/ratio/ratio.comparison/ratio_less_equal.pass.cpp
+++ b/test/std/utilities/ratio/ratio.comparison/ratio_less_equal.pass.cpp
@@ -11,46 +11,57 @@
 
 #include <ratio>
 
+#include "test_macros.h"
+
+template <class Rat1, class Rat2, bool result>
+void test()
+{
+    static_assert((result == std::ratio_less_equal<Rat1, Rat2>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((result == std::ratio_less_equal_v<Rat1, Rat2>), "");
+#endif
+}
+
 int main()
 {
     {
     typedef std::ratio<1, 1> R1;
     typedef std::ratio<1, 1> R2;
-    static_assert((std::ratio_less_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((std::ratio_less_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((std::ratio_less_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R1;
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R2;
-    static_assert((std::ratio_less_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<1, 1> R1;
     typedef std::ratio<1, -1> R2;
-    static_assert((!std::ratio_less_equal<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((!std::ratio_less_equal<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((std::ratio_less_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R1;
     typedef std::ratio<1, -0x7FFFFFFFFFFFFFFFLL> R2;
-    static_assert((!std::ratio_less_equal<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
 }
diff --git a/test/std/utilities/ratio/ratio.comparison/ratio_not_equal.pass.cpp b/test/std/utilities/ratio/ratio.comparison/ratio_not_equal.pass.cpp
index ebf9307..fcd3120 100644
--- a/test/std/utilities/ratio/ratio.comparison/ratio_not_equal.pass.cpp
+++ b/test/std/utilities/ratio/ratio.comparison/ratio_not_equal.pass.cpp
@@ -11,46 +11,57 @@
 
 #include <ratio>
 
+#include "test_macros.h"
+
+template <class Rat1, class Rat2, bool result>
+void test()
+{
+    static_assert((result == std::ratio_not_equal<Rat1, Rat2>::value), "");
+#if TEST_STD_VER > 14
+    static_assert((result == std::ratio_not_equal_v<Rat1, Rat2>), "");
+#endif
+}
+
 int main()
 {
     {
     typedef std::ratio<1, 1> R1;
     typedef std::ratio<1, 1> R2;
-    static_assert((!std::ratio_not_equal<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((!std::ratio_not_equal<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((!std::ratio_not_equal<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R1;
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R2;
-    static_assert((!std::ratio_not_equal<R1, R2>::value), "");
+    test<R1, R2, false>();
     }
     {
     typedef std::ratio<1, 1> R1;
     typedef std::ratio<1, -1> R2;
-    static_assert((std::ratio_not_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((std::ratio_not_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<-0x7FFFFFFFFFFFFFFFLL, 1> R1;
     typedef std::ratio<0x7FFFFFFFFFFFFFFFLL, 1> R2;
-    static_assert((std::ratio_not_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
     {
     typedef std::ratio<1, 0x7FFFFFFFFFFFFFFFLL> R1;
     typedef std::ratio<1, -0x7FFFFFFFFFFFFFFFLL> R2;
-    static_assert((std::ratio_not_equal<R1, R2>::value), "");
+    test<R1, R2, true>();
     }
 }
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 df5ec4a..1743405 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,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // template <class charT>
 //     explicit bitset(const charT* str,
 //                     typename basic_string<charT>::size_type n = basic_string<charT>::npos,
@@ -17,7 +18,9 @@
 #include <algorithm> // for 'min' and 'max'
 #include <stdexcept> // for 'invalid_argument'
 
+#if defined(__clang__)
 #pragma clang diagnostic ignored "-Wtautological-compare"
+#endif
 
 template <std::size_t N>
 void test_char_pointer_ctor()
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 bd5ca7e..2162f34 100644
--- a/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.cons/default.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_default_ctor()
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 98083f8..a040a37 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,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // test bitset(string, pos, n, zero, one);
 
 #include <bitset>
@@ -14,7 +15,9 @@
 #include <algorithm> // for 'min' and 'max'
 #include <stdexcept> // for 'invalid_argument'
 
+#if defined(__clang__)
 #pragma clang diagnostic ignored "-Wtautological-compare"
+#endif
 
 template <std::size_t N>
 void test_string_ctor()
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 f232447..4ba312b 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,7 +13,9 @@
 #include <cassert>
 #include <algorithm> // for 'min' and 'max'
 
+#if defined(__clang__)
 #pragma clang diagnostic ignored "-Wtautological-compare"
+#endif
 
 template <std::size_t N>
 void test_val_ctor()
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 fb9ce64..c8a14c9 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 6c4f5c6..a25e5bd 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 3e09b20..453c82b 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
@@ -7,13 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // test bitset<N>& flip(size_t pos);
 
 #include <bitset>
 #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.pass.cpp b/test/std/utilities/template.bitset/bitset.members/index.pass.cpp
index b96aaa5..02e58a7 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 e3c28c6..870a504 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 7fe9fa7..57b77d2 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 bed3e28..3adab77 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 2f8f711..d9fbb3e 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 b599ec3..64ca15f 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 5f6cf3d..24761c6 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 6e63879..f2880f6 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 e68a641..4209967 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 ee44d92..eed25e2 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 ebaa9e7..5e67739 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
@@ -7,13 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // test bitset<N>& reset(size_t pos);
 
 #include <bitset>
 #include <cassert>
 
+#if defined(__clang__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wtautological-compare"
+#endif
 
 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 87fcc28..180fa84 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 1dd89c1..47494fc 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 56454a8..e5c3e25 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/set_one.pass.cpp b/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp
index 116eaf3..debe543 100644
--- a/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // test bitset<N>& set(size_t pos, bool val = true);
 
 #include <bitset>
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 5102b46..1566106 100644
--- a/test/std/utilities/template.bitset/bitset.members/test.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.members/test.pass.cpp
@@ -7,13 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: libcpp-no-exceptions
 // test constexpr bool test(size_t pos) const;
 
 #include <bitset>
 #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/to_string.pass.cpp b/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp
index b657940..5b2958c 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 751cee6..80792d9 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 fda5e5c..65a7004 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 067f868..dcabaa4 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/date.time/tested_elsewhere.pass.cpp b/test/std/utilities/time/date.time/ctime.pass.cpp
similarity index 83%
rename from test/std/utilities/date.time/tested_elsewhere.pass.cpp
rename to test/std/utilities/time/date.time/ctime.pass.cpp
index 419f415..b762d27 100644
--- a/test/std/utilities/date.time/tested_elsewhere.pass.cpp
+++ b/test/std/utilities/time/date.time/ctime.pass.cpp
@@ -21,18 +21,24 @@
 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};
     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), "");
     static_assert((std::is_same<decltype(std::time(&t)), std::time_t>::value), "");
+#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
     static_assert((std::is_same<decltype(std::asctime(&tm)), char*>::value), "");
     static_assert((std::is_same<decltype(std::ctime(&t)), char*>::value), "");
     static_assert((std::is_same<decltype(std::gmtime(&t)), std::tm*>::value), "");
     static_assert((std::is_same<decltype(std::localtime(&t)), std::tm*>::value), "");
+#endif
     static_assert((std::is_same<decltype(std::strftime(str,s,"",&tm)), std::size_t>::value), "");
 }
diff --git a/test/std/utilities/time/time.duration/time.duration.alg/abs.fail.cpp b/test/std/utilities/time/time.duration/time.duration.alg/abs.fail.cpp
new file mode 100644
index 0000000..221004c
--- /dev/null
+++ b/test/std/utilities/time/time.duration/time.duration.alg/abs.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++03, c++11, c++14
+// <chrono>
+
+// ceil
+
+// template <class Rep, class Period>
+//   constexpr duration<Rep, Period> abs(duration<Rep, Period> d)
+
+// This function shall not participate in overload resolution unless numeric_limits<Rep>::is_signed is true.
+
+#include <chrono>
+
+typedef std::chrono::duration<unsigned> unsigned_secs;
+
+int main()
+{
+    std::chrono::abs(unsigned_secs(0));
+}
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
new file mode 100644
index 0000000..ec32c37
--- /dev/null
+++ b/test/std/utilities/time/time.duration/time.duration.alg/abs.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++03, c++11, c++14
+
+// <chrono>
+
+// abs
+
+// template <class Rep, class Period>
+//   constexpr duration<Rep, Period> abs(duration<Rep, Period> d)
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+template <class Duration>
+void
+test(const Duration& f, const Duration& d)
+{
+    {
+    typedef decltype(std::chrono::abs(f)) R;
+    static_assert((std::is_same<R, Duration>::value), "");
+    assert(std::chrono::abs(f) == d);
+    }
+}
+
+int main()
+{
+//  7290000ms is 2 hours, 1 minute, and 30 seconds
+    test(std::chrono::milliseconds( 7290000), std::chrono::milliseconds( 7290000));
+    test(std::chrono::milliseconds(-7290000), std::chrono::milliseconds( 7290000));
+    test(std::chrono::minutes( 122), std::chrono::minutes( 122));
+    test(std::chrono::minutes(-122), std::chrono::minutes( 122));
+    test(std::chrono::hours(0), std::chrono::hours(0));
+
+    {
+//  9000000ms is 2 hours and 30 minutes
+    constexpr std::chrono::hours h1 = std::chrono::abs(std::chrono::hours(-3));
+    static_assert(h1.count() == 3, "");
+    constexpr std::chrono::hours h2 = std::chrono::abs(std::chrono::hours(3));
+    static_assert(h2.count() == 3, "");
+    }
+}
diff --git a/test/std/utilities/time/time.duration/time.duration.cast/ceil.fail.cpp b/test/std/utilities/time/time.duration/time.duration.cast/ceil.fail.cpp
new file mode 100644
index 0000000..909e857
--- /dev/null
+++ b/test/std/utilities/time/time.duration/time.duration.cast/ceil.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++03, c++11, c++14
+// <chrono>
+
+// ceil
+
+// template <class ToDuration, class Rep, class Period>
+//   ToDuration
+//   ceil(const duration<Rep, Period>& d);
+
+// ToDuration shall be an instantiation of duration.
+
+#include <chrono>
+
+int main()
+{
+    std::chrono::ceil<int>(std::chrono::milliseconds(3));
+}
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
new file mode 100644
index 0000000..6fb73b9
--- /dev/null
+++ b/test/std/utilities/time/time.duration/time.duration.cast/ceil.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++03, c++11, c++14
+
+// <chrono>
+
+// ceil
+
+// template <class ToDuration, class Rep, class Period>
+//   constexpr
+//   ToDuration
+//   ceil(const duration<Rep, Period>& d);
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+template <class ToDuration, class FromDuration>
+void
+test(const FromDuration& f, const ToDuration& d)
+{
+    {
+    typedef decltype(std::chrono::ceil<ToDuration>(f)) R;
+    static_assert((std::is_same<R, ToDuration>::value), "");
+    assert(std::chrono::ceil<ToDuration>(f) == d);
+    }
+}
+
+int main()
+{
+//  7290000ms is 2 hours, 1 minute, and 30 seconds
+    test(std::chrono::milliseconds( 7290000), std::chrono::hours( 3));
+    test(std::chrono::milliseconds(-7290000), std::chrono::hours(-2));
+    test(std::chrono::milliseconds( 7290000), std::chrono::minutes( 122));
+    test(std::chrono::milliseconds(-7290000), std::chrono::minutes(-121));
+
+    {
+//  9000000ms is 2 hours and 30 minutes
+    constexpr std::chrono::hours h1 = std::chrono::ceil<std::chrono::hours>(std::chrono::milliseconds(9000000));
+    static_assert(h1.count() == 3, "");
+    constexpr std::chrono::hours h2 = std::chrono::ceil<std::chrono::hours>(std::chrono::milliseconds(-9000000));
+    static_assert(h2.count() == -2, "");
+    }
+}
diff --git a/test/std/utilities/time/time.duration/time.duration.cast/floor.fail.cpp b/test/std/utilities/time/time.duration/time.duration.cast/floor.fail.cpp
new file mode 100644
index 0000000..14d9ca8
--- /dev/null
+++ b/test/std/utilities/time/time.duration/time.duration.cast/floor.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++03, c++11, c++14
+// <chrono>
+
+// floor
+
+// template <class ToDuration, class Rep, class Period>
+//   ToDuration
+//   floor(const duration<Rep, Period>& d);
+
+// ToDuration shall be an instantiation of duration.
+
+#include <chrono>
+
+int main()
+{
+    std::chrono::floor<int>(std::chrono::milliseconds(3));
+}
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
new file mode 100644
index 0000000..57929dd
--- /dev/null
+++ b/test/std/utilities/time/time.duration/time.duration.cast/floor.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++03, c++11, c++14
+// <chrono>
+
+// floor
+
+// template <class ToDuration, class Rep, class Period>
+//   constexpr
+//   ToDuration
+//   floor(const duration<Rep, Period>& d);
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+template <class ToDuration, class FromDuration>
+void
+test(const FromDuration& f, const ToDuration& d)
+{
+    {
+    typedef decltype(std::chrono::floor<ToDuration>(f)) R;
+    static_assert((std::is_same<R, ToDuration>::value), "");
+    assert(std::chrono::floor<ToDuration>(f) == d);
+    }
+}
+
+int main()
+{
+//  7290000ms is 2 hours, 1 minute, and 30 seconds
+    test(std::chrono::milliseconds( 7290000), std::chrono::hours( 2));
+    test(std::chrono::milliseconds(-7290000), std::chrono::hours(-3));
+    test(std::chrono::milliseconds( 7290000), std::chrono::minutes( 121));
+    test(std::chrono::milliseconds(-7290000), std::chrono::minutes(-122));
+
+    {
+//  9000000ms is 2 hours and 30 minutes
+    constexpr std::chrono::hours h1 = std::chrono::floor<std::chrono::hours>(std::chrono::milliseconds(9000000));
+    static_assert(h1.count() == 2, "");
+    constexpr std::chrono::hours h2 = std::chrono::floor<std::chrono::hours>(std::chrono::milliseconds(-9000000));
+    static_assert(h2.count() == -3, "");
+    }
+}
diff --git a/test/std/utilities/time/time.duration/time.duration.cast/round.fail.cpp b/test/std/utilities/time/time.duration/time.duration.cast/round.fail.cpp
new file mode 100644
index 0000000..6f9f5bd
--- /dev/null
+++ b/test/std/utilities/time/time.duration/time.duration.cast/round.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++03, c++11, c++14
+// <chrono>
+
+// round
+
+// template <class ToDuration, class Rep, class Period>
+//   ToDuration
+//   round(const duration<Rep, Period>& d);
+
+// ToDuration shall be an instantiation of duration.
+
+#include <chrono>
+
+int main()
+{
+    std::chrono::round<int>(std::chrono::milliseconds(3));
+}
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
new file mode 100644
index 0000000..e50b85c
--- /dev/null
+++ b/test/std/utilities/time/time.duration/time.duration.cast/round.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++03, c++11, c++14
+// <chrono>
+
+// round
+
+// template <class ToDuration, class Rep, class Period>
+//   constexpr
+//   ToDuration
+//   ceil(const duration<Rep, Period>& d);
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+template <class ToDuration, class FromDuration>
+void
+test(const FromDuration& f, const ToDuration& d)
+{
+    {
+    typedef decltype(std::chrono::round<ToDuration>(f)) R;
+    static_assert((std::is_same<R, ToDuration>::value), "");
+    assert(std::chrono::round<ToDuration>(f) == d);
+    }
+}
+
+int main()
+{
+//  7290000ms is 2 hours, 1 minute, and 30 seconds
+    test(std::chrono::milliseconds( 7290000), std::chrono::hours( 2));
+    test(std::chrono::milliseconds(-7290000), std::chrono::hours(-2));
+    test(std::chrono::milliseconds( 7290000), std::chrono::minutes( 122));
+    test(std::chrono::milliseconds(-7290000), std::chrono::minutes(-122));
+
+    {
+//  9000000ms is 2 hours and 30 minutes
+    constexpr std::chrono::hours h1 = std::chrono::round<std::chrono::hours>(std::chrono::milliseconds(9000000));
+    static_assert(h1.count() == 2, "");
+    constexpr std::chrono::hours h2 = std::chrono::round<std::chrono::hours>(std::chrono::milliseconds(-9000000));
+    static_assert(h2.count() == -2, "");
+    }
+}
diff --git a/test/std/utilities/time/time.point/time.point.cast/ceil.fail.cpp b/test/std/utilities/time/time.point/time.point.cast/ceil.fail.cpp
new file mode 100644
index 0000000..1c92d75
--- /dev/null
+++ b/test/std/utilities/time/time.point/time.point.cast/ceil.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++03, c++11, c++14
+// <chrono>
+
+// ceil
+
+// template <class ToDuration, class Clock, class Duration>
+//   time_point<Clock, ToDuration>
+//   ceil(const time_point<Clock, Duration>& t);
+
+// ToDuration shall be an instantiation of duration.
+
+#include <chrono>
+
+int main()
+{
+    std::chrono::ceil<int>(std::chrono::system_clock::now());
+}
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
new file mode 100644
index 0000000..379929c
--- /dev/null
+++ b/test/std/utilities/time/time.point/time.point.cast/ceil.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++03, c++11, c++14
+// <chrono>
+
+// ceil
+
+// template <class ToDuration, class Clock, class Duration>
+//   time_point<Clock, ToDuration>
+//   ceil(const time_point<Clock, Duration>& t);
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+template <class FromDuration, class ToDuration>
+void
+test(const FromDuration& df, const ToDuration& d)
+{
+    typedef std::chrono::system_clock Clock;
+    typedef std::chrono::time_point<Clock, FromDuration> FromTimePoint;
+    typedef std::chrono::time_point<Clock, ToDuration> ToTimePoint;
+    {
+    FromTimePoint f(df);
+    ToTimePoint t(d);
+    typedef decltype(std::chrono::ceil<ToDuration>(f)) R;
+    static_assert((std::is_same<R, ToTimePoint>::value), "");
+    assert(std::chrono::ceil<ToDuration>(f) == t);
+    }
+}
+
+template<class FromDuration, long long From, class ToDuration, long long To>
+void test_constexpr ()
+{
+    typedef std::chrono::system_clock Clock;
+    typedef std::chrono::time_point<Clock, FromDuration> FromTimePoint;
+    typedef std::chrono::time_point<Clock, ToDuration> ToTimePoint;
+    {
+    constexpr FromTimePoint f{FromDuration{From}};
+    constexpr ToTimePoint   t{ToDuration{To}};
+    static_assert(std::chrono::ceil<ToDuration>(f) == t, "");
+    }
+}
+
+
+int main()
+{
+//  7290000ms is 2 hours, 1 minute, and 30 seconds
+    test(std::chrono::milliseconds( 7290000), std::chrono::hours( 3));
+    test(std::chrono::milliseconds(-7290000), std::chrono::hours(-2));
+    test(std::chrono::milliseconds( 7290000), std::chrono::minutes( 122));
+    test(std::chrono::milliseconds(-7290000), std::chrono::minutes(-121));
+
+//  9000000ms is 2 hours and 30 minutes
+    test_constexpr<std::chrono::milliseconds, 9000000, std::chrono::hours,    3> ();
+    test_constexpr<std::chrono::milliseconds,-9000000, std::chrono::hours,   -2> ();
+    test_constexpr<std::chrono::milliseconds, 9000001, std::chrono::minutes, 151> ();
+    test_constexpr<std::chrono::milliseconds,-9000001, std::chrono::minutes,-150> ();
+
+    test_constexpr<std::chrono::milliseconds, 9000000, std::chrono::seconds, 9000> ();
+    test_constexpr<std::chrono::milliseconds,-9000000, std::chrono::seconds,-9000> ();
+}
diff --git a/test/std/utilities/time/time.point/time.point.cast/floor.fail.cpp b/test/std/utilities/time/time.point/time.point.cast/floor.fail.cpp
new file mode 100644
index 0000000..ea48e12
--- /dev/null
+++ b/test/std/utilities/time/time.point/time.point.cast/floor.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++03, c++11, c++14
+// <chrono>
+
+// floor
+
+// template <class ToDuration, class Clock, class Duration>
+//   time_point<Clock, ToDuration>
+//   floor(const time_point<Clock, Duration>& t);
+
+// ToDuration shall be an instantiation of duration.
+
+#include <chrono>
+
+int main()
+{
+    std::chrono::floor<int>(std::chrono::system_clock::now());
+}
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
new file mode 100644
index 0000000..d0a908f
--- /dev/null
+++ b/test/std/utilities/time/time.point/time.point.cast/floor.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++03, c++11, c++14
+// <chrono>
+
+// floor
+
+// template <class ToDuration, class Clock, class Duration>
+//   time_point<Clock, ToDuration>
+//   floor(const time_point<Clock, Duration>& t);
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+template <class FromDuration, class ToDuration>
+void
+test(const FromDuration& df, const ToDuration& d)
+{
+    typedef std::chrono::system_clock Clock;
+    typedef std::chrono::time_point<Clock, FromDuration> FromTimePoint;
+    typedef std::chrono::time_point<Clock, ToDuration> ToTimePoint;
+    {
+    FromTimePoint f(df);
+    ToTimePoint t(d);
+    typedef decltype(std::chrono::floor<ToDuration>(f)) R;
+    static_assert((std::is_same<R, ToTimePoint>::value), "");
+    assert(std::chrono::floor<ToDuration>(f) == t);
+    }
+}
+
+template<class FromDuration, long long From, class ToDuration, long long To>
+void test_constexpr ()
+{
+    typedef std::chrono::system_clock Clock;
+    typedef std::chrono::time_point<Clock, FromDuration> FromTimePoint;
+    typedef std::chrono::time_point<Clock, ToDuration> ToTimePoint;
+    {
+    constexpr FromTimePoint f{FromDuration{From}};
+    constexpr ToTimePoint   t{ToDuration{To}};
+    static_assert(std::chrono::floor<ToDuration>(f) == t, "");
+    }
+}
+
+int main()
+{
+//  7290000ms is 2 hours, 1 minute, and 30 seconds
+    test(std::chrono::milliseconds( 7290000), std::chrono::hours( 2));
+    test(std::chrono::milliseconds(-7290000), std::chrono::hours(-3));
+    test(std::chrono::milliseconds( 7290000), std::chrono::minutes( 121));
+    test(std::chrono::milliseconds(-7290000), std::chrono::minutes(-122));
+
+//  9000000ms is 2 hours and 30 minutes
+    test_constexpr<std::chrono::milliseconds, 9000000, std::chrono::hours,    2> ();
+    test_constexpr<std::chrono::milliseconds,-9000000, std::chrono::hours,   -3> ();
+    test_constexpr<std::chrono::milliseconds, 9000001, std::chrono::minutes, 150> ();
+    test_constexpr<std::chrono::milliseconds,-9000001, std::chrono::minutes,-151> ();
+
+    test_constexpr<std::chrono::milliseconds, 9000000, std::chrono::seconds, 9000> ();
+    test_constexpr<std::chrono::milliseconds,-9000000, std::chrono::seconds,-9000> ();
+}
diff --git a/test/std/utilities/time/time.point/time.point.cast/round.fail.cpp b/test/std/utilities/time/time.point/time.point.cast/round.fail.cpp
new file mode 100644
index 0000000..53c14f4
--- /dev/null
+++ b/test/std/utilities/time/time.point/time.point.cast/round.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++03, c++11, c++14
+// <chrono>
+
+// round
+
+// template <class ToDuration, class Clock, class Duration>
+//   time_point<Clock, ToDuration>
+//   round(const time_point<Clock, Duration>& t);
+
+// ToDuration shall be an instantiation of duration.
+
+#include <chrono>
+
+int main()
+{
+    std::chrono::round<int>(std::chrono::system_clock::now());
+}
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
new file mode 100644
index 0000000..ab8bf3a
--- /dev/null
+++ b/test/std/utilities/time/time.point/time.point.cast/round.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++03, c++11, c++14
+// <chrono>
+
+// round
+
+// template <class ToDuration, class Clock, class Duration>
+//   time_point<Clock, ToDuration>
+//   round(const time_point<Clock, Duration>& t);
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+template <class FromDuration, class ToDuration>
+void
+test(const FromDuration& df, const ToDuration& d)
+{
+    typedef std::chrono::system_clock Clock;
+    typedef std::chrono::time_point<Clock, FromDuration> FromTimePoint;
+    typedef std::chrono::time_point<Clock, ToDuration> ToTimePoint;
+    {
+    FromTimePoint f(df);
+    ToTimePoint t(d);
+    typedef decltype(std::chrono::round<ToDuration>(f)) R;
+    static_assert((std::is_same<R, ToTimePoint>::value), "");
+    assert(std::chrono::round<ToDuration>(f) == t);
+    }
+}
+
+template<class FromDuration, long long From, class ToDuration, long long To>
+void test_constexpr ()
+{
+    typedef std::chrono::system_clock Clock;
+    typedef std::chrono::time_point<Clock, FromDuration> FromTimePoint;
+    typedef std::chrono::time_point<Clock, ToDuration> ToTimePoint;
+    {
+    constexpr FromTimePoint f{FromDuration{From}};
+    constexpr ToTimePoint   t{ToDuration{To}};
+    static_assert(std::chrono::round<ToDuration>(f) == t, "");
+    }
+}
+
+int main()
+{
+//  7290000ms is 2 hours, 1 minute, and 30 seconds
+    test(std::chrono::milliseconds( 7290000), std::chrono::hours( 2));
+    test(std::chrono::milliseconds(-7290000), std::chrono::hours(-2));
+    test(std::chrono::milliseconds( 7290000), std::chrono::minutes( 122));
+    test(std::chrono::milliseconds(-7290000), std::chrono::minutes(-122));
+
+//  9000000ms is 2 hours and 30 minutes
+    test_constexpr<std::chrono::milliseconds, 9000000, std::chrono::hours,    2> ();
+    test_constexpr<std::chrono::milliseconds,-9000000, std::chrono::hours,   -2> ();
+    test_constexpr<std::chrono::milliseconds, 9000001, std::chrono::minutes, 150> ();
+    test_constexpr<std::chrono::milliseconds,-9000001, std::chrono::minutes,-150> ();
+
+    test_constexpr<std::chrono::milliseconds, 9000000, std::chrono::seconds, 9000> ();
+    test_constexpr<std::chrono::milliseconds,-9000000, std::chrono::seconds,-9000> ();
+}
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 c32350f..f9ddc87 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
@@ -20,6 +20,10 @@
 {
     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> >), "");
+#endif
 }
 
 struct A {};
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 0000000..4ddfb46
--- /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 0000000..ed3cafa
--- /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/alloc.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp
index 3977682..c69163d 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
@@ -24,12 +24,28 @@
 #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()
 {
     {
         std::tuple<> t(std::allocator_arg, A1<int>());
     }
     {
+        DerivedFromAllocArgT tag;
+        std::tuple<> t(tag, A1<int>());
+    }
+    {
         std::tuple<int> t(std::allocator_arg, A1<int>());
         assert(std::get<0>(t) == 0);
     }
@@ -78,4 +94,29 @@
         assert(!alloc_last::allocator_constructed);
         assert(std::get<2>(t) == alloc_last());
     }
+    {
+        // Test that allocator construction is selected when the user provides
+        // a custom tag type which derives from allocator_arg_t.
+        DerivedFromAllocArgT tag;
+        alloc_first::allocator_constructed = false;
+        alloc_last::allocator_constructed = false;
+
+        std::tuple<DefaultOnly, alloc_first, alloc_last> t(tag, A1<int>(5));
+
+        assert(std::get<0>(t) == DefaultOnly());
+        assert(alloc_first::allocator_constructed);
+        assert(std::get<1>(t) == alloc_first());
+        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 3929965..e174e9b 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 @@
 
         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 @@
 
         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 @@
         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 @@
         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());
+        // 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));
     }
-    {
-        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 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 0000000..b28ad6d
--- /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 0f68926..73d53a4 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 0000000..ccf0883
--- /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 8acfde7..36d9f32 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 @@
         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 0000000..d3539ce
--- /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 c862d3b..d3a6add 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 @@
     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 @@
         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/const_Types.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp
index 00e2af2..b72f0fc 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 bbadf8d..e787e87 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,9 +53,36 @@
     { 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);
     }
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 5ad4f92..e176bc8 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_;
@@ -115,4 +125,14 @@
         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 3a6abd3..8423f5d 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 @@
         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 0cda968..1bd7d6d 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 @@
     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.creation/forward_as_tuple.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp
index 0e556b1..26c3da7 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, "");
 }
@@ -57,7 +57,7 @@
 #if _LIBCPP_STD_VER > 11
 template <class Tuple>
 constexpr int 
-test3(const Tuple& t)
+test3(const Tuple&)
 {
     return std::tuple_size<Tuple>::value;
 }
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const_rv.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const_rv.fail.cpp
new file mode 100644
index 0000000..58df2df
--- /dev/null
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const_rv.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>
+//   const typename tuple_element<I, tuple<Types...> >::type&&
+//   get(const tuple<Types...>&& t);
+
+// UNSUPPORTED: c++98, c++03
+
+#include <tuple>
+
+template <class T> void cref(T const&) {};
+template <class T> void cref(T const&&) = delete;
+
+std::tuple<int> const tup4() { return std::make_tuple(4); }
+
+int main()
+{
+    // LWG2485: tuple should not open a hole in the type system, get() should
+    // imitate [expr.ref]'s rules for accessing data members
+    {
+        cref(std::get<0>(tup4()));  // expected-error {{call to deleted function 'cref'}}
+    }
+}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const_rv.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const_rv.pass.cpp
new file mode 100644
index 0000000..720a906
--- /dev/null
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const_rv.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// template <size_t I, class... Types>
+//   const typename tuple_element<I, tuple<Types...> >::type&&
+//   get(const tuple<Types...>&& t);
+
+// UNSUPPORTED: c++98, c++03
+
+#include <tuple>
+#include <utility>
+#include <string>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+    {
+    typedef std::tuple<int> T;
+    const T t(3);
+    static_assert(std::is_same<const int&&, decltype(std::get<0>(std::move(t)))>::value, "");
+    static_assert(noexcept(std::get<0>(std::move(t))), "");
+    const int&& i = std::get<0>(std::move(t));
+    assert(i == 3);
+    }
+
+    {
+    typedef std::tuple<std::string, int> T;
+    const T t("high", 5);
+    static_assert(std::is_same<const std::string&&, decltype(std::get<0>(std::move(t)))>::value, "");
+    static_assert(noexcept(std::get<0>(std::move(t))), "");
+    static_assert(std::is_same<const int&&, decltype(std::get<1>(std::move(t)))>::value, "");
+    static_assert(noexcept(std::get<1>(std::move(t))), "");
+    const std::string&& s = std::get<0>(std::move(t));
+    const int&& i = std::get<1>(std::move(t));
+    assert(s == "high");
+    assert(i == 5);
+    }
+
+    {
+    int x = 42;
+    int const y = 43;
+    std::tuple<int&, int const&> const p(x, y);
+    static_assert(std::is_same<int&, decltype(std::get<0>(std::move(p)))>::value, "");
+    static_assert(noexcept(std::get<0>(std::move(p))), "");
+    static_assert(std::is_same<int const&, decltype(std::get<1>(std::move(p)))>::value, "");
+    static_assert(noexcept(std::get<1>(std::move(p))), "");
+    }
+
+    {
+    int x = 42;
+    int const y = 43;
+    std::tuple<int&&, int const&&> const p(std::move(x), std::move(y));
+    static_assert(std::is_same<int&&, decltype(std::get<0>(std::move(p)))>::value, "");
+    static_assert(noexcept(std::get<0>(std::move(p))), "");
+    static_assert(std::is_same<int const&&, decltype(std::get<1>(std::move(p)))>::value, "");
+    static_assert(noexcept(std::get<1>(std::move(p))), "");
+    }
+
+#if TEST_STD_VER > 11
+    {
+    typedef std::tuple<double, int> T;
+    constexpr const T t(2.718, 5);
+    static_assert(std::get<0>(std::move(t)) == 2.718, "");
+    static_assert(std::get<1>(std::move(t)) == 5, "");
+    }
+#endif
+}
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 aa020da..01ee1ca 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
@@ -10,30 +10,32 @@
 // UNSUPPORTED: c++98, c++03, c++11
 
 #include <tuple>
+#include <utility>
+#include <memory>
 #include <string>
 #include <complex>
+#include <type_traits>
 
 #include <cassert>
 
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     typedef std::complex<float> cf;
     {
     auto t1 = std::tuple<int, std::string, cf> { 42, "Hi", { 1,2 }};
-    assert ( std::get<int>(t1) == 42 ); // find at the beginning 
+    assert ( std::get<int>(t1) == 42 ); // find at the beginning
     assert ( std::get<std::string>(t1) == "Hi" ); // find in the middle
     assert ( std::get<cf>(t1).real() == 1 ); // find at the end
     assert ( std::get<cf>(t1).imag() == 2 );
     }
-    
+
     {
     auto t2 = std::tuple<int, std::string, int, cf> { 42, "Hi", 23, { 1,2 }};
 //  get<int> would fail!
     assert ( std::get<std::string>(t2) == "Hi" );
     assert (( std::get<cf>(t2) == cf{ 1,2 } ));
     }
-    
+
     {
     constexpr std::tuple<int, const int, double, double> p5 { 1, 2, 3.4, 5.6 };
     static_assert ( std::get<int>(p5) == 1, "" );
@@ -53,8 +55,40 @@
     std::tuple<upint> t(upint(new int(4)));
     upint p = std::get<upint>(std::move(t)); // get rvalue
     assert(*p == 4);
-    assert(std::get<0>(t) == nullptr); // has been moved from
+    assert(std::get<upint>(t) == nullptr); // has been moved from
     }
 
-#endif
+    {
+    typedef std::unique_ptr<int> upint;
+    const std::tuple<upint> t(upint(new int(4)));
+    const upint&& p = std::get<upint>(std::move(t)); // get const rvalue
+    assert(*p == 4);
+    assert(std::get<upint>(t) != nullptr);
+    }
+
+    {
+    int x = 42;
+    int y = 43;
+    std::tuple<int&, int const&> const t(x, y);
+    static_assert(std::is_same<int&, decltype(std::get<int&>(std::move(t)))>::value, "");
+    static_assert(noexcept(std::get<int&>(std::move(t))), "");
+    static_assert(std::is_same<int const&, decltype(std::get<int const&>(std::move(t)))>::value, "");
+    static_assert(noexcept(std::get<int const&>(std::move(t))), "");
+    }
+
+    {
+    int x = 42;
+    int y = 43;
+    std::tuple<int&&, int const&&> const t(std::move(x), std::move(y));
+    static_assert(std::is_same<int&&, decltype(std::get<int&&>(std::move(t)))>::value, "");
+    static_assert(noexcept(std::get<int&&>(std::move(t))), "");
+    static_assert(std::is_same<int const&&, decltype(std::get<int const&&>(std::move(t)))>::value, "");
+    static_assert(noexcept(std::get<int const&&>(std::move(t))), "");
+    }
+
+    {
+    constexpr const std::tuple<int, const int, double, double> t { 1, 2, 3.4, 5.6 };
+    static_assert(std::get<int>(std::move(t)) == 1, "");
+    static_assert(std::get<const int>(std::move(t)) == 2, "");
+    }
 }
diff --git a/test/std/utilities/utility/as_const/as_const.fail.cpp b/test/std/utilities/utility/as_const/as_const.fail.cpp
new file mode 100644
index 0000000..6334e14
--- /dev/null
+++ b/test/std/utilities/utility/as_const/as_const.fail.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, c++11, c++14
+
+// template <class T> constexpr add_const<T>& as_const(T& t) noexcept;      // C++17
+// template <class T>           add_const<T>& as_const(const T&&) = delete; // C++17
+
+#include <utility>
+
+struct S {int i;};
+
+int main()
+{
+	std::as_const(S{});
+}
diff --git a/test/std/utilities/utility/as_const/as_const.pass.cpp b/test/std/utilities/utility/as_const/as_const.pass.cpp
new file mode 100644
index 0000000..ff3f84a
--- /dev/null
+++ b/test/std/utilities/utility/as_const/as_const.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, c++14
+
+// template <class T> constexpr add_const<T>& as_const(T& t) noexcept;      // C++17
+// template <class T>           add_const<T>& as_const(const T&&) = delete; // C++17
+
+#include <utility>
+#include <cassert>
+
+struct S {int i;};
+bool operator==(const S& x, const S& y) { return x.i == y.i; }
+bool operator==(const volatile S& x, const volatile S& y) { return x.i == y.i; }
+
+template<typename T>
+void test(T& t)
+{
+    static_assert(std::is_const<typename std::remove_reference<decltype(std::as_const                  (t))>::type>::value, "");
+    static_assert(std::is_const<typename std::remove_reference<decltype(std::as_const<               T>(t))>::type>::value, "");
+    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);
+    assert(std::as_const<volatile       T>(t) == t);
+    assert(std::as_const<const volatile T>(t) == t);
+}
+
+int main()
+{
+	int i = 3;
+	double d = 4.0;
+	S s{2};
+	test(i);
+	test(d);
+	test(s);
+}
diff --git a/test/std/utilities/utility/forward/forward.pass.cpp b/test/std/utilities/utility/forward/forward.pass.cpp
index 357b36f..9457548 100644
--- a/test/std/utilities/utility/forward/forward.pass.cpp
+++ b/test/std/utilities/utility/forward/forward.pass.cpp
@@ -39,6 +39,9 @@
     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_rv.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/get_const_rv.pass.cpp
new file mode 100644
index 0000000..edd2f3d
--- /dev/null
+++ b/test/std/utilities/utility/pairs/pair.astuple/get_const_rv.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// template<size_t I, class T1, class T2>
+//     const typename tuple_element<I, std::pair<T1, T2> >::type&&
+//     get(const pair<T1, T2>&&);
+
+// UNSUPPORTED: c++98, c++03
+
+#include <utility>
+#include <memory>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+    {
+    typedef std::pair<std::unique_ptr<int>, short> P;
+    const P p(std::unique_ptr<int>(new int(3)), 4);
+    static_assert(std::is_same<const std::unique_ptr<int>&&, decltype(std::get<0>(std::move(p)))>::value, "");
+    static_assert(noexcept(std::get<0>(std::move(p))), "");
+    const std::unique_ptr<int>&& ptr = std::get<0>(std::move(p));
+    assert(*ptr == 3);
+    }
+
+    {
+    int x = 42;
+    int const y = 43;
+    std::pair<int&, int const&> const p(x, y);
+    static_assert(std::is_same<int&, decltype(std::get<0>(std::move(p)))>::value, "");
+    static_assert(noexcept(std::get<0>(std::move(p))), "");
+    static_assert(std::is_same<int const&, decltype(std::get<1>(std::move(p)))>::value, "");
+    static_assert(noexcept(std::get<1>(std::move(p))), "");
+    }
+
+    {
+    int x = 42;
+    int const y = 43;
+    std::pair<int&&, int const&&> const p(std::move(x), std::move(y));
+    static_assert(std::is_same<int&&, decltype(std::get<0>(std::move(p)))>::value, "");
+    static_assert(noexcept(std::get<0>(std::move(p))), "");
+    static_assert(std::is_same<int const&&, decltype(std::get<1>(std::move(p)))>::value, "");
+    static_assert(noexcept(std::get<1>(std::move(p))), "");
+    }
+
+#if TEST_STD_VER > 11
+    {
+    typedef std::pair<int, short> P;
+    constexpr const P p1(3, 4);
+    static_assert(std::get<0>(std::move(p1)) == 3, "");
+    static_assert(std::get<1>(std::move(p1)) == 4, "");
+    }
+#endif
+}
diff --git a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type.pass.cpp
index 176d583..f4a6232 100644
--- a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type.pass.cpp
+++ b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type.pass.cpp
@@ -7,15 +7,18 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: c++98, c++03, c++11
+
 #include <utility>
 #include <string>
+#include <type_traits>
 #include <complex>
+#include <memory>
 
 #include <cassert>
 
 int main()
 {
-#if _LIBCPP_STD_VER > 11
     typedef std::complex<float> cf;
     {
     auto t1 = std::make_pair<int, cf> ( 42, { 1,2 } );
@@ -23,7 +26,7 @@
     assert ( std::get<cf>(t1).real() == 1 );
     assert ( std::get<cf>(t1).imag() == 2 );
     }
-    
+
     {
     const std::pair<int, const int> p1 { 1, 2 };
     const int &i1 = std::get<int>(p1);
@@ -35,10 +38,48 @@
     {
     typedef std::unique_ptr<int> upint;
     std::pair<upint, int> t(upint(new int(4)), 42);
-    upint p = std::get<0>(std::move(t)); // get rvalue
+    upint p = std::get<upint>(std::move(t)); // get rvalue
     assert(*p == 4);
-    assert(std::get<0>(t) == nullptr); // has been moved from
+    assert(std::get<upint>(t) == nullptr); // has been moved from
     }
 
-#endif
+    {
+    typedef std::unique_ptr<int> upint;
+    const std::pair<upint, int> t(upint(new int(4)), 42);
+    static_assert(std::is_same<const upint&&, decltype(std::get<upint>(std::move(t)))>::value, "");
+    static_assert(noexcept(std::get<upint>(std::move(t))), "");
+    static_assert(std::is_same<const int&&, decltype(std::get<int>(std::move(t)))>::value, "");
+    static_assert(noexcept(std::get<int>(std::move(t))), "");
+    auto&& p = std::get<upint>(std::move(t)); // get const rvalue
+    auto&& i = std::get<int>(std::move(t)); // get const rvalue
+    assert(*p == 4);
+    assert(i == 42);
+    assert(std::get<upint>(t) != nullptr);
+    }
+
+    {
+    int x = 42;
+    int const y = 43;
+    std::pair<int&, int const&> const p(x, y);
+    static_assert(std::is_same<int&, decltype(std::get<int&>(std::move(p)))>::value, "");
+    static_assert(noexcept(std::get<int&>(std::move(p))), "");
+    static_assert(std::is_same<int const&, decltype(std::get<int const&>(std::move(p)))>::value, "");
+    static_assert(noexcept(std::get<int const&>(std::move(p))), "");
+    }
+
+    {
+    int x = 42;
+    int const y = 43;
+    std::pair<int&&, int const&&> const p(std::move(x), std::move(y));
+    static_assert(std::is_same<int&&, decltype(std::get<int&&>(std::move(p)))>::value, "");
+    static_assert(noexcept(std::get<int&&>(std::move(p))), "");
+    static_assert(std::is_same<int const&&, decltype(std::get<int const&&>(std::move(p)))>::value, "");
+    static_assert(noexcept(std::get<int const&&>(std::move(p))), "");
+    }
+
+    {
+    constexpr const std::pair<int, const int> p { 1, 2 };
+    static_assert(std::get<int>(std::move(p)) == 1, "");
+    static_assert(std::get<const int>(std::move(p)) == 2, "");
+    }
 }
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 4b54f71..d16313f 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
@@ -13,9 +13,14 @@
 
 // pair(const pair&) = default;
 
+// Doesn't pass due to use of is_trivially_* trait.
+// XFAIL: gcc-4.9
+
 #include <utility>
 #include <cassert>
 
+#include "test_macros.h"
+
 int main()
 {
     {
@@ -28,7 +33,7 @@
 
     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-sfinae.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/default-sfinae.pass.cpp
new file mode 100644
index 0000000..8f9fc66
--- /dev/null
+++ b/test/std/utilities/utility/pairs/pairs.pair/default-sfinae.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// Test the SFINAE required by LWG Issue #2367.
+// is_default_constructible<pair>
+
+// UNSUPPORTED: c++98, c++03
+
+#include <utility>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+#if TEST_STD_VER > 11
+#define CONSTEXPR_CXX14 constexpr
+#define STATIC_ASSERT_CXX14(Pred) static_assert(Pred, "")
+#else
+#define CONSTEXPR_CXX14
+#define STATIC_ASSERT_CXX14(Pred) assert(Pred)
+#endif
+
+struct DeletedDefault {
+    // A class with a deleted default constructor. Used to test the SFINAE
+    // on std::pairs default constructor.
+    constexpr explicit DeletedDefault(int x) : value(x) {}
+    constexpr DeletedDefault() = delete;
+    int value;
+};
+
+template <class Tp, bool>
+struct DependantType: public Tp {};
+
+template <class T, bool Val>
+using DependantIsDefault = DependantType<std::is_default_constructible<T>, Val>;
+
+template <class T>
+struct DefaultSFINAES {
+    template <bool Dummy = false, class = typename std::enable_if<
+             DependantIsDefault<T, Dummy>::value
+                >::type
+            >
+    constexpr DefaultSFINAES() : value() {}
+    constexpr explicit DefaultSFINAES(T const& x) : value(x) {}
+    T value;
+};
+
+struct NoDefault {
+    constexpr NoDefault(int v) : value(v) {}
+    int value;
+};
+
+template <class Tp>
+void test_not_is_default_constructible()
+{
+    {
+        typedef std::pair<int, Tp> P;
+        static_assert(!std::is_default_constructible<P>::value, "");
+        static_assert(std::is_constructible<P, int, Tp>::value, "");
+    }
+    {
+        typedef std::pair<Tp, int> P;
+        static_assert(!std::is_default_constructible<P>::value, "");
+        static_assert(std::is_constructible<P, Tp, int>::value, "");
+    }
+    {
+        typedef std::pair<Tp, Tp> P;
+        static_assert(!std::is_default_constructible<P>::value, "");
+        static_assert(std::is_constructible<P, Tp, Tp>::value, "");
+    }
+}
+
+template <class Tp>
+void test_is_default_constructible()
+{
+    {
+        typedef std::pair<int, Tp> P;
+        static_assert(std::is_default_constructible<P>::value, "");
+    }
+    {
+        typedef std::pair<Tp, int> P;
+        static_assert(std::is_default_constructible<P>::value, "");
+    }
+    {
+        typedef std::pair<Tp, Tp> P;
+        static_assert(std::is_default_constructible<P>::value, "");
+    }
+}
+
+template <class T>
+struct IllFormedDefaultImp {
+  constexpr explicit IllFormedDefaultImp(int v) : value(v) {}
+  constexpr IllFormedDefaultImp() : value(T::DoesNotExistAndShouldNotCompile) {}
+  int value;
+};
+
+typedef IllFormedDefaultImp<int> IllFormedDefault;
+    // A class which provides a constexpr default constructor with a valid
+    // signature but an ill-formed body. The A compile error will be emitted if
+    // the default constructor is instantiated.
+
+
+// Check that the SFINAE on the default constructor is not evaluated when
+// it isn't needed. If the default constructor of 'IllFormedDefault' is evaluated
+// in C++11, even with is_default_constructible, then this test should fail to
+// compile. In C++14 and greater evaluate each test is evaluated as a constant
+// expression.
+// See LWG issue #2367
+void test_illformed_default()
+{
+    {
+    typedef std::pair<IllFormedDefault, int> P;
+    static_assert((std::is_constructible<P, IllFormedDefault, int>::value), "");
+    CONSTEXPR_CXX14 P p(IllFormedDefault(42), -5);
+    STATIC_ASSERT_CXX14(p.first.value == 42 && p.second == -5);
+    }
+    {
+    typedef std::pair<int, IllFormedDefault> P;
+    static_assert((std::is_constructible<P, int, IllFormedDefault>::value), "");
+    CONSTEXPR_CXX14 IllFormedDefault dd(-5);
+    CONSTEXPR_CXX14 P p(42, dd);
+    STATIC_ASSERT_CXX14(p.first == 42 && p.second.value == -5);
+    }
+    {
+    typedef std::pair<IllFormedDefault, IllFormedDefault> P;
+    static_assert((std::is_constructible<P, IllFormedDefault, IllFormedDefault>::value), "");
+    CONSTEXPR_CXX14 P p(IllFormedDefault(42), IllFormedDefault(-5));
+    STATIC_ASSERT_CXX14(p.first.value == 42 && p.second.value == -5);
+    }
+}
+
+
+int main()
+{
+    {
+        // Check that pair<T, U> can still be used even if
+        // is_default_constructible<T> or is_default_constructible<U> cause
+        // a compilation error.
+        test_illformed_default();
+    }
+    {
+        // pair::pair() is only disable in C++11 and beyond.
+        test_not_is_default_constructible<NoDefault>();
+        test_not_is_default_constructible<DeletedDefault>();
+        test_not_is_default_constructible<DefaultSFINAES<int&>>();
+        test_not_is_default_constructible<DefaultSFINAES<int&&>>();
+        test_not_is_default_constructible<int&>();
+        test_not_is_default_constructible<int&&>();
+    }
+    {
+        test_is_default_constructible<int>();
+        test_is_default_constructible<DefaultSFINAES<int>>();
+    }
+}
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 bb6661f..97182d2 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,21 @@
 
 // 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>
 
+#include "test_macros.h"
+
 int main()
 {
     {
@@ -24,13 +36,12 @@
     assert(p.first == 0.0f);
     assert(p.second == nullptr);
     }
-    
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER >= 11
     {
-    typedef std::pair<float, short*> P;
-    constexpr P p;
-    static_assert(p.first == 0.0f, "");
-    static_assert(p.second == nullptr, "");
+        typedef std::pair<float, short*> P;
+        constexpr P p;
+        static_assert(p.first == 0.0f, "");
+        static_assert(p.second == nullptr, "");
     }
 #endif
 }
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 a912df0..dfea61e 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp
@@ -16,6 +16,15 @@
 #include <utility>
 #include <cassert>
 
+struct S {
+    int i;
+    S() : i(0) {}
+    S(int j) : i(j) {}
+    S * operator& () { assert(false); return this; }
+    S const * operator& () const { assert(false); return this; }
+    bool operator==(int x) const { return i == x; }
+    };
+
 int main()
 {
     {
@@ -28,4 +37,14 @@
         assert(p2.first == 3);
         assert(p2.second == 4);
     }
+    {
+        typedef std::pair<int, S> P1;
+        P1 p1(3, S(4));
+        P1 p2(5, S(6));
+        p1.swap(p2);
+        assert(p1.first == 5);
+        assert(p1.second == 6);
+        assert(p2.first == 3);
+        assert(p2.second == 4);
+    }
 }
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 48e0973..4a6d71e 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 @@
         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/containers/sequences/vector/const_value_type.pass.cpp b/test/std/utilities/utility/synopsis.pass.cpp
similarity index 65%
copy from test/std/containers/sequences/vector/const_value_type.pass.cpp
copy to test/std/utilities/utility/synopsis.pass.cpp
index e16e439..900be2a 100644
--- a/test/std/containers/sequences/vector/const_value_type.pass.cpp
+++ b/test/std/utilities/utility/synopsis.pass.cpp
@@ -7,16 +7,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <utility>
+// XFAIL: c++03
 
-// vector<const int> v;  // an extension
+// #include <initializer_list>
 
-#include <vector>
-#include <type_traits>
+#include <utility>
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<const int> v = {1, 2, 3};
-#endif
+    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 8606611..c9c9f3b 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>
+
+#include "test_macros.h"
+
+#if TEST_STD_VER >= 11
+struct CopyOnly {
+    CopyOnly() {}
+    CopyOnly(CopyOnly const&) noexcept {}
+    CopyOnly& operator=(CopyOnly const&) { return *this; }
+};
+
+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>()));
+
+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
 
-void
-test()
-{
-    int i = 1;
-    int j = 2;
-    std::swap(i, j);
-    assert(i == 2);
-    assert(j == 1);
-}
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-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);
-}
-
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 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 b1209c3..ad39934 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>
+
+#include "test_macros.h"
+
+
+#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
 
-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);
-}
-
-#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);
-}
-
-#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/MoveOnly.h b/test/support/MoveOnly.h
index e4d9f64..ee6ae7c 100644
--- a/test/support/MoveOnly.h
+++ b/test/support/MoveOnly.h
@@ -17,6 +17,7 @@
 
 class MoveOnly
 {
+    friend class MoveOnly2;
     MoveOnly(const MoveOnly&);
     MoveOnly& operator=(const MoveOnly&);
 
diff --git a/test/support/allocators.h b/test/support/allocators.h
index b7aba12..4aa467f 100644
--- a/test/support/allocators.h
+++ b/test/support/allocators.h
@@ -35,6 +35,8 @@
 
     A1(const A1& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;}
     A1(A1&& a)      TEST_NOEXCEPT : id_(a.id()) {move_called = true;}
+    A1& operator=(const A1& a) TEST_NOEXCEPT { id_ = a.id(); copy_called = true; return *this;}
+    A1& operator=(A1&& a)      TEST_NOEXCEPT { id_ = a.id(); move_called = true; return *this;}
 
     template <class U>
         A1(const A1<U>& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;}
@@ -96,8 +98,10 @@
 
     A2(const A2& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;}
     A2(A2&& a)      TEST_NOEXCEPT : id_(a.id()) {move_called = true;}
+    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;
@@ -142,7 +146,9 @@
     static bool destroy_called;
 
     A3(const A3& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;}
-    A3(A3&& a)      TEST_NOEXCEPT: id_(a.id())  {move_called = true;}
+    A3(A3&& a)      TEST_NOEXCEPT : id_(a.id())  {move_called = true;}
+    A3& operator=(const A3& a) TEST_NOEXCEPT { id_ = a.id(); copy_called = true; return *this;}
+    A3& operator=(A3&& a)      TEST_NOEXCEPT { id_ = a.id(); move_called = true; return *this;}
 
     template <class U, class ...Args>
     void construct(U* p, Args&& ...args)
diff --git a/test/support/any_helpers.h b/test/support/any_helpers.h
index 76b1922..bb1ad17 100644
--- a/test/support/any_helpers.h
+++ b/test/support/any_helpers.h
@@ -1,3 +1,11 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The 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 ANY_HELPERS_H
 #define ANY_HELPERS_H
 
diff --git a/test/support/asan_testing.h b/test/support/asan_testing.h
index 45ad04b..85cd08b 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,7 +27,7 @@
 
 #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;
 }
diff --git a/test/support/assert_checkpoint.h b/test/support/assert_checkpoint.h
new file mode 100644
index 0000000..c83e0cf
--- /dev/null
+++ b/test/support/assert_checkpoint.h
@@ -0,0 +1,68 @@
+#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;
+
+  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{0};
+}
+
+#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/cmpxchg_loop.h b/test/support/cmpxchg_loop.h
index c39e3fb..5bec51b 100644
--- a/test/support/cmpxchg_loop.h
+++ b/test/support/cmpxchg_loop.h
@@ -1,3 +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 <atomic>
 
 template <class A, class T>
diff --git a/test/support/constexpr_char_traits.hpp b/test/support/constexpr_char_traits.hpp
index b069c90..0a73d3a 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 @@
     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 @@
 }
 
 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 @@
 }
 
 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 @@
 }
 
 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 @@
 }
 
 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 @@
 }
 
 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 0000000..0b97f2e
--- /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 57aca7d..e8968a9 100644
--- a/test/support/count_new.hpp
+++ b/test/support/count_new.hpp
@@ -1,3 +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.
+//
+//===----------------------------------------------------------------------===//
+
 #ifndef COUNT_NEW_HPP
 #define COUNT_NEW_HPP
 
diff --git a/test/support/disable_missing_braces_warning.h b/test/support/disable_missing_braces_warning.h
new file mode 100644
index 0000000..c53eef8
--- /dev/null
+++ b/test/support/disable_missing_braces_warning.h
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The 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_DISABLE_MISSING_BRACES_WARNING_H
+#define SUPPORT_DISABLE_MISSING_BRACES_WARNING_H
+
+// 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/hexfloat.h b/test/support/hexfloat.h
index 7ef0937..19008d1 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 @@
 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/nasty_containers.hpp b/test/support/nasty_containers.hpp
index 5a2e195..b9ef5a6 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>
 
@@ -124,8 +125,8 @@
     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_;
 };
@@ -270,8 +271,8 @@
 //         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 @@
 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/nasty_macros.hpp b/test/support/nasty_macros.hpp
index 2738e47..074853e 100644
--- a/test/support/nasty_macros.hpp
+++ b/test/support/nasty_macros.hpp
@@ -1,3 +1,11 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The 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_NASTY_MACROS_HPP
 #define SUPPORT_NASTY_MACROS_HPP
 
diff --git a/test/support/platform_support.h b/test/support/platform_support.h
index 233e721..f4c2247 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 @@
 }
 #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 @@
     return Name;
 #endif
 }
-#endif // _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
+#endif // __CloudABI__
 
 #endif // PLATFORM_SUPPORT_H
diff --git a/test/support/test_allocator.h b/test/support/test_allocator.h
index 47ef1d5..ce61f38 100644
--- a/test/support/test_allocator.h
+++ b/test/support/test_allocator.h
@@ -76,7 +76,7 @@
             ++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);}
@@ -136,7 +136,7 @@
             ++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);}
@@ -171,13 +171,13 @@
 
     template <class U> struct rebind {typedef test_allocator<U> other;};
 
-    test_allocator() throw() : data_(-1) {}
+    test_allocator() throw() : data_(0) {}
     explicit test_allocator(int i) throw() : data_(i) {}
     test_allocator(const test_allocator& a) throw()
         : data_(a.data_) {}
     template <class U> test_allocator(const test_allocator<U>& a) throw()
         : data_(a.data_) {}
-    ~test_allocator() throw() {data_ = 0;}
+    ~test_allocator() throw() {data_ = -1;}
 
     friend bool operator==(const test_allocator& x, const test_allocator& y)
         {return x.data_ == y.data_;}
@@ -201,7 +201,7 @@
         : 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
diff --git a/test/support/test_iterators.h b/test/support/test_iterators.h
index e09fd83..c639443 100644
--- a/test/support/test_iterators.h
+++ b/test/support/test_iterators.h
@@ -11,8 +11,11 @@
 #define ITERATORS_H
 
 #include <iterator>
+#include <stdexcept>
 #include <cassert>
 
+#include "test_macros.h"
+
 #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
 #define DELETE_FUNCTION = delete
 #else
@@ -324,6 +327,223 @@
 template <class Iter>    // everything else
 inline Iter base(Iter i) { return i; }
 
+template <typename T>
+struct ThrowingIterator {
+    typedef std::bidirectional_iterator_tag iterator_category;
+    typedef ptrdiff_t                       difference_type;
+    typedef const T                         value_type;
+    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)
+#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_;
+};
+
+template <typename T>
+bool operator== (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
+{   return a.operator==(b); }
+
+template <typename T>
+bool operator!= (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
+{   return !a.operator==(b); }
+    
+template <typename T>
+struct NonThrowingIterator {
+    typedef std::bidirectional_iterator_tag iterator_category;
+    typedef ptrdiff_t                       difference_type;
+    typedef const T                         value_type;
+    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_;
+    }
+
+private:
+    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); }
+
+template <typename T>
+bool operator!= (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
+{   return !a.operator==(b); }
+
 #undef DELETE_FUNCTION
 
 #endif  // ITERATORS_H
diff --git a/test/support/test_macros.h b/test/support/test_macros.h
index 08ec28f..00ab7c4 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)
 
@@ -26,6 +28,12 @@
 #define TEST_HAS_EXTENSION(X) 0
 #endif
 
+#ifdef __has_builtin
+#define TEST_HAS_BUILTIN(X) __has_builtin(X)
+#else
+#define TEST_HAS_BUILTIN(X) 0
+#endif
+
 /* Make a nice name for the standard version */
 #if  __cplusplus <= 199711L
 # define TEST_STD_VER 3
@@ -37,14 +45,6 @@
 # define TEST_STD_VER 99    // greater than current standard
 #endif
 
-/* Features that were introduced in C++11 */
-#if TEST_STD_VER >= 11
-#define TEST_HAS_RVALUE_REFERENCES
-#define TEST_HAS_VARIADIC_TEMPLATES
-#define TEST_HAS_INITIALIZER_LISTS
-#define TEST_HAS_BASIC_CONSTEXPR
-#endif
-
 /* Features that were introduced in C++14 */
 #if TEST_STD_VER >= 14
 #define TEST_HAS_EXTENDED_CONSTEXPR
@@ -55,37 +55,20 @@
 #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)
 #define TEST_HAS_NO_RTTI
 #endif
@@ -94,4 +77,18 @@
 #define TEST_HAS_NO_EXCEPTIONS
 #endif
 
+#if TEST_HAS_FEATURE(address_sanitizer) || TEST_HAS_FEATURE(memory_sanitizer) || \
+    TEST_HAS_FEATURE(thread_sanitizer)
+#define TEST_HAS_SANITIZERS
+#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
+
 #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 0000000..88fb41d
--- /dev/null
+++ b/test/support/test_memory_resource.hpp
@@ -0,0 +1,506 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The 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 <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 / BlockSize;
+    }
+
+    static bool is_max_aligned(void* p) {
+        return reinterpret_cast<std::size_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::size_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/tracked_value.h b/test/support/tracked_value.h
index b0869b2..14d96b8 100644
--- a/test/support/tracked_value.h
+++ b/test/support/tracked_value.h
@@ -1,3 +1,11 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The 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_TRACKED_VALUE_H
 #define SUPPORT_TRACKED_VALUE_H
 
diff --git a/test/support/type_id.h b/test/support/type_id.h
new file mode 100644
index 0000000..309f088
--- /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/user_defined_integral.hpp b/test/support/user_defined_integral.hpp
index 3b0f7a1..383b65f 100644
--- a/test/support/user_defined_integral.hpp
+++ b/test/support/user_defined_integral.hpp
@@ -1,3 +1,11 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The 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_USER_DEFINED_INTEGRAL_HPP
 #define SUPPORT_USER_DEFINED_INTEGRAL_HPP
 
diff --git a/test/support/uses_alloc_types.hpp b/test/support/uses_alloc_types.hpp
new file mode 100644
index 0000000..f68b842
--- /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>
+    UsesAllocatorTestBase(AllocLastTag, Args&&... args)
+        : args_id(nullptr),
+          constructor_called(UA_AllocLast)
+    {
+        typedef typename detail::TakeNArgs<sizeof...(Args) - 1, Args&&...>::type
+            ArgIDL;
+        args_id = &makeTypeID<ArgIDL>();
+        getAllocatorFromPack(ArgIDL{}, std::forward<Args>(args)...);
+    }
+
+private:
+    template <class ...LArgs, class ...Args>
+    void getAllocatorFromPack(ArgumentListID<LArgs...>, Args&&... args) {
+        getAllocatorFromPackImp<LArgs const&...>(args...);
+    }
+
+    template <class ...LArgs>
+    void getAllocatorFromPackImp(typename detail::Identity<LArgs>::type..., CtorAlloc const& alloc) {
+        allocator = 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/testit b/test/testit
index 821292e..cac6684 100755
--- a/test/testit
+++ b/test/testit
@@ -42,7 +42,7 @@
 fi
 if [ -z "$OPTIONS" ]
 then
-	OPTIONS="-std=${CXX_LANG} -stdlib=libc++"
+	OPTIONS="-std=${CXX_LANG} -stdlib=libc++ -nostdinc++"
 fi
 OPTIONS="$OPTIONS -I$LIBCXX_ROOT/test/support"
 
diff --git a/utils/gen_link_script/gen_link_script.py b/utils/gen_link_script/gen_link_script.py
new file mode 100755
index 0000000..9f1f0b7
--- /dev/null
+++ b/utils/gen_link_script/gen_link_script.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+#===----------------------------------------------------------------------===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is dual licensed under the MIT and the University of Illinois Open
+# Source Licenses. See LICENSE.TXT for details.
+#
+#===----------------------------------------------------------------------===##
+
+import os
+import sys
+
+def print_and_exit(msg):
+    sys.stderr.write(msg + '\n')
+    sys.exit(1)
+
+def usage_and_exit():
+    print_and_exit("Usage: ./gen_link_script.py [--help] [--dryrun] <path/to/libcxx.so> <abi_libname>")
+
+def help_and_exit():
+    help_msg = \
+"""Usage
+
+  gen_link_script.py [--help] [--dryrun] <path/to/libcxx.so> <abi_libname>
+
+  Generate a linker script that links libc++ to the proper ABI library.
+  The script replaces the specified libc++ symlink.
+  An example script for c++abi would look like "INPUT(libc++.so.1 -lc++abi)".
+
+Arguments
+  <path/to/libcxx.so> - The top level symlink to the versioned libc++ shared
+                        library. This file is replaced with a linker script.
+  <abi_libname>       - The name of the ABI library to use in the linker script.
+                        The name must be one of [c++abi, stdc++, supc++, cxxrt].
+
+Exit Status:
+  0 if OK,
+  1 if the action failed.
+"""
+    print_and_exit(help_msg)
+
+def parse_args():
+    args = list(sys.argv)
+    del args[0]
+    if len(args) == 0:
+        usage_and_exit()
+    if args[0] == '--help':
+        help_and_exit()
+    dryrun = '--dryrun' == args[0]
+    if dryrun:
+        del args[0]
+    if len(args) != 2:
+        usage_and_exit()
+    symlink_file = args[0]
+    abi_libname = args[1]
+    return dryrun, symlink_file, abi_libname
+
+def main():
+    dryrun, symlink_file, abi_libname = parse_args()
+
+    # Check that the given libc++.so file is a valid symlink.
+    if not os.path.islink(symlink_file):
+        print_and_exit("symlink file %s is not a symlink" % symlink_file)
+
+    # Read the symlink so we know what libc++ to link to in the linker script.
+    linked_libcxx = os.readlink(symlink_file)
+
+    # Check that the abi_libname is one of the supported values.
+    supported_abi_list = ['c++abi', 'stdc++', 'supc++', 'cxxrt']
+    if abi_libname not in supported_abi_list:
+        print_and_exit("abi name '%s' is not supported: Use one of %r" %
+                        (abi_libname, supported_abi_list))
+
+    # Generate the linker script contents and print the script and destination
+    # information.
+    contents = "INPUT(%s -l%s)" % (linked_libcxx, abi_libname)
+    print("GENERATING SCRIPT: '%s' as file %s" % (contents, symlink_file))
+
+    # Remove the existing libc++ symlink and replace it with the script.
+    if not dryrun:
+        os.unlink(symlink_file)
+        with open(symlink_file, 'w') as f:
+            f.write(contents + "\n")
+
+
+if __name__ == '__main__':
+    main()
diff --git a/utils/not/not.py b/utils/not/not.py
index 96e4ea7..d9ceb85 100644
--- a/utils/not/not.py
+++ b/utils/not/not.py
@@ -1,3 +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.
+#
+#===----------------------------------------------------------------------===##
+
 """not.py is a utility for inverting the return code of commands.
 It acts similar to llvm/utils/not.
 ex: python /path/to/not.py ' echo hello
diff --git a/utils/sym_check/sym_check/__init__.py b/utils/sym_check/sym_check/__init__.py
index 3c66803..1aa2b45 100644
--- a/utils/sym_check/sym_check/__init__.py
+++ b/utils/sym_check/sym_check/__init__.py
@@ -1,3 +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.
+#
+#===----------------------------------------------------------------------===##
+
 """libcxx abi symbol checker"""
 
 __author__ = 'Eric Fiselier'
diff --git a/utils/sym_check/sym_check/diff.py b/utils/sym_check/sym_check/diff.py
index a16e54d..6502a48 100644
--- a/utils/sym_check/sym_check/diff.py
+++ b/utils/sym_check/sym_check/diff.py
@@ -1,4 +1,12 @@
 # -*- Python -*- vim: set syntax=python tabstop=4 expandtab cc=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.
+#
+#===----------------------------------------------------------------------===##
 """
 diff - A set of functions for diff-ing two symbol lists.
 """
diff --git a/utils/sym_check/sym_check/extract.py b/utils/sym_check/sym_check/extract.py
index b4f4cee..7bafd8e 100644
--- a/utils/sym_check/sym_check/extract.py
+++ b/utils/sym_check/sym_check/extract.py
@@ -1,4 +1,12 @@
 # -*- Python -*- vim: set syntax=python tabstop=4 expandtab cc=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.
+#
+#===----------------------------------------------------------------------===##
 """
 extract - A set of function that extract symbol lists from shared libraries.
 """
diff --git a/utils/sym_check/sym_check/match.py b/utils/sym_check/sym_check/match.py
index 9f49642..fae400e 100644
--- a/utils/sym_check/sym_check/match.py
+++ b/utils/sym_check/sym_check/match.py
@@ -1,4 +1,12 @@
 # -*- Python -*- vim: set syntax=python tabstop=4 expandtab cc=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.
+#
+#===----------------------------------------------------------------------===##
 """
 match - A set of functions for matching symbols in a list to a list of regexs
 """
diff --git a/utils/sym_check/sym_check/util.py b/utils/sym_check/sym_check/util.py
index 1d3b424..6ae71b0 100644
--- a/utils/sym_check/sym_check/util.py
+++ b/utils/sym_check/sym_check/util.py
@@ -1,3 +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.
+#
+#===----------------------------------------------------------------------===##
+
 import ast
 import distutils.spawn
 import signal
diff --git a/utils/sym_check/sym_diff.py b/utils/sym_check/sym_diff.py
index 054c6c1..69c3400 100755
--- a/utils/sym_check/sym_diff.py
+++ b/utils/sym_check/sym_diff.py
@@ -1,7 +1,16 @@
 #!/usr/bin/env python
+#===----------------------------------------------------------------------===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is dual licensed under the MIT and the University of Illinois Open
+# Source Licenses. See LICENSE.TXT for details.
+#
+#===----------------------------------------------------------------------===##
 """
 sym_diff - Compare two symbol lists and output the differences.
 """
+
 from argparse import ArgumentParser
 import sys
 from sym_check import diff, util
diff --git a/utils/sym_check/sym_extract.py b/utils/sym_check/sym_extract.py
index 5d89539..a0fbb3e 100755
--- a/utils/sym_check/sym_extract.py
+++ b/utils/sym_check/sym_extract.py
@@ -1,4 +1,12 @@
 #!/usr/bin/env python
+#===----------------------------------------------------------------------===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is dual licensed under the MIT and the University of Illinois Open
+# Source Licenses. See LICENSE.TXT for details.
+#
+#===----------------------------------------------------------------------===##
 """
 sym_extract - Extract and output a list of symbols from a shared library.
 """
diff --git a/utils/sym_check/sym_match.py b/utils/sym_check/sym_match.py
index c60b246..231bdc8 100755
--- a/utils/sym_check/sym_match.py
+++ b/utils/sym_check/sym_match.py
@@ -1,4 +1,13 @@
 #!/usr/bin/env python
+#===----------------------------------------------------------------------===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is dual licensed under the MIT and the University of Illinois Open
+# Source Licenses. See LICENSE.TXT for details.
+#
+#===----------------------------------------------------------------------===##
+
 """
 sym_match - Match all symbols in a list against a list of regexes.
 """
diff --git a/www/cxx1y_status.html b/www/cxx1y_status.html
index 2b9c05a..f28d67a 100644
--- a/www/cxx1y_status.html
+++ b/www/cxx1y_status.html
@@ -109,165 +109,165 @@
 <!--   <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://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#1214">1214</a></td><td>Insufficient/inconsistent key immutability requirements for associative containers</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2009">2009</a></td><td>Reporting out-of-bound values on numeric string conversions</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2010">2010</a></td><td>is_* traits for binding operations can't be meaningfully specialized</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2015">2015</a></td><td>Incorrect pre-conditions for some type traits</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2021">2021</a></td><td>Further incorrect usages of result_of</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2028">2028</a></td><td>messages_base::catalog overspecified</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2033">2033</a></td><td>Preconditions of reserve, shrink_to_fit, and resize functions</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2039">2039</a></td><td>Issues with std::reverse and std::copy_if</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2044">2044</a></td><td>No definition of "Stable" for copy algorithms</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2045">2045</a></td><td>forward_list::merge and forward_list::splice_after with unequal allocators</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2047">2047</a></td><td>Incorrect "mixed" move-assignment semantics of unique_ptr</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2050">2050</a></td><td>Unordered associative containers do not use allocator_traits to define member types</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2053">2053</a></td><td>Errors in regex bitmask types</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2061">2061</a></td><td>make_move_iterator and arrays</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2064">2064</a></td><td>More noexcept issues in basic_string</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2065">2065</a></td><td>Minimal allocator interface</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2067">2067</a></td><td>packaged_task should have deleted copy c'tor with const parameter</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2069">2069</a></td><td>Inconsistent exception spec for basic_string move constructor</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2096">2096</a></td><td>Incorrect constraints of future::get in regard to MoveAssignable</td><td>Kona</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2102">2102</a></td><td>Why is std::launch an implementation-defined type?</td><td>Kona</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>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2009">2009</a></td><td>Reporting out-of-bound values on numeric string conversions</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2010">2010</a></td><td>is_* traits for binding operations can't be meaningfully specialized</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2015">2015</a></td><td>Incorrect pre-conditions for some type traits</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2021">2021</a></td><td>Further incorrect usages of result_of</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2028">2028</a></td><td>messages_base::catalog overspecified</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2033">2033</a></td><td>Preconditions of reserve, shrink_to_fit, and resize functions</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2039">2039</a></td><td>Issues with std::reverse and std::copy_if</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2044">2044</a></td><td>No definition of "Stable" for copy algorithms</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2045">2045</a></td><td>forward_list::merge and forward_list::splice_after with unequal allocators</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2047">2047</a></td><td>Incorrect "mixed" move-assignment semantics of unique_ptr</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2050">2050</a></td><td>Unordered associative containers do not use allocator_traits to define member types</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2053">2053</a></td><td>Errors in regex bitmask types</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2061">2061</a></td><td>make_move_iterator and arrays</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2064">2064</a></td><td>More noexcept issues in basic_string</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2065">2065</a></td><td>Minimal allocator interface</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2067">2067</a></td><td>packaged_task should have deleted copy c'tor with const parameter</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2069">2069</a></td><td>Inconsistent exception spec for basic_string move constructor</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2096">2096</a></td><td>Incorrect constraints of future::get in regard to MoveAssignable</td><td>Kona</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2102">2102</a></td><td>Why is std::launch an implementation-defined type?</td><td>Kona</td><td>Complete</td></tr>
   <tr><td></td><td></td><td></td><td></td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2071">2071</a></td><td>std::valarray move-assignment</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2074">2074</a></td><td>Off by one error in std::reverse_copy</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2081">2081</a></td><td>Allocator requirements should include CopyConstructible</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2083">2083</a></td><td>const-qualification on weak_ptr::owner_before</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2086">2086</a></td><td>Overly generic type support for math functions</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2099">2099</a></td><td>Unnecessary constraints of va_start() usage</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2103">2103</a></td><td>std::allocator_traits&lt;std::allocator&lt;T&gt;&gt;::propagate_on_container_move_assignment</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2105">2105</a></td><td>Inconsistent requirements on const_iterator's value_type</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2110">2110</a></td><td>remove can't swap but note says it might</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2123">2123</a></td><td>merge() allocator requirements for lists versus forward lists</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2005">2005</a></td><td>unordered_map::insert(T&&) protection should apply to map too</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2011">2011</a></td><td>Unexpected output required of strings</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2048">2048</a></td><td>Unnecessary mem_fn overloads</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2049">2049</a></td><td>is_destructible is underspecified</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2056">2056</a></td><td>future_errc enums start with value 0 (invalid value for broken_promise)</td><td>Portland</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2058">2058</a></td><td>valarray and begin/end</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2071">2071</a></td><td>std::valarray move-assignment</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2074">2074</a></td><td>Off by one error in std::reverse_copy</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2081">2081</a></td><td>Allocator requirements should include CopyConstructible</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2083">2083</a></td><td>const-qualification on weak_ptr::owner_before</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2086">2086</a></td><td>Overly generic type support for math functions</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2099">2099</a></td><td>Unnecessary constraints of va_start() usage</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2103">2103</a></td><td>std::allocator_traits&lt;std::allocator&lt;T&gt;&gt;::propagate_on_container_move_assignment</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2105">2105</a></td><td>Inconsistent requirements on const_iterator's value_type</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2110">2110</a></td><td>remove can't swap but note says it might</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2123">2123</a></td><td>merge() allocator requirements for lists versus forward lists</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2005">2005</a></td><td>unordered_map::insert(T&&) protection should apply to map too</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2011">2011</a></td><td>Unexpected output required of strings</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2048">2048</a></td><td>Unnecessary mem_fn overloads</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2049">2049</a></td><td>is_destructible is underspecified</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2056">2056</a></td><td>future_errc enums start with value 0 (invalid value for broken_promise)</td><td>Portland</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2058">2058</a></td><td>valarray and begin/end</td><td>Portland</td><td>Complete</td></tr>
   <tr><td></td><td></td><td></td><td></td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2091">2091</a></td><td>Misplaced effect in m.try_lock_for()</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2092">2092</a></td><td>Vague Wording for condition_variable_any</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2093">2093</a></td><td>Throws clause of condition_variable::wait with predicate</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2094">2094</a></td><td>duration conversion overflow shouldn't participate in overload resolution</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2122">2122</a></td><td>merge() stability for lists versus forward lists</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2128">2128</a></td><td>Absence of global functions cbegin/cend</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2145">2145</a></td><td>error_category default constructor</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2147">2147</a></td><td>Unclear hint type in Allocator's allocate function</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2148">2148</a></td><td>Hashing enums should be supported directly by std::hash</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2149">2149</a></td><td>Concerns about 20.8/5</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2162">2162</a></td><td>allocator_traits::max_size missing noexcept</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2163">2163</a></td><td>nth_element requires inconsistent post-conditions</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2169">2169</a></td><td>Missing reset() requirements in unique_ptr specialization</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2172">2172</a></td><td>Does atomic_compare_exchange_* accept v == nullptr arguments?</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2080">2080</a></td><td>Specify when once_flag becomes invalid</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2098">2098</a></td><td>promise throws clauses</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2109">2109</a></td><td>Incorrect requirements for hash specializations</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2130">2130</a></td><td>missing ordering constraints for fences</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2138">2138</a></td><td>atomic_flag::clear ordering constraints</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2140">2140</a></td><td>notify_all_at_thread_exit synchronization</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2144">2144</a></td><td>Missing noexcept specification in type_index</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2174">2174</a></td><td>wstring_convert::converted() should be noexcept</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2175">2175</a></td><td>string_convert and wbuffer_convert validity</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2176">2176</a></td><td>Special members for wstring_convert and wbuffer_convert</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2177">2177</a></td><td>Requirements on Copy/MoveInsertable</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2185">2185</a></td><td>Missing throws clause for future/shared_future::wait_for/wait_until</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2187">2187</a></td><td>vector&lt;bool&gt; is missing emplace and emplace_back member functions</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2190">2190</a></td><td>ordering of condition variable operations, reflects Posix discussion</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2196">2196</a></td><td>Specification of is_*[copy/move]_[constructible/assignable] unclear for non-referencable types</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2197">2197</a></td><td>Specification of is_[un]signed unclear for non-arithmetic types</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2200">2200</a></td><td>Data race avoidance for all containers, not only for sequences</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2203">2203</a></td><td>scoped_allocator_adaptor uses wrong argument types for piecewise construction</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2207">2207</a></td><td>basic_string::at should not have a Requires clause</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2209">2209</a></td><td>assign() overspecified for sequence containers</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2210">2210</a></td><td>Missing allocator-extended constructor for allocator-aware containers</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2211">2211</a></td><td>Replace ambiguous use of "Allocator" in container requirements</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2222">2222</a></td><td>Inconsistency in description of forward_list::splice_after single-element overload</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2225">2225</a></td><td>Unrealistic header inclusion checks required</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2229">2229</a></td><td>Standard code conversion facets underspecified</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2231">2231</a></td><td>DR 704 removes complexity guarantee for clear()</td><td>Bristol</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2235">2235</a></td><td>Undefined behavior without proper requirements on basic_string constructors</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2091">2091</a></td><td>Misplaced effect in m.try_lock_for()</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2092">2092</a></td><td>Vague Wording for condition_variable_any</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2093">2093</a></td><td>Throws clause of condition_variable::wait with predicate</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2094">2094</a></td><td>duration conversion overflow shouldn't participate in overload resolution</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2122">2122</a></td><td>merge() stability for lists versus forward lists</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2128">2128</a></td><td>Absence of global functions cbegin/cend</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2145">2145</a></td><td>error_category default constructor</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2147">2147</a></td><td>Unclear hint type in Allocator's allocate function</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2148">2148</a></td><td>Hashing enums should be supported directly by std::hash</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2149">2149</a></td><td>Concerns about 20.8/5</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2162">2162</a></td><td>allocator_traits::max_size missing noexcept</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2163">2163</a></td><td>nth_element requires inconsistent post-conditions</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2169">2169</a></td><td>Missing reset() requirements in unique_ptr specialization</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2172">2172</a></td><td>Does atomic_compare_exchange_* accept v == nullptr arguments?</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2080">2080</a></td><td>Specify when once_flag becomes invalid</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2098">2098</a></td><td>promise throws clauses</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2109">2109</a></td><td>Incorrect requirements for hash specializations</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2130">2130</a></td><td>missing ordering constraints for fences</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2138">2138</a></td><td>atomic_flag::clear ordering constraints</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2140">2140</a></td><td>notify_all_at_thread_exit synchronization</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2144">2144</a></td><td>Missing noexcept specification in type_index</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2174">2174</a></td><td>wstring_convert::converted() should be noexcept</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2175">2175</a></td><td>string_convert and wbuffer_convert validity</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2176">2176</a></td><td>Special members for wstring_convert and wbuffer_convert</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2177">2177</a></td><td>Requirements on Copy/MoveInsertable</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2185">2185</a></td><td>Missing throws clause for future/shared_future::wait_for/wait_until</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2187">2187</a></td><td>vector&lt;bool&gt; is missing emplace and emplace_back member functions</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2190">2190</a></td><td>ordering of condition variable operations, reflects Posix discussion</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2196">2196</a></td><td>Specification of is_*[copy/move]_[constructible/assignable] unclear for non-referencable types</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2197">2197</a></td><td>Specification of is_[un]signed unclear for non-arithmetic types</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2200">2200</a></td><td>Data race avoidance for all containers, not only for sequences</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2203">2203</a></td><td>scoped_allocator_adaptor uses wrong argument types for piecewise construction</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2207">2207</a></td><td>basic_string::at should not have a Requires clause</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2209">2209</a></td><td>assign() overspecified for sequence containers</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2210">2210</a></td><td>Missing allocator-extended constructor for allocator-aware containers</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2211">2211</a></td><td>Replace ambiguous use of "Allocator" in container requirements</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2222">2222</a></td><td>Inconsistency in description of forward_list::splice_after single-element overload</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2225">2225</a></td><td>Unrealistic header inclusion checks required</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2229">2229</a></td><td>Standard code conversion facets underspecified</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2231">2231</a></td><td>DR 704 removes complexity guarantee for clear()</td><td>Bristol</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2235">2235</a></td><td>Undefined behavior without proper requirements on basic_string constructors</td><td>Bristol</td><td>Complete</td></tr>
     <tr><td></td><td></td><td></td><td></td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2141">2141</a></td><td>common_type trait produces reference types</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2246">2246</a></td><td>unique_ptr assignment effects w.r.t. deleter</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2247">2247</a></td><td>Type traits and std::nullptr_t</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2085">2085</a></td><td>Wrong description of effect 1 of basic_istream::ignore</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2087">2087</a></td><td>iostream_category() and noexcept</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2143">2143</a></td><td>ios_base::xalloc should be thread-safe</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2150">2150</a></td><td>Unclear specification of find_end</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2180">2180</a></td><td>Exceptions from std::seed_seq operations</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2194">2194</a></td><td>Impossible container requirements for adaptor types</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2013">2013</a></td><td>Do library implementers have the freedom to add constexpr?</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2018">2018</a></td><td>regex_traits::isctype Returns clause is wrong</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2078">2078</a></td><td>Throw specification of async() incomplete</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2097">2097</a></td><td>packaged_task constructors should be constrained</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2100">2100</a></td><td>Timed waiting functions cannot timeout if launch::async policy used</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2120">2120</a></td><td>What should async do if neither 'async' nor 'deferred' is set in policy?</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2159">2159</a></td><td>atomic_flag initialization</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2275">2275</a></td><td>Why is forward_as_tuple not constexpr?</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2284">2284</a></td><td>Inconsistency in allocator_traits::max_size</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2298">2298</a></td><td>is_nothrow_constructible is always false because of create&lt;&gt;</td><td>Chicago</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2300">2300</a></td><td>Redundant sections for map and multimap members should be removed</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2141">2141</a></td><td>common_type trait produces reference types</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2246">2246</a></td><td>unique_ptr assignment effects w.r.t. deleter</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2247">2247</a></td><td>Type traits and std::nullptr_t</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2085">2085</a></td><td>Wrong description of effect 1 of basic_istream::ignore</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2087">2087</a></td><td>iostream_category() and noexcept</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2143">2143</a></td><td>ios_base::xalloc should be thread-safe</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2150">2150</a></td><td>Unclear specification of find_end</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2180">2180</a></td><td>Exceptions from std::seed_seq operations</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2194">2194</a></td><td>Impossible container requirements for adaptor types</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2013">2013</a></td><td>Do library implementers have the freedom to add constexpr?</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2018">2018</a></td><td>regex_traits::isctype Returns clause is wrong</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2078">2078</a></td><td>Throw specification of async() incomplete</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2097">2097</a></td><td>packaged_task constructors should be constrained</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2100">2100</a></td><td>Timed waiting functions cannot timeout if launch::async policy used</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2120">2120</a></td><td>What should async do if neither 'async' nor 'deferred' is set in policy?</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2159">2159</a></td><td>atomic_flag initialization</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2275">2275</a></td><td>Why is forward_as_tuple not constexpr?</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2284">2284</a></td><td>Inconsistency in allocator_traits::max_size</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2298">2298</a></td><td>is_nothrow_constructible is always false because of create&lt;&gt;</td><td>Chicago</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2300">2300</a></td><td>Redundant sections for map and multimap members should be removed</td><td>Chicago</td><td>Complete</td></tr>
 	<tr><td>NB comment: GB9</td>                                                                     <td>Remove gets from C++14</td><td>Chicago</td><td>Complete</td></tr>
     <tr><td></td><td></td><td></td><td></td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2135">2135</a></td><td>Unclear requirement for exceptions thrown in condition_variable::wait()</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2291">2291</a></td><td>std::hash is vulnerable to collision DoS attack</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2142">2142</a></td><td>packaged_task::operator() synchronization too broad?</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2240">2240</a></td><td>Probable misuse of term "function scope" in [thread.condition]</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2252">2252</a></td><td>Strong guarantee on vector::push_back() still broken with C++11?</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2257">2257</a></td><td>Simplify container requirements with the new algorithms</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2268">2268</a></td><td>Setting a default argument in the declaration of a member function assign of std::basic_string</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2271">2271</a></td><td>regex_traits::lookup_classname specification unclear</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2272">2272</a></td><td>quoted should use char_traits::eq for character comparison</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2278">2278</a></td><td>User-defined literals for Standard Library types</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2280">2280</a></td><td>begin / end for arrays should be constexpr and noexcept</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2285">2285</a></td><td>make_reverse_iterator</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2135">2135</a></td><td>Unclear requirement for exceptions thrown in condition_variable::wait()</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2291">2291</a></td><td>std::hash is vulnerable to collision DoS attack</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2142">2142</a></td><td>packaged_task::operator() synchronization too broad?</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2240">2240</a></td><td>Probable misuse of term "function scope" in [thread.condition]</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2252">2252</a></td><td>Strong guarantee on vector::push_back() still broken with C++11?</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2257">2257</a></td><td>Simplify container requirements with the new algorithms</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2268">2268</a></td><td>Setting a default argument in the declaration of a member function assign of std::basic_string</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2271">2271</a></td><td>regex_traits::lookup_classname specification unclear</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2272">2272</a></td><td>quoted should use char_traits::eq for character comparison</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2278">2278</a></td><td>User-defined literals for Standard Library types</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2280">2280</a></td><td>begin / end for arrays should be constexpr and noexcept</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2285">2285</a></td><td>make_reverse_iterator</td><td>Issaquah</td><td>Complete</td></tr>
 
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2299">2299</a></td><td>Effects of inaccessible key_compare::is_transparent type are not clear</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2299">2299</a></td><td>Effects of inaccessible key_compare::is_transparent type are not clear</td><td>Issaquah</td><td>Complete</td></tr>
 
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#1450">1450</a></td><td>Contradiction in regex_constants</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2003">2003</a></td><td>String exception inconsistency in erase.</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2112">2112</a></td><td>User-defined classes that cannot be derived from</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2132">2132</a></td><td>std::function ambiguity</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2182">2182</a></td><td>Container::[const_]reference types are misleadingly specified</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2188">2188</a></td><td>Reverse iterator does not fully support targets that overload operator&</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2193">2193</a></td><td>Default constructors for standard library containers are explicit</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2205">2205</a></td><td>Problematic postconditions of regex_match and regex_search</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2213">2213</a></td><td>Return value of std::regex_replace</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#1450">1450</a></td><td>Contradiction in regex_constants</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2003">2003</a></td><td>String exception inconsistency in erase.</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2112">2112</a></td><td>User-defined classes that cannot be derived from</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2132">2132</a></td><td>std::function ambiguity</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2182">2182</a></td><td>Container::[const_]reference types are misleadingly specified</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2188">2188</a></td><td>Reverse iterator does not fully support targets that overload operator&</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2193">2193</a></td><td>Default constructors for standard library containers are explicit</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2205">2205</a></td><td>Problematic postconditions of regex_match and regex_search</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2213">2213</a></td><td>Return value of std::regex_replace</td><td>Issaquah</td><td>Complete</td></tr>
 
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2258">2258</a></td><td>a.erase(q1, q2) unable to directly return q2</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2263">2263</a></td><td>Comparing iterators and allocator pointers with different const-character</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2293">2293</a></td><td>Wrong facet used by num_put::do_put</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2301">2301</a></td><td>Why is std::tie not constexpr?</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2304">2304</a></td><td>Complexity of count in unordered associative containers</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2306">2306</a></td><td>match_results::reference should be value_type&, not const value_type&</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2308">2308</a></td><td>Clarify container destructor requirements w.r.t. std::array</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2313">2313</a></td><td>tuple_size should always derive from integral_constant<size_t, N></td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2314">2314</a></td><td>apply() should return decltype(auto) and use decay_t before tuple_size</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2315">2315</a></td><td>weak_ptr should be movable</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2316">2316</a></td><td>weak_ptr::lock() should be atomic</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2317">2317</a></td><td>The type property queries should be UnaryTypeTraits returning size_t</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2320">2320</a></td><td>select_on_container_copy_construction() takes allocators, not containers</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2322">2322</a></td><td>Associative(initializer_list, stuff) constructors are underspecified</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2323">2323</a></td><td>vector::resize(n, t)'s specification should be simplified</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2324">2324</a></td><td>Insert iterator constructors should use addressof()</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2329">2329</a></td><td>regex_match()/regex_search() with match_results should forbid temporary strings</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2330">2330</a></td><td>regex("meow", regex::icase) is technically forbidden but should be permitted</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2332">2332</a></td><td>regex_iterator/regex_token_iterator should forbid temporary regexes</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2339">2339</a></td><td>Wording issue in nth_element</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2341">2341</a></td><td>Inconsistency between basic_ostream::seekp(pos) and basic_ostream::seekp(off, dir)</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2344">2344</a></td><td>quoted()'s interaction with padding is unclear</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2346">2346</a></td><td>integral_constant's member functions should be marked noexcept</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2350">2350</a></td><td>min, max, and minmax should be constexpr</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2356">2356</a></td><td>Stability of erasure in unordered associative containers</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2357">2357</a></td><td>Remaining "Assignable" requirement</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2359">2359</a></td><td>How does regex_constants::nosubs affect basic_regex::mark_count()?</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2360">2360</a></td><td>reverse_iterator::operator*() is unimplementable</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2104">2104</a></td><td>unique_lock move-assignment should not be noexcept</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2186">2186</a></td><td>Incomplete action on async/launch::deferred</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2075">2075</a></td><td>Progress guarantees, lock-free property, and scheduling assumptions</td><td>Issaquah</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2288">2288</a></td><td>Inconsistent requirements for shared mutexes</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2258">2258</a></td><td>a.erase(q1, q2) unable to directly return q2</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2263">2263</a></td><td>Comparing iterators and allocator pointers with different const-character</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2293">2293</a></td><td>Wrong facet used by num_put::do_put</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2301">2301</a></td><td>Why is std::tie not constexpr?</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2304">2304</a></td><td>Complexity of count in unordered associative containers</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2306">2306</a></td><td>match_results::reference should be value_type&, not const value_type&</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2308">2308</a></td><td>Clarify container destructor requirements w.r.t. std::array</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2313">2313</a></td><td>tuple_size should always derive from integral_constant<size_t, N></td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2314">2314</a></td><td>apply() should return decltype(auto) and use decay_t before tuple_size</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2315">2315</a></td><td>weak_ptr should be movable</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2316">2316</a></td><td>weak_ptr::lock() should be atomic</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2317">2317</a></td><td>The type property queries should be UnaryTypeTraits returning size_t</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2320">2320</a></td><td>select_on_container_copy_construction() takes allocators, not containers</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2322">2322</a></td><td>Associative(initializer_list, stuff) constructors are underspecified</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2323">2323</a></td><td>vector::resize(n, t)'s specification should be simplified</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2324">2324</a></td><td>Insert iterator constructors should use addressof()</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2329">2329</a></td><td>regex_match()/regex_search() with match_results should forbid temporary strings</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2330">2330</a></td><td>regex("meow", regex::icase) is technically forbidden but should be permitted</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2332">2332</a></td><td>regex_iterator/regex_token_iterator should forbid temporary regexes</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2339">2339</a></td><td>Wording issue in nth_element</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2341">2341</a></td><td>Inconsistency between basic_ostream::seekp(pos) and basic_ostream::seekp(off, dir)</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2344">2344</a></td><td>quoted()'s interaction with padding is unclear</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2346">2346</a></td><td>integral_constant's member functions should be marked noexcept</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2350">2350</a></td><td>min, max, and minmax should be constexpr</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2356">2356</a></td><td>Stability of erasure in unordered associative containers</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2357">2357</a></td><td>Remaining "Assignable" requirement</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2359">2359</a></td><td>How does regex_constants::nosubs affect basic_regex::mark_count()?</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2360">2360</a></td><td>reverse_iterator::operator*() is unimplementable</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2104">2104</a></td><td>unique_lock move-assignment should not be noexcept</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2186">2186</a></td><td>Incomplete action on async/launch::deferred</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2075">2075</a></td><td>Progress guarantees, lock-free property, and scheduling assumptions</td><td>Issaquah</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2288">2288</a></td><td>Inconsistent requirements for shared mutexes</td><td>Issaquah</td><td>Complete</td></tr>
 <!-- 	<tr><td></td><td></td><td></td><td></td></tr> -->
   </table>
 
diff --git a/www/cxx1z_status.html b/www/cxx1z_status.html
index 4369810..621b6fd 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&lt;T[]&gt;</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&lt;T[]&gt;</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>
@@ -69,6 +69,30 @@
 	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4508">N4508</a></td><td>LWG</td></td><td>shared_mutex for C++17</td><td>Lenexa</td><td>Complete</td><td>3.7</td></tr>
 	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4366">N4366</a></td><td>LWG</td></td><td>LWG 2228 missing SFINAE rule</td><td>Lenexa</td><td>Complete</td><td>3.1</td></tr>
 	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4510">N4510</a></td><td>LWG</td></td><td>Minimal incomplete type support for standard containers, revision 4</td><td>Lenexa</td><td>Complete</td><td>3.6</td></tr>
+  	<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr>
+	<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/P0092R1.html">P0092R1</a></td><td>LWG</td><td>Polishing &lt;chrono&gt;</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/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></td><td></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></td><td></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> -->
   </table>
 
@@ -76,76 +100,145 @@
 <!--   <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://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2016">2016</a></td><td>Allocators must be no-throw swappable</td><td>Urbana</td><td></td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2376">2118</td><td><code>unique_ptr</code> for array does not support cv qualification conversion of actual argument</td><td>Urbana</td><td>Will be resolved by N4089</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2170">2170</a></td><td>Aggregates cannot be <code>DefaultConstructible</code></td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2308">2308</td><td>Clarify container destructor requirements w.r.t. <code>std::array</code></td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2340">2340</a></td><td>Replacement allocation functions declared as inline</td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2354">2354</a></td><td>Unnecessary copying when inserting into maps with braced-init syntax</td><td>Urbana</td><td></td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2377">2377</a></td><td><code>std::align</code> requirements overly strict</td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2396">2396</a></td><td><code>underlying_type</code> doesn't say what to do for an incomplete enumeration type</td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2399">2399</a></td><td><code>shared_ptr</code>'s constructor from <code>unique_ptr</code> should be constrained</td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2400">2400</a></td><td><code>shared_ptr</code>'s <code>get_deleter()</code> should use <code>addressof()</code></td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2401">2401</a></td><td><code>std::function</code> needs more noexcept</td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2404">2404</a></td><td><code>mismatch()</code>'s complexity needs to be updated</td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2408">2408</a></td><td>SFINAE-friendly <code>common_type</code> / <code>iterator_traits</code> is missing in C++14</td><td>Urbana</td><td><code>common_type</code> is waiting on <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2465">LWG#2465</a></td></tr>
+	<tr><td><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>Complete</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>Complete</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>Complete</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></td><td></td><td></td><td></td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2106">2106</td><td><code>move_iterator</code> wrapping iterators returning prvalues</td><td>Urbana</td><td></td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2129">2129</td><td>User specializations of <code>std::initializer_list</code></td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2212">2212</td><td><code>tuple_size</code> for <code>const pair</code> request <tuple> header</td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2217">2217</td><td><code>operator==(sub_match, string)</code> slices on embedded '\0's</td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2230">2230</td><td>"see below" for <code>initializer_list</code> constructors of unordered containers</td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2233">2233</td><td><code>bad_function_call::what()</code> unhelpful</td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2266">2266</td><td><code>vector</code> and <code>deque</code> have incorrect insert requirements</td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2325">2325</td><td><code>minmax_element()</code>'s behavior differing from <code>max_element()</code>'s should be noted</td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2361">2361</td><td>Apply 2299 resolution throughout library</td><td>Urbana</td><td></td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2365">2365</td><td>Missing noexcept in <code>shared_ptr::shared_ptr(nullptr_t)</code></td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2376">2376</td><td><code>bad_weak_ptr::what()</code> overspecified</td><td>Urbana</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2387">2387</td><td>More nested types that must be accessible and unambiguous</td><td>Urbana</td><td>Complete</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>Complete</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>Complete</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></td><td></td><td></td><td></td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2059">2059</td><td>C++0x ambiguity problem with map::erase</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2063">2063</td><td>Contradictory requirements for string move assignment</td><td>Lenexa</td><td></td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2076">2076</td><td>Bad CopyConstructible requirement in set constructors</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2160">2160</td><td>Unintended destruction ordering-specification of resize</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2168">2168</td><td>Inconsistent specification of uniform_real_distribution constructor</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2239">2239</td><td>min/max/minmax requirements</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2364">2364</td><td>deque and vector pop_back don't specify iterator invalidation requirements</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2369">2369</td><td>constexpr max(initializer_list) vs max_element</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2378">2378</td><td>Behaviour of standard exception types</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2403">2403</td><td>stof() should call strtof() and wcstof()</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2406">2406</td><td>negative_binomial_distribution should reject p == 1</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2407">2407</td><td>packaged_task(allocator_arg_t, const Allocator&, F&&) should neither be constrained nor explicit</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2411">2411</td><td>shared_ptr is only contextually convertible to bool</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2415">2415</td><td>Inconsistency between unique_ptr and shared_ptr</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2420">2420</td><td>function<void(ArgTypes...)> does not discard the return value of the target object</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2425">2425</td><td>operator delete(void*, size_t) doesn't invalidate pointers sufficiently</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2427">2427</td><td>Container adaptors as sequence containers, redux</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2428">2428</td><td>"External declaration" used without being defined</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2433">2433</td><td>uninitialized_copy()/etc. should tolerate overloaded operator&</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2434">2434</td><td>shared_ptr::use_count() is efficient</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2437">2437</td><td>iterator_traits::reference can and can't be void</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2438">2438</td><td>std::iterator inheritance shouldn't be mandated</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2439">2439</td><td>unique_copy() sometimes can't fall back to reading its output</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2440">2440</td><td>seed_seq::size() should be noexcept</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2442">2442</td><td>call_once() shouldn't DECAY_COPY()</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2448">2448</td><td>Non-normative Container destructor specification</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2454">2454</td><td>Add raw_storage_iterator::base() member</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2455">2455</td><td>Allocator default construction should be allowed to throw</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2458">2458</td><td>N3778 and new library deallocation signatures</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2459">2459</td><td>std::polar should require a non-negative rho</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2464">2464</td><td>try_emplace and insert_or_assign misspecified</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2467">2467</td><td>is_always_equal has slightly inconsistent default</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2470">2470</td><td>Allocator's destroy function should be allowed to fail to instantiate</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2482">2482</td><td>[c.strings] Table 73 mentions nonexistent functions</td><td>Lenexa</td><td>Complete</td></tr>
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2488">2488</td><td>Placeholders should be allowed and encouraged to be constexpr</td><td>Lenexa</td><td></td></tr>
+	<tr><td><a href="http://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></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>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2111">2111</a></td><td>Which <tt>unexpected</tt>&#47;<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>Complete</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>Complete</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>&lt;cstdlib&gt;</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>Complete</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>Complete</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&amp;&amp;</tt></td><td>Kona</td><td>Complete</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></td><td></td><td></td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2192">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://cplusplus.github.io/LWG/lwg-defects.html#2276">2276</a></td><td>Missing requirement on <tt>std::promise::set_exception</tt></td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2296">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://cplusplus.github.io/LWG/lwg-defects.html#2450">2450</a></td><td><tt>(greater|less|greater_equal|less_equal)&lt;void&gt;</tt> do not yield a total order for pointers</td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2520">2520</a></td><td>N4089 broke initializing <tt>unique_ptr&lt;T[]&gt;</tt> from a <tt>nullptr</tt></td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2522">2522</a></td><td>[fund.ts.v2] Contradiction in <tt>set_default_resource</tt> specification</td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2523">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://cplusplus.github.io/LWG/lwg-defects.html#2537">2537</a></td><td>Constructors for <code>priority_queue</code> taking allocators should call <code>make_heap</code></td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2539">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://cplusplus.github.io/LWG/lwg-defects.html#2545">2545</a></td><td>Simplify wording for <tt>bind</tt> without explicitly specified return type</td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2557">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://cplusplus.github.io/LWG/lwg-defects.html#2558">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://cplusplus.github.io/LWG/lwg-defects.html#2559">2559</a></td><td>Error in LWG 2234's resolution</td><td>Jacksonville</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2560">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://cplusplus.github.io/LWG/lwg-defects.html#2565">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></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2566">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://cplusplus.github.io/LWG/lwg-defects.html#2571">2571</a></td><td>&sect;[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://cplusplus.github.io/LWG/lwg-defects.html#2572">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://cplusplus.github.io/LWG/lwg-defects.html#2574">2574</a></td><td>[fund.ts.v2] <tt>std::experimental::function::operator=(F&amp;&amp;)</tt> should be constrained</td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2575">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://cplusplus.github.io/LWG/lwg-defects.html#2576">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://cplusplus.github.io/LWG/lwg-defects.html#2577">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://cplusplus.github.io/LWG/lwg-defects.html#2579">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://cplusplus.github.io/LWG/lwg-defects.html#2581">2581</a></td><td>Specialization of <tt>&lt;type_traits&gt;</tt> variable templates should be prohibited</td><td>Jacksonville</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2582">2582</a></td><td>&sect;[res.on.functions]/2's prohibition against incomplete types shouldn't apply to type traits</td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2583">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://cplusplus.github.io/LWG/lwg-defects.html#2585">2585</a></td><td><tt>forward_list::resize(size_type, const value_type&amp;)</tt> effects incorrect</td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2586">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://cplusplus.github.io/LWG/lwg-defects.html#2590">2590</a></td><td>Aggregate initialization for <tt>std::array</tt></td><td>Jacksonville</td><td>Complete</td></tr>
 
 <!--
-	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#1214">1214</a></td><td>Insufficient/inconsistent key immutability requirements for associative containers</td><td>Urbana</td><td></td></tr>
+	<tr><td><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>
 
-  <p>Last Updated: 27-May-2015</p>
+  <p>Last Updated: 18-May-2016</p>
 </div>
 </body>
 </html>
diff --git a/www/index.html b/www/index.html
index 798d0c8..821f25d 100644
--- a/www/index.html
+++ b/www/index.html
@@ -43,6 +43,16 @@
      under the MIT license and the UIUC License (a BSD-like license).</p>
 
   <!--=====================================================================-->
+  <h2>New Documentation Coming Soon!</h2>
+  <!--=====================================================================-->
+
+  <p> Looking for documentation on how to use, build and test libc++? If so
+      checkout the new libc++ documentation.</p>
+
+  <p><a href="http://libcxx.llvm.org/docs/">
+      Click here for the new libc++ documentation.</a></p>
+
+  <!--=====================================================================-->
   <h2 id="goals">Features and Goals</h2>
   <!--=====================================================================-->
 
diff --git a/www/ts1z_status.html b/www/ts1z_status.html
index b92f053..b85938f 100644
--- a/www/ts1z_status.html
+++ b/www/ts1z_status.html
@@ -35,8 +35,8 @@
   <h1>Post-C++14 TS Implementation Status</h1>
   <!--*********************************************************************-->
 
-  <p>In April 2013, the C++ standard committee approved the draft for the next version of the C++ standard, known as "C++1Y" (probably to be C++14)</p>
-  <p>The draft standard includes papers and issues that were voted on at the previous three meetings (Kona, Portland, and Bristol)</p>
+  <p>In November 2014, the C++ standard committee approved the draft for the next version of the C++ standard, known as "C++1z" (probably to be C++17)</p>
+  <p>In addition, there are several "Technical Specifications", that consist of new features that are proposed, but not yet accepted for C++1z.</p>
   <p>This page shows the status of libc++; the status of clang's support of the language features is <a href="http://clang.llvm.org/cxx_status.html">here</a>.</p>
 
   <h3>Technical Specifications</h3>
@@ -72,7 +72,15 @@
 	<tr><td>Time Utilities</td><td>Complete</td></tr>
 	<tr><td>System Error Support</td><td>Complete</td></tr>
   <tr><td></td><td></td></tr>
-	<tr><td>Searchers</td><td>Implementation in progress</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>
 	<tr><td>string_view</td><td>Complete</td></tr>
@@ -91,11 +99,11 @@
   <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><td>All features</td><td>In Review</td></tr>
 
   </table>
 
-  <p>Last Updated: 21-Jul-2015</p>
+  <p>Last Updated: 7-Dec-2015</p>
 </div>
 </body>
 </html>
diff --git a/www/upcoming_meeting.html b/www/upcoming_meeting.html
new file mode 100644
index 0000000..3904f75
--- /dev/null
+++ b/www/upcoming_meeting.html
@@ -0,0 +1,129 @@
+<!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++ Jacksonville 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++ Jacksonville 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 Jacksonville.</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><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2192">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://cplusplus.github.io/LWG/lwg-defects.html#2253">2253</a></td><td>[arrays.ts] <tt>dynarray</tt> should state which container requirements aren't met</td><td>Jacksonville</td><td>Nothing to do</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2255">2255</a></td><td>[arrays.ts] <tt>dynarray</tt> constructor ambiguity</td><td>Jacksonville</td><td>Nothing to do</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2276">2276</a></td><td>Missing requirement on <tt>std::promise::set_exception</tt></td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2450">2450</a></td><td><tt>(greater|less|greater_equal|less_equal)&lt;void&gt;</tt> do not yield a total order for pointers</td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2520">2520</a></td><td>N4089 broke initializing <tt>unique_ptr&lt;T[]&gt;</tt> from a <tt>nullptr</tt></td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2522">2522</a></td><td>[fund.ts.v2] Contradiction in <tt>set_default_resource</tt> specification</td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2523">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://cplusplus.github.io/LWG/lwg-defects.html#2537">2537</a></td><td>Constructors for <code>priority_queue</code> taking allocators should call <code>make_heap</code></td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2539">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://cplusplus.github.io/LWG/lwg-defects.html#2545">2545</a></td><td>Simplify wording for <tt>bind</tt> without explicitly specified return type</td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2557">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://cplusplus.github.io/LWG/lwg-defects.html#2558">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://cplusplus.github.io/LWG/lwg-defects.html#2559">2559</a></td><td>Error in LWG 2234's resolution</td><td>Jacksonville</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2560">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://cplusplus.github.io/LWG/lwg-defects.html#2565">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></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2566">2566</a></td><td>Requirements on the first template parameter of container adaptors</td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2571">2571</a></td><td>&sect;[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://cplusplus.github.io/LWG/lwg-defects.html#2572">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://cplusplus.github.io/LWG/lwg-defects.html#2574">2574</a></td><td>[fund.ts.v2] <tt>std::experimental::function::operator=(F&amp;&amp;)</tt> should be constrained</td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2575">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://cplusplus.github.io/LWG/lwg-defects.html#2576">2576</a></td><td><tt>istream_iterator</tt> and <tt>ostream_iterator</tt> should use <tt>std::addressof</tt></td><td>Jacksonville</td><td>Patch done; needs tests</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2577">2577</a></td><td><tt>{shared,unique}_lock</tt> should use <tt>std::addressof</tt></td><td>Jacksonville</td><td></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2579">2579</a></td><td>Inconsistency wrt Allocators in <tt>basic_string</tt> assignment vs. <tt>basic_string::assign</tt></td><td>Jacksonville</td><td><i>Patch Ready</i></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2581">2581</a></td><td>Specialization of <tt>&lt;type_traits&gt;</tt> variable templates should be prohibited</td><td>Jacksonville</td><td>Complete</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2582">2582</a></td><td>&sect;[res.on.functions]/2's prohibition against incomplete types shouldn't apply to type traits</td><td>Jacksonville</td><td>In Progress</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2583">2583</a></td><td>There is no way to supply an allocator for <tt>basic_string(str, pos)</tt></td><td>Jacksonville</td><td><i>Patch Ready</i></td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2585">2585</a></td><td><tt>forward_list::resize(size_type, const value_type&amp;)</tt> effects incorrect</td><td>Jacksonville</td><td>Disputed</td></tr>
+	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2586">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://cplusplus.github.io/LWG/lwg-defects.html#2590">2590</a></td><td>Aggregate initialization for <tt>std::array</tt></td><td>Jacksonville</td><td>Complete</td></tr>
+  </table>
+
+<h3>Comments about the issues</h3>
+<ul>
+<li>2192 - </li>
+<li>2253 - Arrays.ts is moribund. No action needed.</li>
+<li>2255 - Arrays.ts is moribund. No action needed.</li>
+<li>2276 - </li>
+<li>2450 - </li>
+<li>2520 - We need to implement N4089 before doing this.</li>
+<li>2522 - I don't think we have a PMR implementation yet.</li>
+<li>2523 - Cleaning up wording; no code change required.</li>
+<li>2537 - </li>
+<li>2539 - </li>
+<li>2545 - </li>
+<li>2557 - Cleaning up wording; no code change required.</li>
+<li>2558 - Cleaning up wording; no code change required.</li>
+<li>2559 - Cleaning up wording; no code change required.</li>
+<li>2560 - We already do this; added tests in r261653. <i>More: the new tests fail on green-dragon-09, so I reverted it. Will recommit after green-dragon bots are updated. Probably need to XFAIL for clang3-6 as well (arm bots)</i></li>
+<li>2565 - </li>
+<li>2566 - </li>
+<li>2571 - Cleaning up wording; no code change required.</li>
+<li>2572 - We already do this.</li>
+<li>2574 - </li>
+<li>2575 - I don't think we ever implemented this; so 'removing' it is trivial</li>
+<li>2576 - This one is simple, but testing it will be hard. I tried making a sublass of istringstream, but it got sliced.</li>
+<li>2577 - This one is simple</li>
+<li>2579 - <i>Done</i></li>
+<li>2581 - Nothing to do here.</li>
+<li>2582 - I've added tests to meta.unary.cat; no code changes needed yet.</li>
+<li>2583 - <i>Done</i></li>
+<li>2585 - This looks easy; but Alisdair wants to NAD this issue.</li>
+<li>2586 - We need to fix <a href="http:/llvm.org/PR24075">PR24075</a> when we do this.</li>
+<li>2590 - We already do this; added tests in r261648.</li>
+</ul>
+
+<p>Last Updated: 23-Feb-2015</p>
+</div>
+</body>
+</html>