Release 13.x of llvm/libcxx
diff --git a/.arcconfig b/.arcconfig
deleted file mode 100644
index 6d07e82..0000000
--- a/.arcconfig
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "project_id" : "libcxx",
-  "conduit_uri" : "http://reviews.llvm.org/"
-}
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..cfa0c28
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,16 @@
+BasedOnStyle: LLVM
+
+---
+Language: Cpp
+Standard: Cpp03
+
+AlwaysBreakTemplateDeclarations: true
+PointerAlignment: Left
+
+# Disable formatting options which may break tests.
+SortIncludes: false
+ReflowComments: false
+
+# libc++ has some long names so we need more than the 80 column limit imposed by LLVM style, for sensible formatting
+ColumnLimit: 120
+---
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4b214ca
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,55 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+#lib/ # We actually have things checked in to lib/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.cache
+nosetests.xml
+coverage.xml
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# MSVC libraries test harness
+env.lst
+keep.lst
+
+# Editor by-products
+.vscode/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c3b375e..b1e2535 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,16 +1,14 @@
-# See www/CMake.html for instructions on how to build libcxx with CMake.
+# See https://libcxx.llvm.org/docs/BuildingLibcxx.html for instructions on how
+# to build libcxx with CMake.
+
+if (NOT IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../libcxxabi")
+  message(FATAL_ERROR "libc++ now requires being built in a monorepo layout with libcxxabi available")
+endif()
 
 #===============================================================================
 # Setup Project
 #===============================================================================
-
-project(libcxx CXX C)
-cmake_minimum_required(VERSION 2.8)
-
-set(PACKAGE_NAME libcxx)
-set(PACKAGE_VERSION trunk-svn)
-set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
-set(PACKAGE_BUGREPORT "llvmbugs@cs.uiuc.edu")
+cmake_minimum_required(VERSION 3.13.4)
 
 # Add path for custom modules
 set(CMAKE_MODULE_PATH
@@ -19,280 +17,954 @@
   ${CMAKE_MODULE_PATH}
   )
 
+set(CMAKE_FOLDER "libc++")
+
+set(LIBCXX_SOURCE_DIR  ${CMAKE_CURRENT_SOURCE_DIR})
+set(LIBCXX_BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR})
+set(LIBCXX_BINARY_INCLUDE_DIR "${LIBCXX_BINARY_DIR}/include/c++build")
+
+if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LIBCXX_STANDALONE_BUILD)
+  project(libcxx CXX C)
+
+  set(PACKAGE_NAME libcxx)
+  set(PACKAGE_VERSION 13.0.0git)
+  set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
+  set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org")
+
+  # In a standalone build, we don't have llvm to automatically generate the
+  # llvm-lit script for us.  So we need to provide an explicit directory that
+  # the configurator should write the script into.
+  set(LIBCXX_STANDALONE_BUILD 1)
+  set(LLVM_LIT_OUTPUT_DIR "${LIBCXX_BINARY_DIR}/bin")
+
+  # Find the LLVM sources and simulate LLVM CMake options.
+  include(HandleOutOfTreeLLVM)
+endif()
+
+if (LIBCXX_STANDALONE_BUILD)
+  find_package(Python3 COMPONENTS Interpreter)
+  if(NOT Python3_Interpreter_FOUND)
+    message(WARNING "Python3 not found, using python2 as a fallback")
+    find_package(Python2 COMPONENTS Interpreter REQUIRED)
+    if(Python2_VERSION VERSION_LESS 2.7)
+      message(SEND_ERROR "Python 2.7 or newer is required")
+    endif()
+
+    # Treat python2 as python3
+    add_executable(Python3::Interpreter IMPORTED)
+    set_target_properties(Python3::Interpreter PROPERTIES
+      IMPORTED_LOCATION ${Python2_EXECUTABLE})
+    set(Python3_EXECUTABLE ${Python2_EXECUTABLE})
+  endif()
+endif()
+
 # Require out of source build.
 include(MacroEnsureOutOfSourceBuild)
 MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
  "${PROJECT_NAME} requires an out of source build. Please create a separate
  build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there."
  )
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
+  message(STATUS "Configuring for clang-cl")
+  set(LIBCXX_TARGETING_CLANG_CL ON)
+endif()
 
-if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
-  set(LIBCXX_BUILT_STANDALONE 1)
+if (MSVC)
+  set(LIBCXX_TARGETING_MSVC ON)
+  message(STATUS "Configuring for MSVC")
+else()
+  set(LIBCXX_TARGETING_MSVC OFF)
 endif()
 
 #===============================================================================
 # Setup CMake Options
 #===============================================================================
+include(CMakeDependentOption)
+include(HandleCompilerRT)
 
-# Define options.
+# Basic options ---------------------------------------------------------------
+option(LIBCXX_ENABLE_ASSERTIONS "Enable assertions independent of build mode." OFF)
+option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON)
+option(LIBCXX_ENABLE_STATIC "Build libc++ as a static library." ON)
+option(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY "Build libc++experimental.a" ON)
+set(ENABLE_FILESYSTEM_DEFAULT ON)
+if (WIN32 AND NOT MINGW)
+  # Filesystem is buildable for windows, but it requires __int128 helper
+  # functions, that currently are provided by libgcc or compiler_rt builtins.
+  # These are available in MinGW environments, but not currently in MSVC
+  # environments.
+  set(ENABLE_FILESYSTEM_DEFAULT OFF)
+endif()
+option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of the main libc++ library"
+    ${ENABLE_FILESYSTEM_DEFAULT})
+option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
+option(LIBCXX_ENABLE_PARALLEL_ALGORITHMS "Enable the parallel algorithms library. This requires the PSTL to be available." OFF)
+option(LIBCXX_ENABLE_DEBUG_MODE_SUPPORT
+  "Whether to include support for libc++'s debugging mode in the library.
+   By default, this is turned on. If you turn it off and try to enable the
+   debug mode when compiling a program against libc++, it will fail to link
+   since the required support isn't provided in the library." ON)
+option(LIBCXX_ENABLE_RANDOM_DEVICE
+  "Whether to include support for std::random_device in the library. Disabling
+   this can be useful when building the library for platforms that don't have
+   a source of randomness, such as some embedded platforms. When this is not
+   supported, most of <random> will still be available, but std::random_device
+   will not." ON)
+option(LIBCXX_ENABLE_LOCALIZATION
+  "Whether to include support for localization in the library. Disabling
+   localization can be useful when porting to platforms that don't support
+   the C locale API (e.g. embedded). When localization is not supported,
+   several parts of the library will be disabled: <iostream>, <regex>, <locale>
+   will be completely unusable, and other parts may be only partly available." ON)
+option(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS
+  "Whether to turn on vendor availability annotations on declarations that depend
+   on definitions in a shared library. By default, we assume that we're not building
+   libc++ for any specific vendor, and we disable those annotations. Vendors wishing
+   to provide compile-time errors when using features unavailable on some version of
+   the shared library they shipped should turn this on and see `include/__availability`
+   for more details." OFF)
+option(LIBCXX_ENABLE_INCOMPLETE_FEATURES
+    "Whether to enable support for incomplete library features. Incomplete features
+    are new library features under development. These features don't guarantee
+    ABI stability nor the quality of completed library features. Vendors
+    shipping the library may want to disable this option." ON)
+set(LIBCXX_TEST_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/test/configs/legacy.cfg.in" CACHE STRING
+    "The Lit testing configuration to use when running the tests.")
+set(LIBCXX_TEST_PARAMS "" CACHE STRING
+    "A list of parameters to run the Lit test suite with.")
+
+# Benchmark options -----------------------------------------------------------
+option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their dependencies" ON)
+
+set(LIBCXX_BENCHMARK_TEST_ARGS_DEFAULT --benchmark_min_time=0.01)
+set(LIBCXX_BENCHMARK_TEST_ARGS "${LIBCXX_BENCHMARK_TEST_ARGS_DEFAULT}" CACHE STRING
+    "Arguments to pass when running the benchmarks using check-cxx-benchmarks")
+
+set(LIBCXX_BENCHMARK_NATIVE_STDLIB "" CACHE STRING
+        "Build the benchmarks against the specified native STL.
+         The value must be one of libc++/libstdc++")
+set(LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN "" CACHE STRING
+    "Use alternate GCC toolchain when building the native benchmarks")
+
+if (LIBCXX_BENCHMARK_NATIVE_STDLIB)
+  if (NOT (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libc++"
+        OR LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++"))
+    message(FATAL_ERROR "Invalid value for LIBCXX_BENCHMARK_NATIVE_STDLIB: "
+            "'${LIBCXX_BENCHMARK_NATIVE_STDLIB}'")
+  endif()
+endif()
+
+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)
+cmake_dependent_option(LIBCXX_INSTALL_STATIC_LIBRARY
+  "Install the static libc++ library." ON
+  "LIBCXX_ENABLE_STATIC;LIBCXX_INSTALL_LIBRARY" OFF)
+cmake_dependent_option(LIBCXX_INSTALL_SHARED_LIBRARY
+  "Install the shared libc++ library." ON
+  "LIBCXX_ENABLE_SHARED;LIBCXX_INSTALL_LIBRARY" OFF)
+cmake_dependent_option(LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY
+        "Install libc++experimental.a" ON
+        "LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY;LIBCXX_INSTALL_LIBRARY" OFF)
+
+set(LIBCXX_ABI_VERSION "1" CACHE STRING "ABI version of libc++. Can be either 1 or 2, where 2 is currently not stable. Defaults to 1.")
+set(LIBCXX_ABI_NAMESPACE "" CACHE STRING "The inline ABI namespace used by libc++. It defaults to __n where `n` is the current ABI version.")
+option(LIBCXX_ABI_UNSTABLE "Unstable ABI of libc++." OFF)
+option(LIBCXX_ABI_FORCE_ITANIUM "Ignore auto-detection and force use of the Itanium ABI.")
+option(LIBCXX_ABI_FORCE_MICROSOFT "Ignore auto-detection and force use of the Microsoft ABI.")
+
+set(LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION "default" CACHE STRING
+  "Override the implementation to use for comparing typeinfos. By default, this
+   is detected automatically by the library, but this option allows overriding
+   which implementation is used unconditionally.
+
+   See the documentation in <libcxx/include/typeinfo> for details on what each
+   value means.")
+set(TYPEINFO_COMPARISON_VALUES "default;1;2;3")
+if (NOT ("${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}" IN_LIST TYPEINFO_COMPARISON_VALUES))
+  message(FATAL_ERROR "Value '${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}' is not a valid value for
+                       LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION")
+endif()
+
+option(LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT "Enable per TU ABI insulation by default. To be used by vendors." OFF)
+set(LIBCXX_ABI_DEFINES "" CACHE STRING "A semicolon separated list of ABI macros to define in the site config header.")
+option(LIBCXX_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF)
+set(LIBCXX_LIBCPPABI_VERSION "2" CACHE STRING "Version of libc++abi's ABI to re-export from libc++ when re-exporting is enabled.
+                                               Note that this is not related to the version of libc++'s ABI itself!")
+
+# ABI Library options ---------------------------------------------------------
+set(LIBCXX_CXX_ABI "default" CACHE STRING "Specify C++ ABI library to use.")
+set(CXXABIS none default libcxxabi libcxxrt libstdc++ libsupc++ vcruntime)
+set_property(CACHE LIBCXX_CXX_ABI PROPERTY STRINGS ;${CXXABIS})
+
+# Setup the default options if LIBCXX_CXX_ABI is not specified.
+if (LIBCXX_CXX_ABI STREQUAL "default")
+  if (LIBCXX_TARGETING_MSVC)
+    # FIXME: Figure out how to configure the ABI library on Windows.
+    set(LIBCXX_CXX_ABI_LIBNAME "vcruntime")
+  elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
+    set(LIBCXX_CXX_ABI_LIBNAME "libcxxrt")
+  elseif (NOT LIBCXX_STANDALONE_BUILD OR HAVE_LIBCXXABI)
+    set(LIBCXX_CXX_ABI_LIBNAME "libcxxabi")
+  else()
+    set(LIBCXX_CXX_ABI_LIBNAME "default")
+  endif()
+else()
+  set(LIBCXX_CXX_ABI_LIBNAME "${LIBCXX_CXX_ABI}")
+endif()
+
+option(LIBCXX_ENABLE_STATIC_ABI_LIBRARY
+  "Use a static copy of the ABI library when linking libc++.
+   This option cannot be used with LIBCXX_ENABLE_ABI_LINKER_SCRIPT." OFF)
+
+cmake_dependent_option(LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY
+  "Statically link the ABI library to static library" ON
+  "LIBCXX_ENABLE_STATIC_ABI_LIBRARY;LIBCXX_ENABLE_STATIC" OFF)
+
+cmake_dependent_option(LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY
+  "Statically link the ABI library to shared library" ON
+  "LIBCXX_ENABLE_STATIC_ABI_LIBRARY;LIBCXX_ENABLE_SHARED" 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_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY
+      AND NOT LIBCXX_CXX_ABI_LIBNAME STREQUAL "none"
+      AND NOT LIBCXX_CXX_ABI_LIBNAME STREQUAL "default"
+      AND Python3_EXECUTABLE
+      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})
+
+option(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS
+  "Build libc++ with definitions for operator new/delete. These are normally
+   defined in libc++abi, but this option can be used to define them in libc++
+   instead. If you define them in libc++, make sure they are NOT defined in
+   libc++abi. Doing otherwise is an ODR violation." OFF)
+# Build libc++abi with libunwind. We need this option to determine whether to
+# link with libunwind or libgcc_s while running the test cases.
+option(LIBCXXABI_USE_LLVM_UNWINDER "Build and use the LLVM unwinder." OFF)
+
+# Target options --------------------------------------------------------------
+option(LIBCXX_BUILD_32_BITS "Build 32 bit libc++." ${LLVM_BUILD_32_BITS})
+set(LIBCXX_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}" CACHE STRING "Use alternate target triple.")
+set(LIBCXX_SYSROOT "" CACHE STRING "Use alternate sysroot.")
+set(LIBCXX_GCC_TOOLCHAIN "" CACHE STRING "Use alternate GCC toolchain.")
+
+# Feature options -------------------------------------------------------------
 option(LIBCXX_ENABLE_EXCEPTIONS "Use exceptions." ON)
 option(LIBCXX_ENABLE_RTTI "Use run time type information." ON)
-option(LIBCXX_ENABLE_ASSERTIONS "Enable assertions independent of build mode." ON)
-option(LIBCXX_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
-option(LIBCXX_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
-option(LIBCXX_ENABLE_CXX0X "Enable -std=c++0x and use of c++0x language features if the compiler supports it." ON)
-option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON)
-option(LIBCXX_INSTALL_SUPPORT_HEADERS "Install libc++ support headers." ON)
+option(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE "Build libc++ with support for the global filesystem namespace." ON)
+option(LIBCXX_ENABLE_STDIN "Build libc++ with support for stdin/std::cin." ON)
+option(LIBCXX_ENABLE_STDOUT "Build libc++ with support for stdout/std::cout." ON)
+option(LIBCXX_ENABLE_THREADS "Build libc++ with support for threads." ON)
+option(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS "Build libc++ with support for thread-unsafe C functions" ON)
+option(LIBCXX_ENABLE_MONOTONIC_CLOCK
+  "Build libc++ with support for a monotonic clock.
+   This option may only be set to OFF when LIBCXX_ENABLE_THREADS=OFF." ON)
+option(LIBCXX_HAS_MUSL_LIBC "Build libc++ with support for the Musl C library" OFF)
+option(LIBCXX_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread API" OFF)
+option(LIBCXX_HAS_WIN32_THREAD_API "Ignore auto-detection and force use of win32 thread API" OFF)
+option(LIBCXX_HAS_EXTERNAL_THREAD_API
+  "Build libc++ with an externalized threading API.
+   This option may only be set to ON when LIBCXX_ENABLE_THREADS=ON." OFF)
+option(LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY
+    "Build libc++ with an externalized threading library.
+     This option may only be set to ON when LIBCXX_ENABLE_THREADS=ON" OFF)
 
-set(CXXABIS none libcxxabi libcxxrt libstdc++ libsupc++)
-if (NOT LIBCXX_CXX_ABI)
-  if (NOT DEFINED LIBCXX_BUILT_STANDALONE AND
-      IS_DIRECTORY "${CMAKE_SOURCE_DIR}/projects/libcxxabi")
-    set(LIBCXX_CXX_ABI_LIBNAME "libcxxabi")
-    set(LIBCXX_LIBCXXABI_INCLUDE_PATHS "${CMAKE_SOURCE_DIR}/projects/libcxxabi/include")
-    set(LIBCXX_CXX_ABI_INTREE 1)
-  else ()
-    set(LIBCXX_CXX_ABI_LIBNAME "none")
-  endif ()
-else ()
-  set(LIBCXX_CXX_ABI_LIBNAME "${LIBCXX_CXX_ABI}")
+# Misc options ----------------------------------------------------------------
+# FIXME: Turn -pedantic back ON. It is currently off because it warns
+# about #include_next which is used everywhere.
+option(LIBCXX_ENABLE_PEDANTIC "Compile with pedantic enabled." OFF)
+option(LIBCXX_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
+option(LIBCXX_DISABLE_MACRO_CONFLICT_WARNINGS "Disable #warnings about conflicting macros." OFF)
+
+option(LIBCXX_GENERATE_COVERAGE "Enable generating code coverage." OFF)
+set(LIBCXX_COVERAGE_LIBRARY "" CACHE STRING
+    "The Profile-rt library used to build with code coverage")
+
+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})
+
+option(LIBCXX_HERMETIC_STATIC_LIBRARY
+  "Do not export any symbols from the static library." OFF)
+
+#===============================================================================
+# Check option configurations
+#===============================================================================
+
+# Ensure LIBCXX_ENABLE_MONOTONIC_CLOCK is set to ON only when
+# LIBCXX_ENABLE_THREADS is on.
+if(LIBCXX_ENABLE_THREADS AND NOT LIBCXX_ENABLE_MONOTONIC_CLOCK)
+  message(FATAL_ERROR "LIBCXX_ENABLE_MONOTONIC_CLOCK can only be set to OFF"
+                      " when LIBCXX_ENABLE_THREADS is also set to OFF.")
+endif()
+
+if(NOT LIBCXX_ENABLE_THREADS)
+  if(LIBCXX_HAS_PTHREAD_API)
+    message(FATAL_ERROR "LIBCXX_HAS_PTHREAD_API can only be set to ON"
+                        " when LIBCXX_ENABLE_THREADS is also set to ON.")
+  endif()
+  if(LIBCXX_HAS_EXTERNAL_THREAD_API)
+    message(FATAL_ERROR "LIBCXX_HAS_EXTERNAL_THREAD_API can only be set to ON"
+                        " when LIBCXX_ENABLE_THREADS is also set to ON.")
+  endif()
+  if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
+    message(FATAL_ERROR "LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY can only be set "
+                        "to ON when LIBCXX_ENABLE_THREADS is also set to ON.")
+  endif()
+  if (LIBCXX_HAS_WIN32_THREAD_API)
+    message(FATAL_ERROR "LIBCXX_HAS_WIN32_THREAD_API can only be set to ON"
+                        " when LIBCXX_ENABLE_THREADS is also set to ON.")
+  endif()
+
+endif()
+
+if (LIBCXX_HAS_EXTERNAL_THREAD_API)
+  if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
+    message(FATAL_ERROR "The options LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY and "
+                        "LIBCXX_HAS_EXTERNAL_THREAD_API cannot both be ON at "
+                        "the same time")
+  endif()
+  if (LIBCXX_HAS_PTHREAD_API)
+    message(FATAL_ERROR "The options LIBCXX_HAS_EXTERNAL_THREAD_API"
+                        "and LIBCXX_HAS_PTHREAD_API cannot be both"
+                        "set to ON at the same time.")
+  endif()
+  if (LIBCXX_HAS_WIN32_THREAD_API)
+    message(FATAL_ERROR "The options LIBCXX_HAS_EXTERNAL_THREAD_API"
+                        "and LIBCXX_HAS_WIN32_THREAD_API cannot be both"
+                        "set to ON at the same time.")
+  endif()
+endif()
+
+if (LIBCXX_HAS_PTHREAD_API)
+  if (LIBCXX_HAS_WIN32_THREAD_API)
+    message(FATAL_ERROR "The options LIBCXX_HAS_PTHREAD_API"
+                        "and LIBCXX_HAS_WIN32_THREAD_API cannot be both"
+                        "set to ON at the same time.")
+  endif()
+endif()
+
+# Ensure LLVM_USE_SANITIZER is not specified when LIBCXX_GENERATE_COVERAGE
+# is ON.
+if (LLVM_USE_SANITIZER AND LIBCXX_GENERATE_COVERAGE)
+  message(FATAL_ERROR "LLVM_USE_SANITIZER cannot be used with LIBCXX_GENERATE_COVERAGE")
+endif()
+
+# Set LIBCXX_BUILD_32_BITS to (LIBCXX_BUILD_32_BITS OR LLVM_BUILD_32_BITS)
+# and check that we can build with 32 bits if requested.
+if (CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32)
+  if (LIBCXX_BUILD_32_BITS AND NOT LLVM_BUILD_32_BITS) # Don't duplicate the output from LLVM
+    message(STATUS "Building 32 bits executables and libraries.")
+  endif()
+elseif(LIBCXX_BUILD_32_BITS)
+  message(FATAL_ERROR "LIBCXX_BUILD_32_BITS=ON is not supported on this platform.")
+endif()
+
+# Warn users that LIBCXX_ENABLE_STATIC_ABI_LIBRARY is an experimental option.
+if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY)
+  message(WARNING "LIBCXX_ENABLE_STATIC_ABI_LIBRARY is an experimental option")
+  if (LIBCXX_ENABLE_STATIC AND NOT Python3_EXECUTABLE)
+    message(FATAL_ERROR "LIBCXX_ENABLE_STATIC_ABI_LIBRARY requires python but it was not found.")
+  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 LIBCXX_ENABLE_SHARED)
+      message(FATAL_ERROR "LIBCXX_ENABLE_ABI_LINKER_SCRIPT is only available for shared library builds.")
+    endif()
+endif()
+
+if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_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_ABI_FORCE_ITANIUM AND LIBCXX_ABI_FORCE_MICROSOFT)
+  message(FATAL_ERROR "Only one of LIBCXX_ABI_FORCE_ITANIUM and LIBCXX_ABI_FORCE_MICROSOFT can be specified.")
 endif ()
-set(LIBCXX_CXX_ABI "${LIBCXX_CXX_ABI}" CACHE STRING
-    "Specify C++ ABI library to use." FORCE)
-set_property(CACHE LIBCXX_CXX_ABI PROPERTY STRINGS ;${CXXABIS})
 
 #===============================================================================
 # Configure System
 #===============================================================================
 
-# Get triples.
-include(GetTriple)
-get_host_triple(LIBCXX_HOST_TRIPLE
-  LIBCXX_HOST_ARCH
-  LIBCXX_HOST_VENDOR
-  LIBCXX_HOST_OS
-  )
-set(LIBCXX_HOST_TRIPLE ${LIBCXX_HOST_TRIPLE} CACHE STRING "Host triple.")
-get_target_triple(LIBCXX_TARGET_TRIPLE
-  LIBCXX_TARGET_ARCH
-  LIBCXX_TARGET_VENDOR
-  LIBCXX_TARGET_OS
-  )
-set(LIBCXX_TARGET_TRIPLE ${LIBCXX_TARGET_TRIPLE} CACHE STRING "Target triple.")
-
-#===============================================================================
-# Add an ABI library if appropriate
-#===============================================================================
-
-#
-# _setup_abi: Set up the build to use an ABI library
-#
-# Parameters:
-#   abidefines: A list of defines needed to compile libc++ with the ABI library
-#   abilibs   : A list of libraries to link against
-#   abifiles  : A list of files (which may be relative paths) to copy into the
-#               libc++ build tree for the build.  These files will also be
-#               installed alongside the libc++ headers.
-#   abidirs   : A list of relative paths to create under an include directory
-#               in the libc++ build directory.
-#
-macro(setup_abi_lib abipathvar abidefines abilibs abifiles abidirs)
-  list(APPEND LIBCXX_CXX_FEATURE_FLAGS ${abidefines})
-  set(${abipathvar} "${${abipathvar}}"
-    CACHE PATH
-    "Paths to C++ ABI header directories separated by ';'." FORCE
-    )
-  set(LIBCXX_CXX_ABI_LIBRARIES ${abilibs})
-  set(LIBCXX_ABILIB_FILES ${abifiles})
-
-  file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include")
-  foreach(_d ${abidirs})
-    file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include/${_d}")
-  endforeach()
-
-  foreach(fpath ${LIBCXX_ABILIB_FILES})
-    set(found FALSE)
-    foreach(incpath ${${abipathvar}})
-      if (EXISTS "${incpath}/${fpath}")
-        set(found TRUE)
-        get_filename_component(dstdir ${fpath} PATH)
-        get_filename_component(ifile ${fpath} NAME)
-        file(COPY "${incpath}/${fpath}"
-          DESTINATION "${CMAKE_BINARY_DIR}/include/${dstdir}"
-          )
-        list(APPEND abilib_headers "${CMAKE_BINARY_DIR}/include/${fpath}")
-      endif()
-    endforeach()
-    if (NOT found)
-      message(FATAL_ERROR "Failed to find ${fpath}")
-    endif()
-  endforeach()
-
-  add_custom_target(LIBCXX_CXX_ABI_DEPS DEPENDS ${abilib_headers})
-  include_directories("${CMAKE_BINARY_DIR}/include")
-
-  install(FILES ${abilib_headers}
-    DESTINATION include/c++/v1
-    PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
-    )
-endmacro()
-
-if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++" OR
-    "${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libsupc++")
-  set(_LIBSUPCXX_INCLUDE_FILES
-    cxxabi.h bits/c++config.h bits/os_defines.h bits/cpu_defines.h
-    bits/cxxabi_tweaks.h bits/cxxabi_forced.h
-    )
-  if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++")
-    set(_LIBSUPCXX_DEFINES "-DLIBSTDCXX")
-    set(_LIBSUPCXX_LIBNAME stdc++)
-  else()
-    set(_LIBSUPCXX_DEFINES "")
-    set(_LIBSUPCXX_LIBNAME supc++)
+# TODO: Projects that depend on libc++ should use LIBCXX_GENERATED_INCLUDE_DIR
+# instead of hard-coding include/c++/v1.
+if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
+  set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE})
+  set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1")
+  set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LLVM_BINARY_DIR}/include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1")
+  set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH
+      "Path where built libc++ libraries should be installed.")
+  set(LIBCXX_INSTALL_INCLUDE_DIR "include/c++/v1" CACHE PATH
+      "Path where target-agnostic libc++ headers should be installed.")
+  set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1" CACHE PATH
+      "Path where target-specific libc++ headers should be installed.")
+  if(LIBCXX_LIBDIR_SUBDIR)
+    string(APPEND LIBCXX_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR})
+    string(APPEND LIBCXX_INSTALL_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR})
   endif()
-  setup_abi_lib("LIBCXX_LIBSUPCXX_INCLUDE_PATHS"
-    "-D__GLIBCXX__ ${_LIBSUPCXX_DEFINES}"
-    "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_INCLUDE_FILES}" "bits"
-    )
-elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxabi")
-  if (LIBCXX_CXX_ABI_INTREE)
-    # Link against just-built "cxxabi" target.
-    set(CXXABI_LIBNAME cxxabi)
-  else()
-    # Assume c++abi is installed in the system, rely on -lc++abi link flag.
-    set(CXXABI_LIBNAME "c++abi")
-  endif()
-  setup_abi_lib("LIBCXX_LIBCXXABI_INCLUDE_PATHS" ""
-    ${CXXABI_LIBNAME} "cxxabi.h" ""
-    )
-elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxrt")
-  setup_abi_lib("LIBCXX_LIBCXXRT_INCLUDE_PATHS" "-DLIBCXXRT"
-    "cxxrt" "cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h" ""
-    )
-elseif (NOT "${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "none")
-  message(FATAL_ERROR
-    "Currently libstdc++, libsupc++, libcxxabi, libcxxrt and none are "
-    "supported for c++ abi."
-    )
-endif ()
+elseif(LLVM_LIBRARY_OUTPUT_INTDIR)
+  set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
+  set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1")
+  set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LIBCXX_GENERATED_INCLUDE_DIR}")
+  set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX} CACHE PATH
+      "Path where built libc++ libraries should be installed.")
+  set(LIBCXX_INSTALL_INCLUDE_DIR "include/c++/v1" CACHE PATH
+      "Path where target-agnostic libc++ headers should be installed.")
+  set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${LIBCXX_INSTALL_INCLUDE_DIR}" CACHE PATH
+      "Path where target-specific libc++ headers should be installed.")
+else()
+  set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX})
+  set(LIBCXX_GENERATED_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include/c++/v1")
+  set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LIBCXX_GENERATED_INCLUDE_DIR}")
+  set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX} CACHE PATH
+      "Path where built libc++ libraries should be installed.")
+  set(LIBCXX_INSTALL_INCLUDE_DIR "include/c++/v1" CACHE PATH
+      "Path where target-agnostic libc++ headers should be installed.")
+  set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${LIBCXX_INSTALL_INCLUDE_DIR}" CACHE PATH
+      "Path where target-specific libc++ headers should be installed.")
+endif()
+
+file(MAKE_DIRECTORY "${LIBCXX_BINARY_INCLUDE_DIR}")
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})
+
+# Declare libc++ configuration variables.
+# They are intended for use as follows:
+# LIBCXX_CXX_FLAGS: General flags for both the compiler and linker.
+# LIBCXX_COMPILE_FLAGS: Compile only flags.
+# LIBCXX_LINK_FLAGS: Linker only flags.
+# LIBCXX_LIBRARIES: libraries libc++ is linked to.
+set(LIBCXX_COMPILE_FLAGS "")
+set(LIBCXX_LINK_FLAGS "")
+set(LIBCXX_LIBRARIES "")
+
+# Include macros for adding and removing libc++ flags.
+include(HandleLibcxxFlags)
+
+# Target flags ================================================================
+# These flags get added to CMAKE_CXX_FLAGS and CMAKE_C_FLAGS so that
+# 'config-ix' use them during feature checks. It also adds them to both
+# 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS'
+add_target_flags_if(LIBCXX_BUILD_32_BITS "-m32")
+
+if(LIBCXX_TARGET_TRIPLE)
+  add_target_flags_if_supported("--target=${LIBCXX_TARGET_TRIPLE}")
+elseif(CMAKE_CXX_COMPILER_TARGET)
+  set(LIBCXX_TARGET_TRIPLE "${CMAKE_CXX_COMPILER_TARGET}")
+endif()
+if(LIBCXX_SYSROOT)
+  add_target_flags_if_supported("--sysroot=${LIBCXX_SYSROOT}")
+elseif(CMAKE_SYSROOT)
+  set(LIBCXX_SYSROOT "${CMAKE_SYSROOT}")
+endif()
+if(LIBCXX_GCC_TOOLCHAIN)
+  add_target_flags_if_supported("--gcc-toolchain=${LIBCXX_GCC_TOOLCHAIN}")
+elseif(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN)
+  set(LIBCXX_GCC_TOOLCHAIN "${CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN}")
+endif()
 
 # Configure compiler.
 include(config-ix)
 
+# Configure coverage options.
+if (LIBCXX_GENERATE_COVERAGE)
+  include(CodeCoverage)
+  set(CMAKE_BUILD_TYPE "COVERAGE" CACHE STRING "" FORCE)
+endif()
+
+string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
+if (uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
+  set(LIBCXX_DEBUG_BUILD ON)
+else()
+  set(LIBCXX_DEBUG_BUILD OFF)
+endif()
+
 #===============================================================================
 # Setup Compiler Flags
 #===============================================================================
 
-# Get required flags.
-# On all systems the system c++ standard library headers need to be excluded.
-if (MSVC)
+include(HandleLibCXXABI) # Setup the ABI library flags
+
+if (NOT LIBCXX_STANDALONE_BUILD)
+  # Remove flags that may have snuck in.
+  remove_flags(-DNDEBUG -UNDEBUG -D_DEBUG
+               -lc++abi)
+endif()
+remove_flags(--stdlib=libc++ -stdlib=libc++ --stdlib=libstdc++ -stdlib=libstdc++)
+
+# FIXME: Remove all debug flags and flags that change which Windows
+# default libraries are linked. Currently we only support linking the
+# non-debug DLLs
+remove_flags("/D_DEBUG" "/MTd" "/MDd" "/MT" "/Md")
+
+# 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 respectively.
+remove_flags(-Wno-pedantic -pedantic-errors -pedantic)
+
+# Required flags ==============================================================
+function(cxx_add_basic_build_flags target)
+
+  # Require C++20 for all targets. C++17 is needed to use aligned allocation
+  # in the dylib. C++20 is needed to use char8_t.
+  set_target_properties(${target} PROPERTIES
+    CXX_STANDARD 20
+    CXX_STANDARD_REQUIRED NO
+    CXX_EXTENSIONS NO)
+
+  # When building the dylib, don't warn for unavailable aligned allocation
+  # functions based on the deployment target -- they are always available
+  # because they are provided by the dylib itself with the excepton of z/OS.
+  if (ZOS)
+    target_add_compile_flags_if_supported(${target} PRIVATE -fno-aligned-allocation)
+  else()
+    target_add_compile_flags_if_supported(${target} PRIVATE -faligned-allocation)
+  endif()
+
+  # On all systems the system c++ standard library headers need to be excluded.
   # MSVC only has -X, which disables all default includes; including the crt.
   # Thus, we do nothing and hope we don't accidentally include any of the C++
-  # headers.
-else()
-  if (LIBCXX_HAS_NOSTDINCXX_FLAG)
-    list(APPEND LIBCXX_CXX_REQUIRED_FLAGS -nostdinc++)
-    string(REPLACE "-stdlib=libc++" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+  # headers
+  target_add_compile_flags_if_supported(${target} PUBLIC -nostdinc++)
+
+  # Hide all inline function definitions which have not explicitly been marked
+  # visible. This prevents new definitions for inline functions from appearing in
+  # the dylib when get ODR used by another function.
+  target_add_compile_flags_if_supported(${target} PRIVATE -fvisibility-inlines-hidden)
+
+  # Our visibility annotations are not quite right for non-Clang compilers,
+  # so we end up not exporting all the symbols we should. In the future, we
+  # can improve the situation by providing an explicit list of exported
+  # symbols on all compilers.
+  if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+    target_add_compile_flags_if_supported(${target} PRIVATE -fvisibility=hidden)
   endif()
-  if (LIBCXX_ENABLE_CXX0X AND LIBCXX_HAS_STDCXX0X_FLAG)
-    list(APPEND LIBCXX_CXX_REQUIRED_FLAGS -std=c++0x)
+
+  if (LIBCXX_CONFIGURE_IDE)
+    # This simply allows IDE to process <experimental/coroutine>
+    target_add_compile_flags_if_supported(${target} PRIVATE -fcoroutines-ts)
+  endif()
+
+  # Let the library headers know they are currently being used to build the
+  # library.
+  target_compile_definitions(${target} PRIVATE -D_LIBCPP_BUILDING_LIBRARY)
+
+  if (NOT LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS)
+    target_compile_definitions(${target} PRIVATE -D_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS)
+  endif()
+
+  if (LIBCXX_HAS_COMMENT_LIB_PRAGMA)
+    if (LIBCXX_HAS_PTHREAD_LIB)
+      target_compile_definitions(${target} PRIVATE -D_LIBCPP_LINK_PTHREAD_LIB)
+    endif()
+    if (LIBCXX_HAS_RT_LIB)
+      target_compile_definitions(${target} PRIVATE -D_LIBCPP_LINK_RT_LIB)
+    endif()
+  endif()
+endfunction()
+
+# Warning flags ===============================================================
+function(cxx_add_warning_flags target)
+  target_compile_definitions(${target} PUBLIC -D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+  if (MSVC)
+    # -W4 is the cl.exe/clang-cl equivalent of -Wall. (In cl.exe and clang-cl,
+    # -Wall is equivalent to -Weverything in GCC style compiler drivers.)
+    target_add_compile_flags_if_supported(${target} PRIVATE -W4)
+  else()
+    target_add_compile_flags_if_supported(${target} PRIVATE -Wall)
+  endif()
+  target_add_compile_flags_if_supported(${target} PRIVATE -Wextra -W -Wwrite-strings
+                                                          -Wno-unused-parameter -Wno-long-long
+                                                          -Werror=return-type -Wextra-semi -Wundef)
+  if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+    target_add_compile_flags_if_supported(${target} PRIVATE
+      -Wno-user-defined-literals
+      -Wno-covered-switch-default
+      -Wno-suggest-override
+      -Wno-ignored-attributes # FIXME: Caused by _LIBCPP_NODEBUG_TYPE not being supported on older clangs
+    )
+    if (LIBCXX_TARGETING_CLANG_CL)
+      target_add_compile_flags_if_supported(${target} PRIVATE
+        -Wno-c++98-compat
+        -Wno-c++98-compat-pedantic
+        -Wno-c++11-compat
+        -Wno-undef
+        -Wno-reserved-id-macro
+        -Wno-gnu-include-next
+        -Wno-gcc-compat # For ignoring "'diagnose_if' is a clang extension" warnings
+        -Wno-zero-as-null-pointer-constant # FIXME: Remove this and fix all occurrences.
+        -Wno-deprecated-dynamic-exception-spec # For auto_ptr
+        -Wno-sign-conversion
+        -Wno-old-style-cast
+        -Wno-deprecated # FIXME: Remove this and fix all occurrences.
+        -Wno-shift-sign-overflow # FIXME: Why do we need this with clang-cl but not clang?
+        -Wno-double-promotion # FIXME: remove me
+      )
+    endif()
+  elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+    target_add_compile_flags_if_supported(${target} PRIVATE
+      -Wno-literal-suffix
+      -Wno-c++14-compat
+      -Wno-noexcept-type
+      -Wno-suggest-override)
+  endif()
+  if (LIBCXX_ENABLE_WERROR)
+    target_add_compile_flags_if_supported(${target} PRIVATE -Werror)
+    target_add_compile_flags_if_supported(${target} PRIVATE -WX)
+  else()
+    # TODO(EricWF) Remove this. We shouldn't be suppressing errors when -Werror is
+    # added elsewhere.
+    target_add_compile_flags_if_supported(${target} PRIVATE -Wno-error)
+  endif()
+  if (LIBCXX_ENABLE_PEDANTIC)
+    target_add_compile_flags_if_supported(${target} PRIVATE -pedantic)
+  endif()
+  if (LIBCXX_DISABLE_MACRO_CONFLICT_WARNINGS)
+    target_compile_definitions(${target} PRIVATE -D_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS)
+  endif()
+endfunction()
+
+# Exception flags =============================================================
+function(cxx_add_exception_flags target)
+  if (LIBCXX_ENABLE_EXCEPTIONS)
+    # Catches C++ exceptions only and tells the compiler to assume that extern C
+    # functions never throw a C++ exception.
+    target_add_compile_flags_if_supported(${target} PUBLIC -EHsc)
+  else()
+    target_add_compile_flags_if_supported(${target} PUBLIC -EHs- -EHa-)
+    target_add_compile_flags_if_supported(${target} PUBLIC -fno-exceptions)
+  endif()
+endfunction()
+
+# RTTI flags ==================================================================
+function(cxx_add_rtti_flags target)
+  if (NOT LIBCXX_ENABLE_RTTI)
+    target_add_compile_flags_if_supported(${target} PUBLIC -GR-)
+    target_add_compile_flags_if_supported(${target} PUBLIC -fno-rtti)
+  endif()
+endfunction()
+
+# Threading flags =============================================================
+if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY AND LIBCXX_ENABLE_SHARED)
+  # Need to allow unresolved symbols if this is to work with shared library builds
+  if (APPLE)
+    add_link_flags("-undefined dynamic_lookup")
+  else()
+    # Relax this restriction from HandleLLVMOptions
+    string(REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
   endif()
 endif()
 
-macro(append_if list condition var)
-  if (${condition})
-    list(APPEND ${list} ${var})
-  endif()
-endmacro()
-
-# Get warning flags
-if (NOT MSVC)
-  append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WALL_FLAG -Wall)
-  list(APPEND LIBCXX_CXX_REQUIRED_FLAGS -Werror=return-type)
-endif()
-
-append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_W_FLAG -W)
-append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WNO_UNUSED_PARAMETER_FLAG -Wno-unused-parameter)
-append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WWRITE_STRINGS_FLAG -Wwrite-strings)
-append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WNO_LONG_LONG_FLAG -Wno-long-long)
-if (LIBCXX_ENABLE_WERROR)
-  append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WERROR_FLAG -Werror)
-  append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WX_FLAG -WX)
-else()
-  append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WNO_ERROR_FLAG -Wno-error)
-  append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_NO_WX_FLAG -WX-)
-endif()
-if (LIBCXX_ENABLE_PEDANTIC)
-  append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_PEDANTIC_FLAG -pedantic)
-endif()
-
-# Get feature flags.
-# Exceptions
-if (LIBCXX_ENABLE_EXCEPTIONS)
-  # Catches C++ exceptions only and tells the compiler to assume that extern C
-  # functions never throw a C++ exception.
-  append_if(LIBCXX_CXX_FEATURE_FLAGS LIBCXX_HAS_EHSC_FLAG -EHsc)
-else()
-  list(APPEND LIBCXX_CXX_FEATURE_FLAGS -D_LIBCPP_NO_EXCEPTIONS)
-  append_if(LIBCXX_CXX_FEATURE_FLAGS LIBCXX_HAS_NO_EHS_FLAG -EHs-)
-  append_if(LIBCXX_CXX_FEATURE_FLAGS LIBCXX_HAS_NO_EHA_FLAG -EHa-)
-  append_if(LIBCXX_CXX_FEATURE_FLAGS LIBCXX_HAS_FNO_EXCEPTIONS_FLAG -fno-exceptions)
-endif()
-# RTTI
-if (NOT LIBCXX_ENABLE_RTTI)
-  list(APPEND LIBCXX_CXX_FEATURE_FLAGS -D_LIBCPP_NO_RTTI)
-  append_if(LIBCXX_CXX_FEATURE_FLAGS LIBCXX_HAS_NO_GR_FLAG -GR-)
-  append_if(LIBCXX_CXX_FEATURE_FLAGS LIBCXX_HAS_FNO_RTTI_FLAG -fno-rtti)
-endif()
-# Assert
-string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
-if (LIBCXX_ENABLE_ASSERTIONS)
+# Assertion flags =============================================================
+define_if(LIBCXX_ENABLE_ASSERTIONS -UNDEBUG)
+define_if_not(LIBCXX_ENABLE_ASSERTIONS -DNDEBUG)
+define_if(LIBCXX_ENABLE_ASSERTIONS -D_LIBCPP_DEBUG=0)
+define_if(LIBCXX_DEBUG_BUILD -D_DEBUG)
+if (LIBCXX_ENABLE_ASSERTIONS AND NOT LIBCXX_DEBUG_BUILD)
   # MSVC doesn't like _DEBUG on release builds. See PR 4379.
-  if (NOT MSVC)
-    list(APPEND LIBCXX_CXX_FEATURE_FLAGS -D_DEBUG)
-  endif()
-  # On Release builds cmake automatically defines NDEBUG, so we
-  # explicitly undefine it:
-  if (uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE")
-    list(APPEND LIBCXX_CXX_FEATURE_FLAGS -UNDEBUG)
-  endif()
-else()
-  if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE")
-    list(APPEND LIBCXX_CXX_FEATURE_FLAGS -DNDEBUG)
-  endif()
-endif()
-# Static library
-if (NOT LIBCXX_ENABLE_SHARED)
-  list(APPEND LIBCXX_CXX_FEATURE_FLAGS -D_LIBCPP_BUILD_STATIC)
+  define_if_not(LIBCXX_TARGETING_MSVC -D_DEBUG)
 endif()
 
-# This is the _ONLY_ place where add_definitions is called.
-if (MSVC)
-  add_definitions(-D_CRT_SECURE_NO_WARNINGS)
+# Modules flags ===============================================================
+# FIXME The libc++ sources are fundamentally non-modular. They need special
+# versions of the headers in order to provide C++03 and legacy ABI definitions.
+# NOTE: The public headers can be used with modules in all other contexts.
+function(cxx_add_module_flags target)
+  if (LLVM_ENABLE_MODULES)
+    # Ignore that the rest of the modules flags are now unused.
+    target_add_compile_flags_if_supported(${target} PUBLIC -Wno-unused-command-line-argument)
+    target_compile_options(${target} PUBLIC -fno-modules)
+  endif()
+endfunction()
+
+# Sanitizer flags =============================================================
+
+function(get_sanitizer_flags OUT_VAR  USE_SANITIZER)
+  set(SANITIZER_FLAGS)
+  set(USE_SANITIZER "${USE_SANITIZER}")
+  # NOTE: LLVM_USE_SANITIZER checks for a UNIX like system instead of MSVC.
+  # But we don't have LLVM_ON_UNIX so checking for MSVC is the best we can do.
+  if (USE_SANITIZER AND NOT MSVC)
+    append_flags_if_supported(SANITIZER_FLAGS "-fno-omit-frame-pointer")
+    append_flags_if_supported(SANITIZER_FLAGS "-gline-tables-only")
+
+    if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" AND
+            NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
+      append_flags_if_supported(SANITIZER_FLAGS "-gline-tables-only")
+    endif()
+    if (USE_SANITIZER STREQUAL "Address")
+      append_flags(SANITIZER_FLAGS "-fsanitize=address")
+    elseif (USE_SANITIZER MATCHES "Memory(WithOrigins)?")
+      append_flags(SANITIZER_FLAGS -fsanitize=memory)
+      if (USE_SANITIZER STREQUAL "MemoryWithOrigins")
+        append_flags(SANITIZER_FLAGS "-fsanitize-memory-track-origins")
+      endif()
+    elseif (USE_SANITIZER STREQUAL "Undefined")
+      append_flags(SANITIZER_FLAGS "-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all")
+    elseif (USE_SANITIZER STREQUAL "Address;Undefined" OR
+            USE_SANITIZER STREQUAL "Undefined;Address")
+      append_flags(SANITIZER_FLAGS "-fsanitize=address,undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all")
+    elseif (USE_SANITIZER STREQUAL "Thread")
+      append_flags(SANITIZER_FLAGS -fsanitize=thread)
+    elseif (USE_SANITIZER STREQUAL "DataFlow")
+      append_flags(SANITIZER_FLAGS -fsanitize=dataflow)
+    else()
+      message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${USE_SANITIZER}")
+    endif()
+  elseif(USE_SANITIZER AND MSVC)
+    message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.")
+  endif()
+  set(${OUT_VAR} "${SANITIZER_FLAGS}" PARENT_SCOPE)
+endfunction()
+
+# Configure for sanitizers. If LIBCXX_STANDALONE_BUILD then we have to do
+# the flag translation ourselves. Othewise LLVM's CMakeList.txt will handle it.
+if (LIBCXX_STANDALONE_BUILD)
+  set(LLVM_USE_SANITIZER "" CACHE STRING
+      "Define the sanitizer used to build the library and tests")
+endif()
+get_sanitizer_flags(SANITIZER_FLAGS "${LLVM_USE_SANITIZER}")
+if (LIBCXX_STANDALONE_BUILD AND SANITIZER_FLAGS)
+  add_flags(${SANITIZER_FLAGS})
 endif()
 
-string(REPLACE ";" " " LIBCXX_CXX_REQUIRED_FLAGS "${LIBCXX_CXX_REQUIRED_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBCXX_CXX_REQUIRED_FLAGS}")
+# Link system libraries =======================================================
+function(cxx_link_system_libraries target)
 
-string(REPLACE ";" " " LIBCXX_CXX_WARNING_FLAGS "${LIBCXX_CXX_WARNING_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBCXX_CXX_WARNING_FLAGS}")
+# In order to remove just libc++ from the link step
+# we need to use -nostdlib++ whenever it is supported.
+# Unfortunately this cannot be used universally because for example g++ supports
+# only -nodefaultlibs in which case all libraries will be removed and
+# all libraries but c++ have to be added in manually.
+  if (LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG)
+    target_add_link_flags_if_supported(${target} PRIVATE "-nostdlib++")
+  else()
+    target_add_link_flags_if_supported(${target} PRIVATE "-nodefaultlibs")
+    target_add_compile_flags_if_supported(${target} PRIVATE "/Zl")
+    target_add_link_flags_if_supported(${target} PRIVATE "/nodefaultlib")
+  endif()
 
-string(REPLACE ";" " " LIBCXX_CXX_FEATURE_FLAGS "${LIBCXX_CXX_FEATURE_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBCXX_CXX_FEATURE_FLAGS}")
+  if (LIBCXX_HAS_SYSTEM_LIB)
+    target_link_libraries(${target} PRIVATE System)
+  endif()
+
+  if (LIBCXX_HAS_PTHREAD_LIB)
+    target_link_libraries(${target} PRIVATE pthread)
+  endif()
+
+  if (LIBCXX_HAS_C_LIB)
+    target_link_libraries(${target} PRIVATE c)
+  endif()
+
+  if (LIBCXX_HAS_M_LIB)
+    target_link_libraries(${target} PRIVATE m)
+  endif()
+
+  if (LIBCXX_HAS_RT_LIB)
+    target_link_libraries(${target} PRIVATE rt)
+  endif()
+
+  if (LIBCXX_USE_COMPILER_RT)
+    find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY)
+    if (LIBCXX_BUILTINS_LIBRARY)
+      target_link_libraries(${target} PRIVATE "${LIBCXX_BUILTINS_LIBRARY}")
+    endif()
+  elseif (LIBCXX_HAS_GCC_LIB)
+    target_link_libraries(${target} PRIVATE gcc)
+  elseif (LIBCXX_HAS_GCC_S_LIB)
+    target_link_libraries(${target} PRIVATE gcc_s)
+  endif()
+
+  if (LIBCXX_HAS_ATOMIC_LIB)
+    target_link_libraries(${target} PRIVATE atomic)
+  endif()
+
+  if (MINGW)
+    target_link_libraries(${target} PRIVATE "${MINGW_LIBRARIES}")
+  endif()
+
+  if (LIBCXX_TARGETING_MSVC)
+    if (LIBCXX_DEBUG_BUILD)
+      set(LIB_SUFFIX "d")
+    else()
+      set(LIB_SUFFIX "")
+    endif()
+
+    target_link_libraries(${target} PRIVATE ucrt${LIB_SUFFIX}) # Universal C runtime
+    target_link_libraries(${target} PRIVATE vcruntime${LIB_SUFFIX}) # C++ runtime
+    target_link_libraries(${target} PRIVATE msvcrt${LIB_SUFFIX}) # C runtime startup files
+    target_link_libraries(${target} PRIVATE msvcprt${LIB_SUFFIX}) # C++ standard library. Required for exception_ptr internals.
+    # Required for standards-complaint wide character formatting functions
+    # (e.g. `printfw`/`scanfw`)
+    target_link_libraries(${target} PRIVATE iso_stdio_wide_specifiers)
+  endif()
+
+  if (ANDROID AND ANDROID_PLATFORM_LEVEL LESS 21)
+    target_link_libraries(${target} PUBLIC android_support)
+  endif()
+endfunction()
+
+# Windows-related flags =======================================================
+function(cxx_add_windows_flags target)
+  if(WIN32 AND NOT MINGW)
+    target_compile_definitions(${target} PRIVATE
+                                 # Ignore the -MSC_VER mismatch, as we may build
+                                 # with a different compatibility version.
+                                 _ALLOW_MSC_VER_MISMATCH
+                                 # Don't check the msvcprt iterator debug levels
+                                 # as we will define the iterator types; libc++
+                                 # uses a different macro to identify the debug
+                                 # level.
+                                 _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH
+                                 # We are building the c++ runtime, don't pull in
+                                 # msvcprt.
+                                 _CRTBLD
+                                 # Don't warn on the use of "deprecated"
+                                 # "insecure" functions which are standards
+                                 # specified.
+                                 _CRT_SECURE_NO_WARNINGS
+                                 # Use the ISO conforming behaviour for conversion
+                                 # in printf, scanf.
+                                 _CRT_STDIO_ISO_WIDE_SPECIFIERS)
+  endif()
+endfunction()
+
+# Configuration file flags =====================================================
+if (NOT LIBCXX_ABI_VERSION EQUAL 1)
+  config_define(${LIBCXX_ABI_VERSION} _LIBCPP_ABI_VERSION)
+endif()
+if (NOT LIBCXX_ABI_NAMESPACE STREQUAL "")
+  if (NOT LIBCXX_ABI_NAMESPACE MATCHES "__.*")
+    message(FATAL_ERROR "LIBCXX_ABI_NAMESPACE must be a reserved identifier.")
+  endif()
+  if (LIBCXX_ABI_NAMESPACE MATCHES "__[0-9]+$")
+    message(FATAL_ERROR "LIBCXX_ABI_NAMESPACE '${LIBCXX_ABI_NAMESPACE}' is reserved for use by libc++.")
+  endif()
+  config_define(${LIBCXX_ABI_NAMESPACE} _LIBCPP_ABI_NAMESPACE)
+endif()
+config_define_if(LIBCXX_ABI_UNSTABLE _LIBCPP_ABI_UNSTABLE)
+config_define_if(LIBCXX_ABI_FORCE_ITANIUM _LIBCPP_ABI_FORCE_ITANIUM)
+config_define_if(LIBCXX_ABI_FORCE_MICROSOFT _LIBCPP_ABI_FORCE_MICROSOFT)
+config_define_if(LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT)
+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)
+if (NOT LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION STREQUAL "default")
+  config_define("${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}" _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION)
+endif()
+config_define_if(LIBCXX_HAS_PTHREAD_API _LIBCPP_HAS_THREAD_API_PTHREAD)
+config_define_if(LIBCXX_HAS_EXTERNAL_THREAD_API _LIBCPP_HAS_THREAD_API_EXTERNAL)
+config_define_if(LIBCXX_HAS_WIN32_THREAD_API _LIBCPP_HAS_THREAD_API_WIN32)
+config_define_if(LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL)
+config_define_if(LIBCXX_HAS_MUSL_LIBC _LIBCPP_HAS_MUSL_LIBC)
+config_define_if(LIBCXX_NO_VCRUNTIME _LIBCPP_NO_VCRUNTIME)
+config_define_if(LIBCXX_ENABLE_PARALLEL_ALGORITHMS _LIBCPP_HAS_PARALLEL_ALGORITHMS)
+config_define_if_not(LIBCXX_ENABLE_FILESYSTEM _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
+config_define_if_not(LIBCXX_ENABLE_RANDOM_DEVICE _LIBCPP_HAS_NO_RANDOM_DEVICE)
+config_define_if_not(LIBCXX_ENABLE_LOCALIZATION _LIBCPP_HAS_NO_LOCALIZATION)
+config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
+# Incomplete features get their own specific disabling flags. This makes it
+# easier to grep for target specific flags once the feature is complete.
+config_define_if_not(LIBCXX_ENABLE_INCOMPLETE_FEATURES _LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
+config_define_if_not(LIBCXX_ENABLE_INCOMPLETE_FEATURES _LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+if (LIBCXX_ABI_DEFINES)
+  set(abi_defines)
+  foreach (abi_define ${LIBCXX_ABI_DEFINES})
+    if (NOT abi_define MATCHES "^_LIBCPP_ABI_")
+      message(SEND_ERROR "Invalid ABI macro ${abi_define} in LIBCXX_ABI_DEFINES")
+    endif()
+    list(APPEND abi_defines "#define ${abi_define}")
+  endforeach()
+  string(REPLACE ";" "\n" abi_defines "${abi_defines}")
+  config_define(${abi_defines} _LIBCPP_ABI_DEFINES)
+endif()
+
+# By default libc++ on Windows expects to use a shared library, which requires
+# the headers to use DLL import/export semantics. However when building a
+# static library only we modify the headers to disable DLL import/export.
+if (DEFINED WIN32 AND LIBCXX_ENABLE_STATIC AND NOT LIBCXX_ENABLE_SHARED)
+  message(STATUS "Generating custom __config for non-DLL Windows build")
+  config_define(ON _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+endif()
+
+if (WIN32 AND LIBCXX_ENABLE_STATIC_ABI_LIBRARY)
+  # If linking libcxxabi statically into libcxx, skip the dllimport attributes
+  # on symbols we refer to from libcxxabi.
+  add_definitions(-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS)
+endif()
+
+# Setup all common build flags =================================================
+function(cxx_add_common_build_flags target)
+  cxx_add_basic_build_flags(${target})
+  cxx_add_warning_flags(${target})
+  cxx_add_windows_flags(${target})
+  cxx_add_exception_flags(${target})
+  cxx_add_rtti_flags(${target})
+  cxx_add_module_flags(${target})
+  cxx_link_system_libraries(${target})
+endfunction()
 
 #===============================================================================
-# Setup Source Code
+# Setup Source Code And Tests
 #===============================================================================
-
-include_directories(include)
 add_subdirectory(include)
+add_subdirectory(src)
+add_subdirectory(utils)
 
-# Add source code. This also contains all of the logic for deciding linker flags
-# soname, etc...
-add_subdirectory(lib)
+set(LIBCXX_TEST_DEPS "")
 
-#===============================================================================
-# Setup Tests
-#===============================================================================
+if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
+  list(APPEND LIBCXX_TEST_DEPS cxx_experimental)
+endif()
 
-add_subdirectory(test)
+if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
+  list(APPEND LIBCXX_TEST_DEPS cxx_external_threads)
+endif()
+
+if (LIBCXX_INCLUDE_BENCHMARKS)
+  add_subdirectory(benchmarks)
+endif()
+
+if (LIBCXX_INCLUDE_TESTS)
+  add_subdirectory(test)
+  add_subdirectory(lib/abi)
+  if (LIBCXX_STANDALONE_BUILD)
+    include(AddLLVM) # for get_llvm_lit_path
+    # Make sure the llvm-lit script is generated into the bin directory, and
+    # do it after adding all tests, since the generated script will only work
+    # correctly discovered tests against test locations from the source tree
+    # that have already been discovered.
+    add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/llvm-lit
+                     ${CMAKE_CURRENT_BINARY_DIR}/llvm-lit)
+  endif()
+endif()
+
+if (LIBCXX_INCLUDE_DOCS)
+  add_subdirectory(docs)
+endif()
diff --git a/CREDITS.TXT b/CREDITS.TXT
index 368b526..49f095d 100644
--- a/CREDITS.TXT
+++ b/CREDITS.TXT
@@ -12,6 +12,10 @@
 E: compnerd@compnerd.org
 D: Minor patches and Linux fixes.
 
+N: Dan Albert
+E: danalbert@google.com
+D: Android support and test runner improvements.
+
 N: Dimitry Andric
 E: dimitry@andric.com
 D: Visibility fixes, minor FreeBSD portability patches.
@@ -33,6 +37,23 @@
 E: marshall@idio.com
 D: C++14 support, patches and bug fixes.
 
+N: Jonathan B Coe
+E: jbcoe@me.com
+D: Implementation of propagate_const.
+
+N: Christopher Di Bella
+E: cjdb@google.com
+E: cjdb.ns@gmail.com
+D: Library concepts.
+
+N: Glen Joseph Fernandes
+E: glenjofe@gmail.com
+D: Implementation of to_address.
+
+N: Eric Fiselier
+E: eric@efcs.ca
+D: LFTS support, patches and bug fixes.
+
 N: Bill Fisher
 E: william.w.fisher@gmail.com
 D: Regex bug fixes.
@@ -48,6 +69,10 @@
 E: hhinnant@apple.com
 D: Architect and primary author of libc++
 
+N: Sergej Jaskiewicz
+E: jaskiewiczs@icloud.com
+D: Minor improvements in the testing infrastructure
+
 N: Hyeon-bin Jeong
 E: tuhertz@gmail.com
 D: Minor patches and bug fixes.
@@ -68,6 +93,10 @@
 E: andrew.c.morrow@gmail.com
 D: Minor patches and Linux fixes.
 
+N: Michael Park
+E: mcypark@gmail.com
+D: Implementation of <variant>.
+
 N: Arvid Picciani
 E: aep at exys dot org
 D: Minor patches and musl port.
@@ -80,6 +109,10 @@
 E: nico.rieck@gmail.com
 D: Windows fixes
 
+N: Jon Roelofs
+E: jroelofS@jroelofs.com
+D: Remote testing, Newlib port, baremetal/single-threaded support.
+
 N: Jonathan Sauer
 D: Minor patches, mostly related to constexpr
 
@@ -101,6 +134,9 @@
 N: Michael van der Westhuizen
 E: r1mikey at gmail dot com
 
+N: Larisse Voufo
+D: Minor patches.
+
 N: Klaas de Vries
 E: klaas at klaasgaaf dot nl
 D: Minor bug fix.
diff --git a/LICENSE.TXT b/LICENSE.TXT
index 41ca5d1..e159d28 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -1,5 +1,240 @@
 ==============================================================================
-libc++ License
+The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
+==============================================================================
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+    1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+    2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+    3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+    4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+    5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+    6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+    7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+    8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+    9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+    END OF TERMS AND CONDITIONS
+
+    APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+    Copyright [yyyy] [name of copyright owner]
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+
+---- LLVM Exceptions to the Apache 2.0 License ----
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+
+==============================================================================
+Software from third parties included in the LLVM Project:
+==============================================================================
+The LLVM Project contains third party software which is under different license
+terms. All such code will be identified clearly using at least one of two
+mechanisms:
+1) It will be in a separate directory tree with its own `LICENSE.txt` or
+   `LICENSE` file at the top containing the specific license and restrictions
+   which apply to that software, or
+2) It will contain specific license and restriction terms at the top of every
+   file.
+
+==============================================================================
+Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
 ==============================================================================
 
 The libc++ library is dual licensed under both the University of Illinois
@@ -14,7 +249,7 @@
 University of Illinois/NCSA
 Open Source License
 
-Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
+Copyright (c) 2009-2019 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
new file mode 100644
index 0000000..cf489d2
--- /dev/null
+++ b/TODO.TXT
@@ -0,0 +1,75 @@
+This is meant to be a general place to list things that should be done "someday"
+
+CXX Runtime Library Tasks
+=========================
+* Look into mirroring libsupc++'s typeinfo vtable layout when libsupc++/libstdc++
+  is used as the runtime library.
+* Investigate and document interoperability between libc++ and libstdc++ on
+  linux. Do this for every supported c++ runtime library.
+
+Atomic Related Tasks
+====================
+* future should use <atomic> for synchronization.
+
+Test Suite Tasks
+================
+* Improve the quality and portability of the locale test data.
+* Convert failure tests to use Clang Verify.
+
+Filesystem Tasks
+================
+* P0492r2 - Implement National body comments for Filesystem
+    * INCOMPLETE - US 25: has_filename() is equivalent to just !empty()
+    * INCOMPLETE - US 31: Everything is defined in terms of one implicit host system
+    * INCOMPLETE - US 32: Meaning of 27.10.2.1 unclear
+    * INCOMPLETE - US 33: Definition of canonical path problematic
+    * INCOMPLETE - US 34: Are there attributes of a file that are not an aspect of the file system?
+    * INCOMPLETE - US 35: What synchronization is required to avoid a file system race?
+    * INCOMPLETE - US 36: Symbolic links themselves are attached to a directory via (hard) links
+    * INCOMPLETE - US 37: The term “redundant current directory (dot) elements” is not defined
+    * INCOMPLETE - US 38: Duplicates §17.3.16
+    * INCOMPLETE - US 39: Remove note: Dot and dot-dot are not directories
+    * INCOMPLETE - US 40: Not all directories have a parent.
+    * INCOMPLETE - US 41: The term “parent directory” for a (non-directory) file is unusual
+    * INCOMPLETE - US 42: Pathname resolution does not always resolve a symlink
+    * INCOMPLETE - US 43: Concerns about encoded character types
+    * INCOMPLETE - US 44: Definition of path in terms of a string requires leaky abstraction
+    * INCOMPLETE - US 45: Generic format portability compromised by unspecified root-name
+    * INCOMPLETE - US 46: filename can be empty so productions for relative-path are redundant
+    * INCOMPLETE - US 47: “.” and “..” already match the name production
+    * INCOMPLETE - US 48: Multiple separators are often meaningful in a root-name
+    * INCOMPLETE - US 49: What does “method of conversion method” mean?
+    * INCOMPLETE - US 50: 27.10.8.1 ¶ 1.4 largely redundant with ¶ 1.3
+    * INCOMPLETE - US 51: Failing to add / when appending empty string prevents useful apps
+    * INCOMPLETE - US 52: remove_filename() postcondition is not by itself a definition
+    * INCOMPLETE - US 53: remove_filename()'s name does not correspond to its behavior
+    * INCOMPLETE - US 54: remove_filename() is broken
+    * INCOMPLETE - US 55: replace_extension()'s use of path as parameter is inappropriate
+    * INCOMPLETE - US 56: Remove replace_extension()'s conditional addition of period
+    * INCOMPLETE - US 57: On Windows, absolute paths will sort in among relative paths
+    * INCOMPLETE - US 58: parent_path() behavior for root paths is useless
+    * INCOMPLETE - US 59: filename() returning path for single path components is bizarre
+    * INCOMPLETE - US 60: path("/foo/").filename()==path(".") is surprising
+    * INCOMPLETE - US 61: Leading dots in filename() should not begin an extension
+    * INCOMPLETE - US 62: It is important that stem()+extension()==filename()
+    * INCOMPLETE - US 63: lexically_normal() inconsistently treats trailing "/" but not "/.." as directory
+    * INCOMPLETE - US 73, CA 2: root-name is effectively implementation defined
+    * INCOMPLETE - US 74, CA 3: The term “pathname” is ambiguous in some contexts
+    * INCOMPLETE - US 75, CA 4: Extra flag in path constructors is needed
+    * INCOMPLETE - US 76, CA 5: root-name definition is over-specified.
+    * INCOMPLETE - US 77, CA 6: operator/ and other appends not useful if arg has root-name
+    * INCOMPLETE - US 78, CA 7: Member absolute() in 27.10.4.1 is overspecified for non-POSIX-like O/S
+    * INCOMPLETE - US 79, CA 8: Some operation functions are overspecified for implementation-defined file types
+    * INCOMPLETE - US 185: Fold error_code and non-error_code signatures into one signature
+    * INCOMPLETE - FI 14: directory_entry comparisons are members
+    * INCOMPLETE - Late 36: permissions() error_code overload should be noexcept
+    * INCOMPLETE - Late 37: permissions() actions should be separate parameter
+    * INCOMPLETE - Late 42: resize_file() Postcondition missing argument
+
+Misc Tasks
+==========
+* Find all sequences of >2 underscores and eradicate them.
+* run clang-tidy on libc++
+* Document the "conditionally-supported" bits of libc++
+* Look at basic_string's move assignment operator, re LWG 2063 and POCMA
+* Put a static_assert in std::allocator to deny const/volatile types (LWG 2447)
diff --git a/appveyor-reqs-install.cmd b/appveyor-reqs-install.cmd
new file mode 100644
index 0000000..e3bd018
--- /dev/null
+++ b/appveyor-reqs-install.cmd
@@ -0,0 +1,53 @@
+@echo on
+
+if NOT EXIST C:\projects\deps (
+  mkdir C:\projects\deps
+)
+cd C:\projects\deps
+
+::###########################################################################
+:: Setup Compiler
+::###########################################################################
+if NOT EXIST llvm-installer.exe (
+  appveyor DownloadFile https://prereleases.llvm.org/win-snapshots/LLVM-9.0.0-r357435-win32.exe -FileName llvm-installer.exe
+)
+if "%CLANG_VERSION%"=="ToT" (
+    START /WAIT llvm-installer.exe /S /D=C:\"Program Files\LLVM"
+)
+if DEFINED CLANG_VERSION  @set PATH="C:\Program Files\LLVM\bin";%PATH%
+if DEFINED CLANG_VERSION  clang-cl -v
+
+if DEFINED MINGW_PATH rename "C:\Program Files\Git\usr\bin\sh.exe" "sh-ignored.exe"
+if DEFINED MINGW_PATH @set "PATH=%PATH:C:\Program Files (x86)\Git\bin=%"
+if DEFINED MINGW_PATH @set "PATH=%PATH%;%MINGW_PATH%"
+if DEFINED MINGW_PATH g++ -v
+
+::###########################################################################
+:: Install a recent CMake
+::###########################################################################
+if NOT EXIST cmake (
+  appveyor DownloadFile https://cmake.org/files/v3.7/cmake-3.7.2-win64-x64.zip -FileName cmake.zip
+  7z x cmake.zip -oC:\projects\deps > nul
+  move C:\projects\deps\cmake-* C:\projects\deps\cmake
+  rm cmake.zip
+)
+@set PATH=C:\projects\deps\cmake\bin;%PATH%
+cmake --version
+
+::###########################################################################
+:: Install Ninja
+::###########################################################################
+if NOT EXIST ninja (
+  appveyor DownloadFile https://github.com/ninja-build/ninja/releases/download/v1.6.0/ninja-win.zip -FileName ninja.zip
+  7z x ninja.zip -oC:\projects\deps\ninja > nul
+  rm ninja.zip
+)
+@set PATH=C:\projects\deps\ninja;%PATH%
+ninja --version
+
+::###########################################################################
+:: Setup the cached copy of LLVM
+::###########################################################################
+git clone --depth=1 http://llvm.org/git/llvm.git
+
+@echo off
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..ae7c7ad
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,71 @@
+version: '{build}'
+
+shallow_clone: true
+
+build:
+  verbosity: detailed
+
+configuration:
+  - Debug
+
+environment:
+  matrix:
+    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+      CMAKE_OPTIONS: -DCMAKE_C_COMPILER=clang-cl.exe -DCMAKE_CXX_COMPILER=clang-cl.exe
+      CLANG_VERSION: ToT
+      MSVC_SETUP_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat
+      MSVC_SETUP_ARG: x86
+      GENERATOR: Ninja
+      MAKE_PROGRAM: ninja
+      APPVEYOR_SAVE_CACHE_ON_ERROR: true
+# TODO: Maybe re-enable this configuration? Do we want to support MSVC 2015's runtime?
+#    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+#      MINGW_PATH: C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin
+#      GENERATOR: MinGW Makefiles
+#      MAKE_PROGRAM: mingw32-make
+#      APPVEYOR_SAVE_CACHE_ON_ERROR: true
+
+install:
+  ############################################################################
+  # All external dependencies are installed in C:\projects\deps
+  ############################################################################
+  - call "%APPVEYOR_BUILD_FOLDER%\\appveyor-reqs-install.cmd"
+
+before_build:
+  - if DEFINED MSVC_SETUP_PATH call "%MSVC_SETUP_PATH%" %MSVC_SETUP_ARG%
+  - cd %APPVEYOR_BUILD_FOLDER%
+
+build_script:
+  - md C:\projects\build-libcxx
+  - cd C:\projects\build-libcxx
+  - echo %configuration%
+
+  #############################################################################
+  # Configuration Step
+  #############################################################################
+  - cmake -G "%GENERATOR%" %CMAKE_OPTIONS%
+    "-DCMAKE_BUILD_TYPE=%configuration%"
+    "-DLLVM_PATH=C:\projects\deps\llvm" -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF
+    -DLLVM_LIT_ARGS="-sv --show-xfail --show-unsupported"
+    %APPVEYOR_BUILD_FOLDER%
+
+  #############################################################################
+  # Build Step
+  #############################################################################
+  - "%MAKE_PROGRAM%"
+
+test_script:
+  - "%MAKE_PROGRAM% check-cxx"
+
+on_failure:
+  - appveyor PushArtifact CMakeFiles/CMakeOutput.log
+  - appveyor PushArtifact CMakeFiles/CMakeError.log
+
+artifacts:
+  - path: '_build/CMakeFiles/*.log'
+    name: logs
+
+cache:
+ - C:\projects\deps\ninja
+ - C:\projects\deps\cmake
+ - C:\projects\deps\llvm-installer.exe
diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt
new file mode 100644
index 0000000..c4b8247
--- /dev/null
+++ b/benchmarks/CMakeLists.txt
@@ -0,0 +1,218 @@
+include(ExternalProject)
+include(CheckCXXCompilerFlag)
+
+#==============================================================================
+# Build Google Benchmark for libc++
+#==============================================================================
+
+set(CMAKE_FOLDER "${CMAKE_FOLDER}/Benchmarks")
+
+set(BENCHMARK_LIBCXX_COMPILE_FLAGS
+    -Wno-unused-command-line-argument
+    -nostdinc++
+    -isystem "${LIBCXX_GENERATED_INCLUDE_DIR}"
+    -L${LIBCXX_LIBRARY_DIR}
+    -Wl,-rpath,${LIBCXX_LIBRARY_DIR}
+    ${SANITIZER_FLAGS}
+    )
+if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
+  list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS
+    -isystem "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}")
+endif()
+if (DEFINED LIBCXX_CXX_ABI_LIBRARY_PATH)
+  list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS
+          -L${LIBCXX_CXX_ABI_LIBRARY_PATH}
+          -Wl,-rpath,${LIBCXX_CXX_ABI_LIBRARY_PATH})
+endif()
+split_list(BENCHMARK_LIBCXX_COMPILE_FLAGS)
+
+ExternalProject_Add(google-benchmark-libcxx
+        EXCLUDE_FROM_ALL ON
+        DEPENDS cxx cxx-headers
+        PREFIX benchmark-libcxx
+        SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark
+        INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx
+        CMAKE_CACHE_ARGS
+          -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
+          -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
+          -DCMAKE_BUILD_TYPE:STRING=RELEASE
+          -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+          -DCMAKE_CXX_FLAGS:STRING=${BENCHMARK_LIBCXX_COMPILE_FLAGS}
+          -DBENCHMARK_USE_LIBCXX:BOOL=ON
+          -DBENCHMARK_ENABLE_TESTING:BOOL=OFF)
+
+#==============================================================================
+# Build Google Benchmark for the native stdlib
+#==============================================================================
+set(BENCHMARK_NATIVE_TARGET_FLAGS)
+if (LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN)
+  set(BENCHMARK_NATIVE_TARGET_FLAGS
+      -gcc-toolchain ${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN})
+endif()
+split_list(BENCHMARK_NATIVE_TARGET_FLAGS)
+
+if (LIBCXX_BENCHMARK_NATIVE_STDLIB)
+  ExternalProject_Add(google-benchmark-native
+        EXCLUDE_FROM_ALL ON
+        PREFIX benchmark-native
+        SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark
+        INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native
+        CMAKE_CACHE_ARGS
+          -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
+          -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
+          -DCMAKE_CXX_FLAGS:STRING=${BENCHMARK_NATIVE_TARGET_FLAGS}
+          -DCMAKE_BUILD_TYPE:STRING=RELEASE
+          -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+          -DBENCHMARK_ENABLE_TESTING:BOOL=OFF)
+endif()
+
+
+#==============================================================================
+# Benchmark tests configuration
+#==============================================================================
+add_custom_target(cxx-benchmarks)
+set(BENCHMARK_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
+set(BENCHMARK_LIBCXX_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx)
+set(BENCHMARK_NATIVE_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native)
+
+
+set(BENCHMARK_TEST_COMPILE_FLAGS
+    -O2
+    -fsized-deallocation
+    -I${BENCHMARK_LIBCXX_INSTALL}/include
+    -I${LIBCXX_SOURCE_DIR}/test/support
+)
+set(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS
+    ${BENCHMARK_TEST_COMPILE_FLAGS}
+    ${SANITIZER_FLAGS}
+    -Wno-user-defined-literals
+    -Wno-suggest-override
+)
+
+set(BENCHMARK_TEST_LIBCXX_LINK_FLAGS
+    -nodefaultlibs
+    -L${BENCHMARK_LIBCXX_INSTALL}/lib/
+    ${SANITIZER_FLAGS}
+)
+set(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS
+  ${BENCHMARK_NATIVE_TARGET_FLAGS}
+  ${BENCHMARK_TEST_COMPILE_FLAGS}
+)
+set(BENCHMARK_TEST_NATIVE_LINK_FLAGS
+    ${BENCHMARK_NATIVE_TARGET_FLAGS}
+    -L${BENCHMARK_NATIVE_INSTALL}/lib
+)
+split_list(BENCHMARK_TEST_COMPILE_FLAGS)
+split_list(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS)
+split_list(BENCHMARK_TEST_LIBCXX_LINK_FLAGS)
+split_list(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS)
+split_list(BENCHMARK_TEST_NATIVE_LINK_FLAGS)
+
+if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++")
+  find_library(LIBSTDCXX_FILESYSTEM_TEST stdc++fs
+        PATHS ${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN}
+        PATH_SUFFIXES lib lib64
+        DOC "The libstdc++ filesystem library used by the benchmarks"
+    )
+    if (NOT "${LIBSTDCXX_FILESYSTEM_TEST}" STREQUAL "LIBSTDCXX_FILESYSTEM_TEST-NOTFOUND")
+      set(LIBSTDCXX_FILESYSTEM_LIB "stdc++fs")
+    endif()
+endif()
+
+set(libcxx_benchmark_targets)
+
+function(add_benchmark_test name source_file)
+  set(libcxx_target ${name}_libcxx)
+  list(APPEND libcxx_benchmark_targets ${libcxx_target})
+  add_executable(${libcxx_target} EXCLUDE_FROM_ALL ${source_file})
+  add_dependencies(${libcxx_target} cxx google-benchmark-libcxx)
+  add_dependencies(cxx-benchmarks ${libcxx_target})
+  if (LIBCXX_ENABLE_SHARED)
+    target_link_libraries(${libcxx_target} PRIVATE cxx_shared)
+  else()
+    target_link_libraries(${libcxx_target} PRIVATE cxx_static)
+  endif()
+  if (TARGET cxx_experimental)
+    target_link_libraries(${libcxx_target} PRIVATE cxx_experimental)
+  endif()
+  target_link_libraries(${libcxx_target} PRIVATE -lbenchmark)
+  if (LLVM_USE_SANITIZER)
+    target_link_libraries(${libcxx_target} PRIVATE -ldl)
+  endif()
+  set_target_properties(${libcxx_target}
+    PROPERTIES
+          OUTPUT_NAME "${name}.libcxx.out"
+          RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}"
+          COMPILE_FLAGS "${BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS}"
+          LINK_FLAGS "${BENCHMARK_TEST_LIBCXX_LINK_FLAGS}"
+          CXX_STANDARD 17
+          CXX_STANDARD_REQUIRED YES
+          CXX_EXTENSIONS NO)
+  cxx_link_system_libraries(${libcxx_target})
+  if (LIBCXX_BENCHMARK_NATIVE_STDLIB)
+    if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++" AND NOT DEFINED LIBSTDCXX_FILESYSTEM_LIB
+        AND "${name}" STREQUAL "filesystem")
+      return()
+    endif()
+    set(native_target ${name}_native)
+    add_executable(${native_target} EXCLUDE_FROM_ALL ${source_file})
+    add_dependencies(${native_target} google-benchmark-native
+                                      google-benchmark-libcxx)
+    target_link_libraries(${native_target} PRIVATE -lbenchmark)
+    if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++")
+      target_link_libraries(${native_target} PRIVATE ${LIBSTDCXX_FILESYSTEM_LIB})
+    elseif (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libc++")
+      target_link_libraries(${native_target} PRIVATE -lc++fs -lc++experimental)
+    endif()
+    if (LIBCXX_HAS_PTHREAD_LIB)
+      target_link_libraries(${native_target} PRIVATE -pthread)
+    endif()
+    add_dependencies(cxx-benchmarks ${native_target})
+    set_target_properties(${native_target}
+      PROPERTIES
+          OUTPUT_NAME "${name}.native.out"
+          RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}"
+          INCLUDE_DIRECTORIES ""
+          COMPILE_FLAGS "${BENCHMARK_TEST_NATIVE_COMPILE_FLAGS}"
+          LINK_FLAGS "${BENCHMARK_TEST_NATIVE_LINK_FLAGS}"
+          CXX_STANDARD 17
+          CXX_STANDARD_REQUIRED YES
+          CXX_EXTENSIONS NO)
+  endif()
+endfunction()
+
+
+#==============================================================================
+# Register Benchmark tests
+#==============================================================================
+file(GLOB BENCHMARK_TESTS "*.bench.cpp")
+foreach(test_path ${BENCHMARK_TESTS})
+  get_filename_component(test_file "${test_path}" NAME)
+  string(REPLACE ".bench.cpp" "" test_name "${test_file}")
+  if (NOT DEFINED ${test_name}_REPORTED)
+    message(STATUS "Adding Benchmark: ${test_file}")
+    # Only report the adding of the benchmark once.
+    set(${test_name}_REPORTED ON CACHE INTERNAL "")
+  endif()
+  add_benchmark_test(${test_name} ${test_file})
+endforeach()
+
+if (LIBCXX_INCLUDE_TESTS)
+  include(AddLLVM)
+
+  if (NOT DEFINED LIBCXX_TEST_DEPS)
+    message(FATAL_ERROR "Expected LIBCXX_TEST_DEPS to be defined")
+  endif()
+
+  configure_lit_site_cfg(
+          ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+          ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py)
+
+  set(BENCHMARK_LIT_ARGS "--show-all --show-xfail --show-unsupported ${LIT_ARGS_DEFAULT}")
+
+  add_lit_target(check-cxx-benchmarks
+          "Running libcxx benchmarks tests"
+          ${CMAKE_CURRENT_BINARY_DIR}
+          DEPENDS cxx-benchmarks ${LIBCXX_TEST_DEPS}
+          ARGS ${BENCHMARK_LIT_ARGS})
+endif()
diff --git a/benchmarks/CartesianBenchmarks.h b/benchmarks/CartesianBenchmarks.h
new file mode 100644
index 0000000..2eea156
--- /dev/null
+++ b/benchmarks/CartesianBenchmarks.h
@@ -0,0 +1,133 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <vector>
+
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
+
+namespace internal {
+
+template <class D, class E, size_t I>
+struct EnumValue : std::integral_constant<E, static_cast<E>(I)> {
+  static std::string name() { return std::string("_") + D::Names[I]; }
+};
+
+template <class D, class E, size_t ...Idxs>
+constexpr auto makeEnumValueTuple(std::index_sequence<Idxs...>) {
+  return std::make_tuple(EnumValue<D, E, Idxs>{}...);
+}
+
+template <class B>
+static auto skip(const B& Bench, int) -> decltype(Bench.skip()) {
+  return Bench.skip();
+}
+template <class B>
+static auto skip(const B& Bench, char) {
+  return false;
+}
+
+template <class B, class Args, size_t... Is>
+void makeBenchmarkFromValuesImpl(const Args& A, std::index_sequence<Is...>) {
+  for (auto& V : A) {
+    B Bench{std::get<Is>(V)...};
+    if (!internal::skip(Bench, 0)) {
+      benchmark::RegisterBenchmark(Bench.name().c_str(),
+                                   [=](benchmark::State& S) { Bench.run(S); });
+    }
+  }
+}
+
+template <class B, class... Args>
+void makeBenchmarkFromValues(const std::vector<std::tuple<Args...> >& A) {
+  makeBenchmarkFromValuesImpl<B>(A, std::index_sequence_for<Args...>());
+}
+
+template <template <class...> class B, class Args, class... U>
+void makeBenchmarkImpl(const Args& A, std::tuple<U...> t) {
+  makeBenchmarkFromValues<B<U...> >(A);
+}
+
+template <template <class...> class B, class Args, class... U,
+          class... T, class... Tuples>
+void makeBenchmarkImpl(const Args& A, std::tuple<U...>, std::tuple<T...>,
+                       Tuples... rest) {
+  (internal::makeBenchmarkImpl<B>(A, std::tuple<U..., T>(), rest...), ...);
+}
+
+template <class R, class T>
+void allValueCombinations(R& Result, const T& Final) {
+  return Result.push_back(Final);
+}
+
+template <class R, class T, class V, class... Vs>
+void allValueCombinations(R& Result, const T& Prev, const V& Value,
+                          const Vs&... Values) {
+  for (const auto& E : Value) {
+    allValueCombinations(Result, std::tuple_cat(Prev, std::make_tuple(E)),
+                         Values...);
+  }
+}
+
+}  // namespace internal
+
+// CRTP class that enables using enum types as a dimension for
+// makeCartesianProductBenchmark below.
+// The type passed to `B` will be a std::integral_constant<E, e>, with the
+// additional static function `name()` that returns the stringified name of the
+// label.
+//
+// Eg:
+// enum class MyEnum { A, B };
+// struct AllMyEnum : EnumValuesAsTuple<AllMyEnum, MyEnum, 2> {
+//   static constexpr absl::string_view Names[] = {"A", "B"};
+// };
+template <class Derived, class EnumType, size_t NumLabels>
+using EnumValuesAsTuple =
+    decltype(internal::makeEnumValueTuple<Derived, EnumType>(
+        std::make_index_sequence<NumLabels>{}));
+
+// Instantiates B<T0, T1, ..., TN> where <Ti...> are the combinations in the
+// cartesian product of `Tuples...`, and pass (arg0, ..., argN) as constructor
+// arguments where `(argi...)` are the combination in the cartesian product of
+// the runtime values of `A...`.
+// B<T...> requires:
+//  - std::string name(args...): The name of the benchmark.
+//  - void run(benchmark::State&, args...): The body of the benchmark.
+// It can also optionally provide:
+//  - bool skip(args...): When `true`, skips the combination. Default is false.
+//
+// Returns int to facilitate registration. The return value is unspecified.
+template <template <class...> class B, class... Tuples, class... Args>
+int makeCartesianProductBenchmark(const Args&... A) {
+  std::vector<std::tuple<typename Args::value_type...> > V;
+  internal::allValueCombinations(V, std::tuple<>(), A...);
+  internal::makeBenchmarkImpl<B>(V, std::tuple<>(), Tuples()...);
+  return 0;
+}
+
+template <class B, class... Args>
+int makeCartesianProductBenchmark(const Args&... A) {
+  std::vector<std::tuple<typename Args::value_type...> > V;
+  internal::allValueCombinations(V, std::tuple<>(), A...);
+  internal::makeBenchmarkFromValues<B>(V);
+  return 0;
+}
+
+// When `opaque` is true, this function hides the runtime state of `value` from
+// the optimizer.
+// It returns `value`.
+template <class T>
+TEST_ALWAYS_INLINE inline T maybeOpaque(T value, bool opaque) {
+  if (opaque) benchmark::DoNotOptimize(value);
+  return value;
+}
diff --git a/benchmarks/ContainerBenchmarks.h b/benchmarks/ContainerBenchmarks.h
new file mode 100644
index 0000000..d2061f2
--- /dev/null
+++ b/benchmarks/ContainerBenchmarks.h
@@ -0,0 +1,140 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BENCHMARK_CONTAINER_BENCHMARKS_H
+#define BENCHMARK_CONTAINER_BENCHMARKS_H
+
+#include <cassert>
+
+#include "Utilities.h"
+#include "benchmark/benchmark.h"
+
+namespace ContainerBenchmarks {
+
+template <class Container>
+void BM_ConstructSize(benchmark::State& st, Container) {
+  auto size = st.range(0);
+  for (auto _ : st) {
+    Container c(size);
+    DoNotOptimizeData(c);
+  }
+}
+
+template <class Container>
+void BM_ConstructSizeValue(benchmark::State& st, Container, typename Container::value_type const& val) {
+  const auto size = st.range(0);
+  for (auto _ : st) {
+    Container c(size, val);
+    DoNotOptimizeData(c);
+  }
+}
+
+template <class Container, class GenInputs>
+void BM_ConstructIterIter(benchmark::State& st, Container, GenInputs gen) {
+    auto in = gen(st.range(0));
+    const auto begin = in.begin();
+    const auto end = in.end();
+    benchmark::DoNotOptimize(&in);
+    while (st.KeepRunning()) {
+        Container c(begin, end);
+        DoNotOptimizeData(c);
+    }
+}
+
+template <class Container, class GenInputs>
+void BM_InsertValue(benchmark::State& st, Container c, GenInputs gen) {
+    auto in = gen(st.range(0));
+    const auto end = in.end();
+    while (st.KeepRunning()) {
+        c.clear();
+        for (auto it = in.begin(); it != end; ++it) {
+            benchmark::DoNotOptimize(&(*c.insert(*it).first));
+        }
+        benchmark::ClobberMemory();
+    }
+}
+
+template <class Container, class GenInputs>
+void BM_InsertValueRehash(benchmark::State& st, Container c, GenInputs gen) {
+    auto in = gen(st.range(0));
+    const auto end = in.end();
+    while (st.KeepRunning()) {
+        c.clear();
+        c.rehash(16);
+        for (auto it = in.begin(); it != end; ++it) {
+            benchmark::DoNotOptimize(&(*c.insert(*it).first));
+        }
+        benchmark::ClobberMemory();
+    }
+}
+
+
+template <class Container, class GenInputs>
+void BM_InsertDuplicate(benchmark::State& st, Container c, GenInputs gen) {
+    auto in = gen(st.range(0));
+    const auto end = in.end();
+    c.insert(in.begin(), in.end());
+    benchmark::DoNotOptimize(&c);
+    benchmark::DoNotOptimize(&in);
+    while (st.KeepRunning()) {
+        for (auto it = in.begin(); it != end; ++it) {
+            benchmark::DoNotOptimize(&(*c.insert(*it).first));
+        }
+        benchmark::ClobberMemory();
+    }
+}
+
+
+template <class Container, class GenInputs>
+void BM_EmplaceDuplicate(benchmark::State& st, Container c, GenInputs gen) {
+    auto in = gen(st.range(0));
+    const auto end = in.end();
+    c.insert(in.begin(), in.end());
+    benchmark::DoNotOptimize(&c);
+    benchmark::DoNotOptimize(&in);
+    while (st.KeepRunning()) {
+        for (auto it = in.begin(); it != end; ++it) {
+            benchmark::DoNotOptimize(&(*c.emplace(*it).first));
+        }
+        benchmark::ClobberMemory();
+    }
+}
+
+template <class Container, class GenInputs>
+static void BM_Find(benchmark::State& st, Container c, GenInputs gen) {
+    auto in = gen(st.range(0));
+    c.insert(in.begin(), in.end());
+    benchmark::DoNotOptimize(&(*c.begin()));
+    const auto end = in.data() + in.size();
+    while (st.KeepRunning()) {
+        for (auto it = in.data(); it != end; ++it) {
+            benchmark::DoNotOptimize(&(*c.find(*it)));
+        }
+        benchmark::ClobberMemory();
+    }
+}
+
+template <class Container, class GenInputs>
+static void BM_FindRehash(benchmark::State& st, Container c, GenInputs gen) {
+    c.rehash(8);
+    auto in = gen(st.range(0));
+    c.insert(in.begin(), in.end());
+    benchmark::DoNotOptimize(&(*c.begin()));
+    const auto end = in.data() + in.size();
+    while (st.KeepRunning()) {
+        for (auto it = in.data(); it != end; ++it) {
+            benchmark::DoNotOptimize(&(*c.find(*it)));
+        }
+        benchmark::ClobberMemory();
+    }
+}
+
+} // end namespace ContainerBenchmarks
+
+#endif // BENCHMARK_CONTAINER_BENCHMARKS_H
diff --git a/benchmarks/GenerateInput.h b/benchmarks/GenerateInput.h
new file mode 100644
index 0000000..e4f131c
--- /dev/null
+++ b/benchmarks/GenerateInput.h
@@ -0,0 +1,144 @@
+#ifndef BENCHMARK_GENERATE_INPUT_H
+#define BENCHMARK_GENERATE_INPUT_H
+
+#include <algorithm>
+#include <random>
+#include <vector>
+#include <string>
+#include <climits>
+#include <cstddef>
+
+static const char Letters[] = {
+    '0','1','2','3','4',
+    '5','6','7','8','9',
+    'A','B','C','D','E','F',
+    'G','H','I','J','K',
+    'L','M','N','O','P',
+    'Q','R','S','T','U',
+    'V','W','X','Y','Z',
+    'a','b','c','d','e','f',
+    'g','h','i','j','k',
+    'l','m','n','o','p',
+    'q','r','s','t','u',
+    'v','w','x','y','z'
+};
+static const std::size_t LettersSize = sizeof(Letters);
+
+inline std::default_random_engine& getRandomEngine() {
+    static std::default_random_engine RandEngine(std::random_device{}());
+    return RandEngine;
+}
+
+
+inline char getRandomChar() {
+    std::uniform_int_distribution<> LettersDist(0, LettersSize-1);
+    return Letters[LettersDist(getRandomEngine())];
+}
+
+template <class IntT>
+inline IntT getRandomInteger(IntT Min = 0,
+                             IntT Max = std::numeric_limits<IntT>::max()) {
+    std::uniform_int_distribution<IntT> dist(Min, Max);
+    return dist(getRandomEngine());
+}
+
+inline std::string getRandomString(std::size_t Len) {
+    std::string str(Len, 0);
+    std::generate_n(str.begin(), Len, &getRandomChar);
+    return str;
+}
+
+template <class IntT>
+inline std::vector<IntT> getDuplicateIntegerInputs(size_t N) {
+    std::vector<IntT> inputs(N, static_cast<IntT>(-1));
+    return inputs;
+}
+
+template <class IntT>
+inline std::vector<IntT> getSortedIntegerInputs(size_t N) {
+    std::vector<IntT> inputs;
+    for (size_t i=0; i < N; i += 1)
+        inputs.push_back(i);
+    return inputs;
+}
+
+template <class IntT>
+std::vector<IntT> getSortedLargeIntegerInputs(size_t N) {
+    std::vector<IntT> inputs;
+    for (size_t i=0; i < N; ++i) {
+        inputs.push_back(i + N);
+    }
+    return inputs;
+}
+
+template <class IntT>
+std::vector<IntT> getSortedTopBitsIntegerInputs(size_t N) {
+    std::vector<IntT> inputs = getSortedIntegerInputs<IntT>(N);
+    for (auto& E : inputs) E <<= ((sizeof(IntT) / 2) * CHAR_BIT);
+    return inputs;
+}
+
+template <class IntT>
+inline std::vector<IntT> getReverseSortedIntegerInputs(size_t N) {
+    std::vector<IntT> inputs;
+    std::size_t i = N;
+    while (i > 0) {
+        --i;
+        inputs.push_back(i);
+    }
+    return inputs;
+}
+
+template <class IntT>
+std::vector<IntT> getPipeOrganIntegerInputs(size_t N) {
+    std::vector<IntT> v; v.reserve(N);
+    for (size_t i = 0; i < N/2; ++i) v.push_back(i);
+    for (size_t i = N/2; i < N; ++i) v.push_back(N - i);
+    return v;
+}
+
+
+template <class IntT>
+std::vector<IntT> getRandomIntegerInputs(size_t N) {
+    std::vector<IntT> inputs;
+    for (size_t i=0; i < N; ++i) {
+        inputs.push_back(getRandomInteger<IntT>());
+    }
+    return inputs;
+}
+
+inline std::vector<std::string> getDuplicateStringInputs(size_t N) {
+    std::vector<std::string> inputs(N, getRandomString(1024));
+    return inputs;
+}
+
+inline std::vector<std::string> getRandomStringInputs(size_t N) {
+    std::vector<std::string> inputs;
+    for (size_t i=0; i < N; ++i) {
+        inputs.push_back(getRandomString(1024));
+    }
+    return inputs;
+}
+
+inline std::vector<std::string> getSortedStringInputs(size_t N) {
+    std::vector<std::string> inputs = getRandomStringInputs(N);
+    std::sort(inputs.begin(), inputs.end());
+    return inputs;
+}
+
+inline std::vector<std::string> getReverseSortedStringInputs(size_t N) {
+    std::vector<std::string> inputs = getSortedStringInputs(N);
+    std::reverse(inputs.begin(), inputs.end());
+    return inputs;
+}
+
+inline std::vector<const char*> getRandomCStringInputs(size_t N) {
+    static std::vector<std::string> inputs = getRandomStringInputs(N);
+    std::vector<const char*> cinputs;
+    for (auto const& str : inputs)
+        cinputs.push_back(str.c_str());
+    return cinputs;
+}
+
+
+#endif // BENCHMARK_GENERATE_INPUT_H
diff --git a/benchmarks/Utilities.h b/benchmarks/Utilities.h
new file mode 100644
index 0000000..9ad2a58
--- /dev/null
+++ b/benchmarks/Utilities.h
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BENCHMARK_UTILITIES_H
+#define BENCHMARK_UTILITIES_H
+
+#include <cassert>
+#include <type_traits>
+
+#include "benchmark/benchmark.h"
+
+namespace UtilitiesInternal {
+  template <class Container>
+  auto HaveDataImpl(int) -> decltype((std::declval<Container&>().data(), std::true_type{}));
+  template <class Container>
+  auto HaveDataImpl(long) -> std::false_type;
+  template <class T>
+  using HasData = decltype(HaveDataImpl<T>(0));
+} // namespace UtilitiesInternal
+
+template <class Container, std::enable_if_t<UtilitiesInternal::HasData<Container>::value>* = nullptr>
+void DoNotOptimizeData(Container &c) { benchmark::DoNotOptimize(c.data()); }
+template <class Container, std::enable_if_t<!UtilitiesInternal::HasData<Container>::value>* = nullptr>
+void DoNotOptimizeData(Container &c) { benchmark::DoNotOptimize(&c); }
+
+
+#endif // BENCHMARK_UTILITIES_H
diff --git a/benchmarks/VariantBenchmarks.h b/benchmarks/VariantBenchmarks.h
new file mode 100644
index 0000000..2feaeab
--- /dev/null
+++ b/benchmarks/VariantBenchmarks.h
@@ -0,0 +1,58 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BENCHMARK_VARIANT_BENCHMARKS_H
+#define BENCHMARK_VARIANT_BENCHMARKS_H
+
+#include <array>
+#include <cstddef>
+#include <tuple>
+#include <type_traits>
+#include <variant>
+
+#include "benchmark/benchmark.h"
+
+#include "GenerateInput.h"
+
+namespace VariantBenchmarks {
+
+template <std::size_t I>
+struct S {
+  static constexpr size_t v = I;
+};
+
+template <std::size_t N, std::size_t... Is>
+static auto genVariants(std::index_sequence<Is...>) {
+  using V = std::variant<S<Is>...>;
+  using F = V (*)();
+  static constexpr F fs[] = {[] { return V(std::in_place_index<Is>); }...};
+
+  std::array<V, N> result = {};
+  for (auto& v : result) {
+    v = fs[getRandomInteger(0ul, sizeof...(Is) - 1)]();
+  }
+
+  return result;
+}
+
+template <std::size_t N, std::size_t Alts>
+static void BM_Visit(benchmark::State& state) {
+  auto args = genVariants<N>(std::make_index_sequence<Alts>{});
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(std::apply(
+        [](auto... vs) {
+          return std::visit([](auto... is) { return (is.v + ... + 0); }, vs...);
+        },
+        args));
+  }
+}
+
+} // end namespace VariantBenchmarks
+
+#endif // BENCHMARK_VARIANT_BENCHMARKS_H
diff --git a/benchmarks/algorithms.bench.cpp b/benchmarks/algorithms.bench.cpp
new file mode 100644
index 0000000..93383e2
--- /dev/null
+++ b/benchmarks/algorithms.bench.cpp
@@ -0,0 +1,337 @@
+
+#include <algorithm>
+#include <cstdint>
+#include <map>
+#include <random>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "CartesianBenchmarks.h"
+#include "GenerateInput.h"
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
+
+namespace {
+
+enum class ValueType { Uint32, Uint64, Pair, Tuple, String };
+struct AllValueTypes : EnumValuesAsTuple<AllValueTypes, ValueType, 5> {
+  static constexpr const char* Names[] = {
+      "uint32", "uint64", "pair<uint32, uint32>",
+      "tuple<uint32, uint64, uint32>", "string"};
+};
+
+template <class V>
+using Value = std::conditional_t<
+    V() == ValueType::Uint32, uint32_t,
+    std::conditional_t<
+        V() == ValueType::Uint64, uint64_t,
+        std::conditional_t<
+            V() == ValueType::Pair, std::pair<uint32_t, uint32_t>,
+            std::conditional_t<V() == ValueType::Tuple,
+                               std::tuple<uint32_t, uint64_t, uint32_t>,
+                               std::string> > > >;
+
+enum class Order {
+  Random,
+  Ascending,
+  Descending,
+  SingleElement,
+  PipeOrgan,
+  Heap
+};
+struct AllOrders : EnumValuesAsTuple<AllOrders, Order, 6> {
+  static constexpr const char* Names[] = {"Random",     "Ascending",
+                                          "Descending", "SingleElement",
+                                          "PipeOrgan",  "Heap"};
+};
+
+template <typename T>
+void fillValues(std::vector<T>& V, size_t N, Order O) {
+  if (O == Order::SingleElement) {
+    V.resize(N, 0);
+  } else {
+    while (V.size() < N)
+      V.push_back(V.size());
+  }
+}
+
+template <typename T>
+void fillValues(std::vector<std::pair<T, T> >& V, size_t N, Order O) {
+  if (O == Order::SingleElement) {
+    V.resize(N, std::make_pair(0, 0));
+  } else {
+    while (V.size() < N)
+      // Half of array will have the same first element.
+      if (V.size() % 2) {
+        V.push_back(std::make_pair(V.size(), V.size()));
+      } else {
+        V.push_back(std::make_pair(0, V.size()));
+      }
+  }
+}
+
+template <typename T1, typename T2, typename T3>
+void fillValues(std::vector<std::tuple<T1, T2, T3> >& V, size_t N, Order O) {
+  if (O == Order::SingleElement) {
+    V.resize(N, std::make_tuple(0, 0, 0));
+  } else {
+    while (V.size() < N)
+      // One third of array will have the same first element.
+      // One third of array will have the same first element and the same second element.
+      switch (V.size() % 3) {
+      case 0:
+        V.push_back(std::make_tuple(V.size(), V.size(), V.size()));
+        break;
+      case 1:
+        V.push_back(std::make_tuple(0, V.size(), V.size()));
+        break;
+      case 2:
+        V.push_back(std::make_tuple(0, 0, V.size()));
+        break;
+      }
+  }
+}
+
+void fillValues(std::vector<std::string>& V, size_t N, Order O) {
+  if (O == Order::SingleElement) {
+    V.resize(N, getRandomString(64));
+  } else {
+    while (V.size() < N)
+      V.push_back(getRandomString(64));
+  }
+}
+
+template <class T>
+void sortValues(T& V, Order O) {
+  assert(std::is_sorted(V.begin(), V.end()));
+  switch (O) {
+  case Order::Random: {
+    std::random_device R;
+    std::mt19937 M(R());
+    std::shuffle(V.begin(), V.end(), M);
+    break;
+  }
+  case Order::Ascending:
+    std::sort(V.begin(), V.end());
+    break;
+  case Order::Descending:
+    std::sort(V.begin(), V.end(), std::greater<>());
+    break;
+  case Order::SingleElement:
+    // Nothing to do
+    break;
+  case Order::PipeOrgan:
+    std::sort(V.begin(), V.end());
+    std::reverse(V.begin() + V.size() / 2, V.end());
+    break;
+  case Order::Heap:
+    std::make_heap(V.begin(), V.end());
+    break;
+  }
+}
+
+constexpr size_t TestSetElements =
+#if !TEST_HAS_FEATURE(memory_sanitizer)
+    1 << 18;
+#else
+    1 << 14;
+#endif
+
+template <class ValueType>
+std::vector<std::vector<Value<ValueType> > > makeOrderedValues(size_t N,
+                                                               Order O) {
+  std::vector<std::vector<Value<ValueType> > > Ret;
+  const size_t NumCopies = std::max(size_t{1}, TestSetElements / N);
+  Ret.resize(NumCopies);
+  for (auto& V : Ret) {
+    fillValues(V, N, O);
+    sortValues(V, O);
+  }
+  return Ret;
+}
+
+template <class T, class U>
+TEST_ALWAYS_INLINE void resetCopies(benchmark::State& state, T& Copies,
+                                    U& Orig) {
+  state.PauseTiming();
+  for (auto& Copy : Copies)
+    Copy = Orig;
+  state.ResumeTiming();
+}
+
+enum class BatchSize {
+  CountElements,
+  CountBatch,
+};
+
+template <class ValueType, class F>
+void runOpOnCopies(benchmark::State& state, size_t Quantity, Order O,
+                   BatchSize Count, F Body) {
+  auto Copies = makeOrderedValues<ValueType>(Quantity, O);
+  auto Orig = Copies;
+
+  const size_t Batch = Count == BatchSize::CountElements
+                           ? Copies.size() * Quantity
+                           : Copies.size();
+  while (state.KeepRunningBatch(Batch)) {
+    for (auto& Copy : Copies) {
+      Body(Copy);
+      benchmark::DoNotOptimize(Copy);
+    }
+    state.PauseTiming();
+    Copies = Orig;
+    state.ResumeTiming();
+  }
+}
+
+template <class ValueType, class Order>
+struct Sort {
+  size_t Quantity;
+
+  void run(benchmark::State& state) const {
+    runOpOnCopies<ValueType>(
+        state, Quantity, Order(), BatchSize::CountElements,
+        [](auto& Copy) { std::sort(Copy.begin(), Copy.end()); });
+  }
+
+  bool skip() const { return Order() == ::Order::Heap; }
+
+  std::string name() const {
+    return "BM_Sort" + ValueType::name() + Order::name() + "_" +
+           std::to_string(Quantity);
+  };
+};
+
+template <class ValueType, class Order>
+struct StableSort {
+  size_t Quantity;
+
+  void run(benchmark::State& state) const {
+    runOpOnCopies<ValueType>(
+        state, Quantity, Order(), BatchSize::CountElements,
+        [](auto& Copy) { std::stable_sort(Copy.begin(), Copy.end()); });
+  }
+
+  bool skip() const { return Order() == ::Order::Heap; }
+
+  std::string name() const {
+    return "BM_StableSort" + ValueType::name() + Order::name() + "_" +
+           std::to_string(Quantity);
+  };
+};
+
+template <class ValueType, class Order>
+struct MakeHeap {
+  size_t Quantity;
+
+  void run(benchmark::State& state) const {
+    runOpOnCopies<ValueType>(
+        state, Quantity, Order(), BatchSize::CountElements,
+        [](auto& Copy) { std::make_heap(Copy.begin(), Copy.end()); });
+  }
+
+  std::string name() const {
+    return "BM_MakeHeap" + ValueType::name() + Order::name() + "_" +
+           std::to_string(Quantity);
+  };
+};
+
+template <class ValueType>
+struct SortHeap {
+  size_t Quantity;
+
+  void run(benchmark::State& state) const {
+    runOpOnCopies<ValueType>(
+        state, Quantity, Order::Heap, BatchSize::CountElements,
+        [](auto& Copy) { std::sort_heap(Copy.begin(), Copy.end()); });
+  }
+
+  std::string name() const {
+    return "BM_SortHeap" + ValueType::name() + "_" + std::to_string(Quantity);
+  };
+};
+
+template <class ValueType, class Order>
+struct MakeThenSortHeap {
+  size_t Quantity;
+
+  void run(benchmark::State& state) const {
+    runOpOnCopies<ValueType>(state, Quantity, Order(), BatchSize::CountElements,
+                             [](auto& Copy) {
+                               std::make_heap(Copy.begin(), Copy.end());
+                               std::sort_heap(Copy.begin(), Copy.end());
+                             });
+  }
+
+  std::string name() const {
+    return "BM_MakeThenSortHeap" + ValueType::name() + Order::name() + "_" +
+           std::to_string(Quantity);
+  };
+};
+
+template <class ValueType, class Order>
+struct PushHeap {
+  size_t Quantity;
+
+  void run(benchmark::State& state) const {
+    runOpOnCopies<ValueType>(
+        state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
+          for (auto I = Copy.begin(), E = Copy.end(); I != E; ++I) {
+            std::push_heap(Copy.begin(), I + 1);
+          }
+        });
+  }
+
+  bool skip() const { return Order() == ::Order::Heap; }
+
+  std::string name() const {
+    return "BM_PushHeap" + ValueType::name() + Order::name() + "_" +
+           std::to_string(Quantity);
+  };
+};
+
+template <class ValueType>
+struct PopHeap {
+  size_t Quantity;
+
+  void run(benchmark::State& state) const {
+    runOpOnCopies<ValueType>(
+        state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
+          for (auto B = Copy.begin(), I = Copy.end(); I != B; --I) {
+            std::pop_heap(B, I);
+          }
+        });
+  }
+
+  std::string name() const {
+    return "BM_PopHeap" + ValueType::name() + "_" + std::to_string(Quantity);
+  };
+};
+
+} // namespace
+
+int main(int argc, char** argv) {
+  benchmark::Initialize(&argc, argv);
+  if (benchmark::ReportUnrecognizedArguments(argc, argv))
+    return 1;
+
+  const std::vector<size_t> Quantities = {1 << 0, 1 << 2,  1 << 4,  1 << 6,
+                                          1 << 8, 1 << 10, 1 << 14,
+    // Running each benchmark in parallel consumes too much memory with MSAN
+    // and can lead to the test process being killed.
+#if !TEST_HAS_FEATURE(memory_sanitizer)
+                                          1 << 18
+#endif
+  };
+  makeCartesianProductBenchmark<Sort, AllValueTypes, AllOrders>(Quantities);
+  makeCartesianProductBenchmark<StableSort, AllValueTypes, AllOrders>(
+      Quantities);
+  makeCartesianProductBenchmark<MakeHeap, AllValueTypes, AllOrders>(Quantities);
+  makeCartesianProductBenchmark<SortHeap, AllValueTypes>(Quantities);
+  makeCartesianProductBenchmark<MakeThenSortHeap, AllValueTypes, AllOrders>(
+      Quantities);
+  makeCartesianProductBenchmark<PushHeap, AllValueTypes, AllOrders>(Quantities);
+  makeCartesianProductBenchmark<PopHeap, AllValueTypes>(Quantities);
+  benchmark::RunSpecifiedBenchmarks();
+}
\ No newline at end of file
diff --git a/benchmarks/algorithms.partition_point.bench.cpp b/benchmarks/algorithms.partition_point.bench.cpp
new file mode 100644
index 0000000..840cf03
--- /dev/null
+++ b/benchmarks/algorithms.partition_point.bench.cpp
@@ -0,0 +1,124 @@
+#include <array>
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <tuple>
+#include <vector>
+
+#include "benchmark/benchmark.h"
+
+#include "CartesianBenchmarks.h"
+#include "GenerateInput.h"
+
+namespace {
+
+template <typename I, typename N>
+std::array<I, 10> every_10th_percentile_N(I first, N n) {
+  N step = n / 10;
+  std::array<I, 10> res;
+
+  for (size_t i = 0; i < 10; ++i) {
+    res[i] = first;
+    std::advance(first, step);
+  }
+
+  return res;
+}
+
+template <class IntT>
+struct TestIntBase {
+  static std::vector<IntT> generateInput(size_t size) {
+    std::vector<IntT> Res(size);
+    std::generate(Res.begin(), Res.end(),
+                  [] { return getRandomInteger<IntT>(); });
+    return Res;
+  }
+};
+
+struct TestInt32 : TestIntBase<std::int32_t> {
+  static constexpr const char* Name = "TestInt32";
+};
+
+struct TestInt64 : TestIntBase<std::int64_t> {
+  static constexpr const char* Name = "TestInt64";
+};
+
+struct TestUint32 : TestIntBase<std::uint32_t> {
+  static constexpr const char* Name = "TestUint32";
+};
+
+struct TestMediumString {
+  static constexpr const char* Name = "TestMediumString";
+  static constexpr size_t StringSize = 32;
+
+  static std::vector<std::string> generateInput(size_t size) {
+    std::vector<std::string> Res(size);
+    std::generate(Res.begin(), Res.end(), [] { return getRandomString(StringSize); });
+    return Res;
+  }
+};
+
+using AllTestTypes = std::tuple<TestInt32, TestInt64, TestUint32, TestMediumString>;
+
+struct LowerBoundAlg {
+  template <class I, class V>
+  I operator()(I first, I last, const V& value) const {
+    return std::lower_bound(first, last, value);
+  }
+
+  static constexpr const char* Name = "LowerBoundAlg";
+};
+
+struct UpperBoundAlg {
+  template <class I, class V>
+  I operator()(I first, I last, const V& value) const {
+    return std::upper_bound(first, last, value);
+  }
+
+  static constexpr const char* Name = "UpperBoundAlg";
+};
+
+struct EqualRangeAlg {
+  template <class I, class V>
+  std::pair<I, I> operator()(I first, I last, const V& value) const {
+    return std::equal_range(first, last, value);
+  }
+
+  static constexpr const char* Name = "EqualRangeAlg";
+};
+
+using AllAlgs = std::tuple<LowerBoundAlg, UpperBoundAlg, EqualRangeAlg>;
+
+template <class Alg, class TestType>
+struct PartitionPointBench {
+  size_t Quantity;
+
+  std::string name() const {
+    return std::string("PartitionPointBench_") + Alg::Name + "_" +
+           TestType::Name + '/' + std::to_string(Quantity);
+  }
+
+  void run(benchmark::State& state) const {
+    auto Data = TestType::generateInput(Quantity);
+    std::sort(Data.begin(), Data.end());
+    auto Every10Percentile = every_10th_percentile_N(Data.begin(), Data.size());
+
+    for (auto _ : state) {
+      for (auto Test : Every10Percentile)
+        benchmark::DoNotOptimize(Alg{}(Data.begin(), Data.end(), *Test));
+    }
+  }
+};
+
+} // namespace
+
+int main(int argc, char** argv) {
+  benchmark::Initialize(&argc, argv);
+  if (benchmark::ReportUnrecognizedArguments(argc, argv))
+    return 1;
+
+  const std::vector<size_t> Quantities = {1 << 8, 1 << 10, 1 << 20};
+  makeCartesianProductBenchmark<PartitionPointBench, AllAlgs, AllTestTypes>(
+      Quantities);
+  benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/benchmarks/allocation.bench.cpp b/benchmarks/allocation.bench.cpp
new file mode 100644
index 0000000..236e740
--- /dev/null
+++ b/benchmarks/allocation.bench.cpp
@@ -0,0 +1,136 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "benchmark/benchmark.h"
+
+#include <new>
+#include <vector>
+#include <cassert>
+
+struct PointerList {
+  PointerList* Next = nullptr;
+};
+
+struct MallocWrapper {
+  __attribute__((always_inline))
+  static void* Allocate(size_t N) {
+    return std::malloc(N);
+  }
+  __attribute__((always_inline))
+  static void Deallocate(void* P, size_t) {
+    std::free(P);
+  }
+};
+
+struct NewWrapper {
+  __attribute__((always_inline))
+  static void* Allocate(size_t N) {
+    return ::operator new(N);
+  }
+  __attribute__((always_inline))
+  static void Deallocate(void* P, size_t) {
+    ::operator delete(P);
+  }
+};
+
+struct BuiltinNewWrapper {
+  __attribute__((always_inline))
+  static void* Allocate(size_t N) {
+    return __builtin_operator_new(N);
+  }
+  __attribute__((always_inline))
+  static void Deallocate(void* P, size_t) {
+    __builtin_operator_delete(P);
+  }
+};
+
+struct BuiltinSizedNewWrapper {
+  __attribute__((always_inline))
+  static void* Allocate(size_t N) {
+    return __builtin_operator_new(N);
+  }
+  __attribute__((always_inline))
+  static void Deallocate(void* P, size_t N) {
+    __builtin_operator_delete(P, N);
+  }
+};
+
+
+template <class AllocWrapper>
+static void BM_AllocateAndDeallocate(benchmark::State& st) {
+  const size_t alloc_size = st.range(0);
+  while (st.KeepRunning()) {
+    void* p = AllocWrapper::Allocate(alloc_size);
+    benchmark::DoNotOptimize(p);
+    AllocWrapper::Deallocate(p, alloc_size);
+  }
+}
+
+
+template <class AllocWrapper>
+static void BM_AllocateOnly(benchmark::State& st) {
+  const size_t alloc_size = st.range(0);
+  PointerList *Start = nullptr;
+
+  while (st.KeepRunning()) {
+    PointerList* p = (PointerList*)AllocWrapper::Allocate(alloc_size);
+    benchmark::DoNotOptimize(p);
+    p->Next = Start;
+    Start = p;
+  }
+
+  PointerList *Next = Start;
+  while (Next) {
+    PointerList *Tmp = Next;
+    Next = Tmp->Next;
+    AllocWrapper::Deallocate(Tmp, alloc_size);
+  }
+}
+
+template <class AllocWrapper>
+static void BM_DeallocateOnly(benchmark::State& st) {
+  const size_t alloc_size = st.range(0);
+  const auto NumAllocs = st.max_iterations;
+
+  using PtrT = void*;
+  std::vector<void*> Pointers(NumAllocs);
+  for (auto& p : Pointers) {
+    p = AllocWrapper::Allocate(alloc_size);
+  }
+
+  void** Data = Pointers.data();
+  void** const End = Pointers.data() + Pointers.size();
+  while (st.KeepRunning()) {
+    AllocWrapper::Deallocate(*Data, alloc_size);
+    Data += 1;
+  }
+  assert(Data == End);
+}
+
+static int RegisterAllocBenchmarks() {
+  using FnType = void(*)(benchmark::State&);
+  struct {
+    const char* name;
+    FnType func;
+  } TestCases[] = {
+      {"BM_Malloc", &BM_AllocateAndDeallocate<MallocWrapper>},
+      {"BM_New", &BM_AllocateAndDeallocate<NewWrapper>},
+      {"BM_BuiltinNewDelete", BM_AllocateAndDeallocate<BuiltinNewWrapper>},
+      {"BM_BuiltinSizedNewDelete", BM_AllocateAndDeallocate<BuiltinSizedNewWrapper>},
+      {"BM_BuiltinNewAllocateOnly", BM_AllocateOnly<BuiltinSizedNewWrapper>},
+      {"BM_BuiltinNewSizedDeallocateOnly", BM_DeallocateOnly<BuiltinSizedNewWrapper>},
+
+  };
+  for (auto TC : TestCases) {
+    benchmark::RegisterBenchmark(TC.name, TC.func)->Range(16, 4096 * 2);
+  }
+  return 0;
+}
+int Sink = RegisterAllocBenchmarks();
+
+BENCHMARK_MAIN();
diff --git a/benchmarks/deque.bench.cpp b/benchmarks/deque.bench.cpp
new file mode 100644
index 0000000..0025a33
--- /dev/null
+++ b/benchmarks/deque.bench.cpp
@@ -0,0 +1,47 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <deque>
+
+#include "benchmark/benchmark.h"
+
+#include "ContainerBenchmarks.h"
+#include "GenerateInput.h"
+
+using namespace ContainerBenchmarks;
+
+constexpr std::size_t TestNumInputs = 1024;
+
+BENCHMARK_CAPTURE(BM_ConstructSize,
+    deque_byte,
+    std::deque<unsigned char>{})->Arg(5140480);
+
+BENCHMARK_CAPTURE(BM_ConstructSizeValue,
+    deque_byte,
+    std::deque<unsigned char>{}, 0)->Arg(5140480);
+
+BENCHMARK_CAPTURE(BM_ConstructIterIter,
+  deque_char,
+  std::deque<char>{},
+  getRandomIntegerInputs<char>)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_ConstructIterIter,
+  deque_size_t,
+  std::deque<size_t>{},
+  getRandomIntegerInputs<size_t>)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_ConstructIterIter,
+  deque_string,
+  std::deque<std::string>{},
+  getRandomStringInputs)->Arg(TestNumInputs);
+
+
+
+
+BENCHMARK_MAIN();
diff --git a/benchmarks/filesystem.bench.cpp b/benchmarks/filesystem.bench.cpp
new file mode 100644
index 0000000..95aecd5
--- /dev/null
+++ b/benchmarks/filesystem.bench.cpp
@@ -0,0 +1,163 @@
+#include "benchmark/benchmark.h"
+#include "GenerateInput.h"
+#include "test_iterators.h"
+#include "filesystem_include.h"
+
+static const size_t TestNumInputs = 1024;
+
+
+template <class GenInputs>
+void BM_PathConstructString(benchmark::State &st, GenInputs gen) {
+  using fs::path;
+  const auto in = gen(st.range(0));
+  path PP;
+  for (auto& Part : in)
+    PP /= Part;
+  benchmark::DoNotOptimize(PP.native().data());
+  while (st.KeepRunning()) {
+    const path P(PP.native());
+    benchmark::DoNotOptimize(P.native().data());
+  }
+  st.SetComplexityN(st.range(0));
+}
+BENCHMARK_CAPTURE(BM_PathConstructString, large_string,
+  getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
+
+
+template <class GenInputs>
+void BM_PathConstructCStr(benchmark::State &st, GenInputs gen) {
+  using fs::path;
+  const auto in = gen(st.range(0));
+  path PP;
+  for (auto& Part : in)
+    PP /= Part;
+  benchmark::DoNotOptimize(PP.native().data());
+  while (st.KeepRunning()) {
+    const path P(PP.native().c_str());
+    benchmark::DoNotOptimize(P.native().data());
+  }
+}
+BENCHMARK_CAPTURE(BM_PathConstructCStr, large_string,
+  getRandomStringInputs)->Arg(TestNumInputs);
+
+
+template <template <class...> class ItType, class GenInputs>
+void BM_PathConstructIter(benchmark::State &st, GenInputs gen) {
+  using fs::path;
+  using Iter = ItType<std::string::const_iterator>;
+  const auto in = gen(st.range(0));
+  path PP;
+  for (auto& Part : in)
+    PP /= Part;
+  auto Start = Iter(PP.native().begin());
+  auto End = Iter(PP.native().end());
+  benchmark::DoNotOptimize(PP.native().data());
+  benchmark::DoNotOptimize(Start);
+  benchmark::DoNotOptimize(End);
+  while (st.KeepRunning()) {
+    const path P(Start, End);
+    benchmark::DoNotOptimize(P.native().data());
+  }
+  st.SetComplexityN(st.range(0));
+}
+template <class GenInputs>
+void BM_PathConstructInputIter(benchmark::State &st, GenInputs gen) {
+  BM_PathConstructIter<cpp17_input_iterator>(st, gen);
+}
+template <class GenInputs>
+void BM_PathConstructForwardIter(benchmark::State &st, GenInputs gen) {
+  BM_PathConstructIter<forward_iterator>(st, gen);
+}
+BENCHMARK_CAPTURE(BM_PathConstructInputIter, large_string,
+  getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
+BENCHMARK_CAPTURE(BM_PathConstructForwardIter, large_string,
+  getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
+
+
+template <class GenInputs>
+void BM_PathIterateMultipleTimes(benchmark::State &st, GenInputs gen) {
+  using fs::path;
+  const auto in = gen(st.range(0));
+  path PP;
+  for (auto& Part : in)
+    PP /= Part;
+  benchmark::DoNotOptimize(PP.native().data());
+  while (st.KeepRunning()) {
+    for (auto &E : PP) {
+      benchmark::DoNotOptimize(E.native().data());
+    }
+    benchmark::ClobberMemory();
+  }
+  st.SetComplexityN(st.range(0));
+}
+BENCHMARK_CAPTURE(BM_PathIterateMultipleTimes, iterate_elements,
+  getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
+
+
+template <class GenInputs>
+void BM_PathIterateOnce(benchmark::State &st, GenInputs gen) {
+  using fs::path;
+  const auto in = gen(st.range(0));
+  path PP;
+  for (auto& Part : in)
+    PP /= Part;
+  benchmark::DoNotOptimize(PP.native().data());
+  while (st.KeepRunning()) {
+    const path P = PP.native();
+    for (auto &E : P) {
+      benchmark::DoNotOptimize(E.native().data());
+    }
+    benchmark::ClobberMemory();
+  }
+  st.SetComplexityN(st.range(0));
+}
+BENCHMARK_CAPTURE(BM_PathIterateOnce, iterate_elements,
+  getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
+
+template <class GenInputs>
+void BM_PathIterateOnceBackwards(benchmark::State &st, GenInputs gen) {
+  using fs::path;
+  const auto in = gen(st.range(0));
+  path PP;
+  for (auto& Part : in)
+    PP /= Part;
+  benchmark::DoNotOptimize(PP.native().data());
+  while (st.KeepRunning()) {
+    const path P = PP.native();
+    const auto B = P.begin();
+    auto I = P.end();
+    while (I != B) {
+      --I;
+      benchmark::DoNotOptimize(*I);
+    }
+    benchmark::DoNotOptimize(*I);
+  }
+}
+BENCHMARK_CAPTURE(BM_PathIterateOnceBackwards, iterate_elements,
+  getRandomStringInputs)->Arg(TestNumInputs);
+
+static fs::path getRandomPaths(int NumParts, int PathLen) {
+  fs::path Result;
+  while (NumParts--) {
+    std::string Part = getRandomString(PathLen);
+    Result /= Part;
+  }
+  return Result;
+}
+
+template <class GenInput>
+void BM_LexicallyNormal(benchmark::State &st, GenInput gen, size_t PathLen) {
+  using fs::path;
+  auto In = gen(st.range(0), PathLen);
+  benchmark::DoNotOptimize(&In);
+  while (st.KeepRunning()) {
+    benchmark::DoNotOptimize(In.lexically_normal());
+  }
+  st.SetComplexityN(st.range(0));
+}
+BENCHMARK_CAPTURE(BM_LexicallyNormal, small_path,
+  getRandomPaths, /*PathLen*/5)->RangeMultiplier(2)->Range(2, 256)->Complexity();
+BENCHMARK_CAPTURE(BM_LexicallyNormal, large_path,
+  getRandomPaths, /*PathLen*/32)->RangeMultiplier(2)->Range(2, 256)->Complexity();
+
+BENCHMARK_MAIN();
diff --git a/benchmarks/function.bench.cpp b/benchmarks/function.bench.cpp
new file mode 100644
index 0000000..7fabc93
--- /dev/null
+++ b/benchmarks/function.bench.cpp
@@ -0,0 +1,231 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <string>
+
+#include "CartesianBenchmarks.h"
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
+
+namespace {
+
+enum class FunctionType {
+  Null,
+  FunctionPointer,
+  MemberFunctionPointer,
+  MemberPointer,
+  SmallTrivialFunctor,
+  SmallNonTrivialFunctor,
+  LargeTrivialFunctor,
+  LargeNonTrivialFunctor
+};
+
+struct AllFunctionTypes : EnumValuesAsTuple<AllFunctionTypes, FunctionType, 8> {
+  static constexpr const char* Names[] = {"Null",
+                                          "FuncPtr",
+                                          "MemFuncPtr",
+                                          "MemPtr",
+                                          "SmallTrivialFunctor",
+                                          "SmallNonTrivialFunctor",
+                                          "LargeTrivialFunctor",
+                                          "LargeNonTrivialFunctor"};
+};
+
+enum class Opacity { kOpaque, kTransparent };
+
+struct AllOpacity : EnumValuesAsTuple<AllOpacity, Opacity, 2> {
+  static constexpr const char* Names[] = {"Opaque", "Transparent"};
+};
+
+struct S {
+  int function() const { return 0; }
+  int field = 0;
+};
+
+int FunctionWithS(const S*) { return 0; }
+
+struct SmallTrivialFunctor {
+  int operator()(const S*) const { return 0; }
+};
+struct SmallNonTrivialFunctor {
+  SmallNonTrivialFunctor() {}
+  SmallNonTrivialFunctor(const SmallNonTrivialFunctor&) {}
+  ~SmallNonTrivialFunctor() {}
+  int operator()(const S*) const { return 0; }
+};
+struct LargeTrivialFunctor {
+  LargeTrivialFunctor() {
+      // Do not spend time initializing the padding.
+  }
+  int padding[16];
+  int operator()(const S*) const { return 0; }
+};
+struct LargeNonTrivialFunctor {
+  int padding[16];
+  LargeNonTrivialFunctor() {
+      // Do not spend time initializing the padding.
+  }
+  LargeNonTrivialFunctor(const LargeNonTrivialFunctor&) {}
+  ~LargeNonTrivialFunctor() {}
+  int operator()(const S*) const { return 0; }
+};
+
+using Function = std::function<int(const S*)>;
+
+TEST_ALWAYS_INLINE
+inline Function MakeFunction(FunctionType type, bool opaque = false) {
+  switch (type) {
+    case FunctionType::Null:
+      return nullptr;
+    case FunctionType::FunctionPointer:
+      return maybeOpaque(FunctionWithS, opaque);
+    case FunctionType::MemberFunctionPointer:
+      return maybeOpaque(&S::function, opaque);
+    case FunctionType::MemberPointer:
+      return maybeOpaque(&S::field, opaque);
+    case FunctionType::SmallTrivialFunctor:
+      return maybeOpaque(SmallTrivialFunctor{}, opaque);
+    case FunctionType::SmallNonTrivialFunctor:
+      return maybeOpaque(SmallNonTrivialFunctor{}, opaque);
+    case FunctionType::LargeTrivialFunctor:
+      return maybeOpaque(LargeTrivialFunctor{}, opaque);
+    case FunctionType::LargeNonTrivialFunctor:
+      return maybeOpaque(LargeNonTrivialFunctor{}, opaque);
+  }
+}
+
+template <class Opacity, class FunctionType>
+struct ConstructAndDestroy {
+  static void run(benchmark::State& state) {
+    for (auto _ : state) {
+      if (Opacity() == ::Opacity::kOpaque) {
+        benchmark::DoNotOptimize(MakeFunction(FunctionType(), true));
+      } else {
+        MakeFunction(FunctionType());
+      }
+    }
+  }
+
+  static std::string name() {
+    return "BM_ConstructAndDestroy" + FunctionType::name() + Opacity::name();
+  }
+};
+
+template <class FunctionType>
+struct Copy {
+  static void run(benchmark::State& state) {
+    auto value = MakeFunction(FunctionType());
+    for (auto _ : state) {
+      benchmark::DoNotOptimize(value);
+      auto copy = value;  // NOLINT
+      benchmark::DoNotOptimize(copy);
+    }
+  }
+
+  static std::string name() { return "BM_Copy" + FunctionType::name(); }
+};
+
+template <class FunctionType>
+struct Move {
+  static void run(benchmark::State& state) {
+    Function values[2] = {MakeFunction(FunctionType())};
+    int i = 0;
+    for (auto _ : state) {
+      benchmark::DoNotOptimize(values);
+      benchmark::DoNotOptimize(values[i ^ 1] = std::move(values[i]));
+      i ^= 1;
+    }
+  }
+
+  static std::string name() {
+    return "BM_Move" + FunctionType::name();
+  }
+};
+
+template <class Function1, class Function2>
+struct Swap {
+  static void run(benchmark::State& state) {
+    Function values[2] = {MakeFunction(Function1()), MakeFunction(Function2())};
+    for (auto _ : state) {
+      benchmark::DoNotOptimize(values);
+      values[0].swap(values[1]);
+    }
+  }
+
+  static bool skip() { return Function1() > Function2(); }
+
+  static std::string name() {
+    return "BM_Swap" + Function1::name() + Function2::name();
+  }
+};
+
+template <class FunctionType>
+struct OperatorBool {
+  static void run(benchmark::State& state) {
+    auto f = MakeFunction(FunctionType());
+    for (auto _ : state) {
+      benchmark::DoNotOptimize(f);
+      benchmark::DoNotOptimize(static_cast<bool>(f));
+    }
+  }
+
+  static std::string name() { return "BM_OperatorBool" + FunctionType::name(); }
+};
+
+template <class FunctionType>
+struct Invoke {
+  static void run(benchmark::State& state) {
+    S s;
+    const auto value = MakeFunction(FunctionType());
+    for (auto _ : state) {
+      benchmark::DoNotOptimize(value);
+      benchmark::DoNotOptimize(value(&s));
+    }
+  }
+
+  static bool skip() { return FunctionType() == ::FunctionType::Null; }
+
+  static std::string name() { return "BM_Invoke" + FunctionType::name(); }
+};
+
+template <class FunctionType>
+struct InvokeInlined {
+  static void run(benchmark::State& state) {
+    S s;
+    for (auto _ : state) {
+      MakeFunction(FunctionType())(&s);
+    }
+  }
+
+  static bool skip() { return FunctionType() == ::FunctionType::Null; }
+
+  static std::string name() {
+    return "BM_InvokeInlined" + FunctionType::name();
+  }
+};
+
+}  // namespace
+
+int main(int argc, char** argv) {
+  benchmark::Initialize(&argc, argv);
+  if (benchmark::ReportUnrecognizedArguments(argc, argv))
+    return 1;
+
+  makeCartesianProductBenchmark<ConstructAndDestroy, AllOpacity,
+                                AllFunctionTypes>();
+  makeCartesianProductBenchmark<Copy, AllFunctionTypes>();
+  makeCartesianProductBenchmark<Move, AllFunctionTypes>();
+  makeCartesianProductBenchmark<Swap, AllFunctionTypes, AllFunctionTypes>();
+  makeCartesianProductBenchmark<OperatorBool, AllFunctionTypes>();
+  makeCartesianProductBenchmark<Invoke, AllFunctionTypes>();
+  makeCartesianProductBenchmark<InvokeInlined, AllFunctionTypes>();
+  benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/benchmarks/lit.cfg.py b/benchmarks/lit.cfg.py
new file mode 100644
index 0000000..84857d5
--- /dev/null
+++ b/benchmarks/lit.cfg.py
@@ -0,0 +1,23 @@
+# -*- Python -*- vim: set ft=python ts=4 sw=4 expandtab tw=79:
+# Configuration file for the 'lit' test runner.
+import os
+import site
+
+site.addsitedir(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'utils'))
+from libcxx.test.googlebenchmark import GoogleBenchmark
+
+# Tell pylint that we know config and lit_config exist somewhere.
+if 'PYLINT_IMPORT' in os.environ:
+    config = object()
+    lit_config = object()
+
+# name: The name of this test suite.
+config.name = 'libc++ benchmarks'
+config.suffixes = []
+
+config.test_exec_root = os.path.join(config.libcxx_obj_root, 'benchmarks')
+config.test_source_root = config.test_exec_root
+
+config.test_format = GoogleBenchmark(test_sub_dirs='.',
+                                     test_suffix='.libcxx.out',
+                                     benchmark_args=config.benchmark_args)
\ No newline at end of file
diff --git a/benchmarks/lit.site.cfg.py.in b/benchmarks/lit.site.cfg.py.in
new file mode 100644
index 0000000..e3ce8b2
--- /dev/null
+++ b/benchmarks/lit.site.cfg.py.in
@@ -0,0 +1,10 @@
+@LIT_SITE_CFG_IN_HEADER@
+
+import sys
+
+config.libcxx_src_root = "@LIBCXX_SOURCE_DIR@"
+config.libcxx_obj_root = "@LIBCXX_BINARY_DIR@"
+config.benchmark_args = "@LIBCXX_BENCHMARK_TEST_ARGS@".split(';')
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@LIBCXX_SOURCE_DIR@/benchmarks/lit.cfg.py")
\ No newline at end of file
diff --git a/benchmarks/map.bench.cpp b/benchmarks/map.bench.cpp
new file mode 100644
index 0000000..dd1884f
--- /dev/null
+++ b/benchmarks/map.bench.cpp
@@ -0,0 +1,1037 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+#include <cstdint>
+#include <map>
+#include <random>
+#include <vector>
+
+#include "CartesianBenchmarks.h"
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
+
+// When VALIDATE is defined the benchmark will run to validate the benchmarks.
+// The time taken by several operations depend on whether or not an element
+// exists. To avoid errors in the benchmark these operations have a validation
+// mode to test the benchmark. Since they are not meant to be benchmarked the
+// number of sizes tested is limited to 1.
+//#define VALIDATE
+
+namespace {
+
+enum class Mode { Hit, Miss };
+
+struct AllModes : EnumValuesAsTuple<AllModes, Mode, 2> {
+  static constexpr const char* Names[] = {"ExistingElement", "NewElement"};
+};
+
+// The positions of the hints to pick:
+// - Begin picks the first item. The item cannot be put before this element.
+// - Thrid picks the third item. This is just an element with a valid entry
+//   before and after it.
+// - Correct contains the correct hint.
+// - End contains a hint to the end of the map.
+enum class Hint { Begin, Third, Correct, End };
+struct AllHints : EnumValuesAsTuple<AllHints, Hint, 4> {
+  static constexpr const char* Names[] = {"Begin", "Third", "Correct", "End"};
+};
+
+enum class Order { Sorted, Random };
+struct AllOrders : EnumValuesAsTuple<AllOrders, Order, 2> {
+  static constexpr const char* Names[] = {"Sorted", "Random"};
+};
+
+struct TestSets {
+  std::vector<uint64_t> Keys;
+  std::vector<std::map<uint64_t, int64_t> > Maps;
+  std::vector<
+      std::vector<typename std::map<uint64_t, int64_t>::const_iterator> >
+      Hints;
+};
+
+enum class Shuffle { None, Keys, Hints };
+
+TestSets makeTestingSets(size_t MapSize, Mode mode, Shuffle shuffle,
+                         size_t max_maps) {
+  /*
+   * The shuffle does not retain the random number generator to use the same
+   * set of random numbers for every iteration.
+   */
+  TestSets R;
+
+  int MapCount = std::min(max_maps, 1000000 / MapSize);
+
+  for (uint64_t I = 0; I < MapSize; ++I) {
+    R.Keys.push_back(mode == Mode::Hit ? 2 * I + 2 : 2 * I + 1);
+  }
+  if (shuffle == Shuffle::Keys)
+    std::shuffle(R.Keys.begin(), R.Keys.end(), std::mt19937());
+
+  for (int M = 0; M < MapCount; ++M) {
+    auto& map = R.Maps.emplace_back();
+    auto& hints = R.Hints.emplace_back();
+    for (uint64_t I = 0; I < MapSize; ++I) {
+      hints.push_back(map.insert(std::make_pair(2 * I + 2, 0)).first);
+    }
+    if (shuffle == Shuffle::Hints)
+      std::shuffle(hints.begin(), hints.end(), std::mt19937());
+  }
+
+  return R;
+}
+
+struct Base {
+  size_t MapSize;
+  Base(size_t T) : MapSize(T) {}
+
+  std::string baseName() const { return "_MapSize=" + std::to_string(MapSize); }
+};
+
+//*******************************************************************|
+//                       Member functions                            |
+//*******************************************************************|
+
+struct ConstructorDefault {
+  void run(benchmark::State& State) const {
+    for (auto _ : State) {
+      benchmark::DoNotOptimize(std::map<uint64_t, int64_t>());
+    }
+  }
+
+  std::string name() const { return "BM_ConstructorDefault"; }
+};
+
+struct ConstructorIterator : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1);
+    auto& Map = Data.Maps.front();
+    while (State.KeepRunningBatch(MapSize)) {
+#ifndef VALIDATE
+      benchmark::DoNotOptimize(
+          std::map<uint64_t, int64_t>(Map.begin(), Map.end()));
+#else
+      std::map<uint64_t, int64_t> M{Map.begin(), Map.end()};
+      if (M != Map)
+        State.SkipWithError("Map copy not identical");
+#endif
+    }
+  }
+
+  std::string name() const { return "BM_ConstructorIterator" + baseName(); }
+};
+
+struct ConstructorCopy : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1);
+    auto& Map = Data.Maps.front();
+    while (State.KeepRunningBatch(MapSize)) {
+#ifndef VALIDATE
+      std::map<uint64_t, int64_t> M(Map);
+      benchmark::DoNotOptimize(M);
+#else
+      std::map<uint64_t, int64_t> M(Map);
+      if (M != Map)
+        State.SkipWithError("Map copy not identical");
+#endif
+    }
+  }
+
+  std::string name() const { return "BM_ConstructorCopy" + baseName(); }
+};
+
+struct ConstructorMove : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (auto& Map : Data.Maps) {
+        std::map<uint64_t, int64_t> M(std::move(Map));
+        benchmark::DoNotOptimize(M);
+      }
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
+      State.ResumeTiming();
+    }
+  }
+
+  std::string name() const { return "BM_ConstructorMove" + baseName(); }
+};
+
+//*******************************************************************|
+//                           Capacity                                |
+//*******************************************************************|
+
+struct Empty : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1);
+    auto& Map = Data.Maps.front();
+    for (auto _ : State) {
+#ifndef VALIDATE
+      benchmark::DoNotOptimize(Map.empty());
+#else
+      if (Map.empty())
+        State.SkipWithError("Map contains an invalid number of elements.");
+#endif
+    }
+  }
+
+  std::string name() const { return "BM_Empty" + baseName(); }
+};
+
+struct Size : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1);
+    auto& Map = Data.Maps.front();
+    for (auto _ : State) {
+#ifndef VALIDATE
+      benchmark::DoNotOptimize(Map.size());
+#else
+      if (Map.size() != MapSize)
+        State.SkipWithError("Map contains an invalid number of elements.");
+#endif
+    }
+  }
+
+  std::string name() const { return "BM_Size" + baseName(); }
+};
+
+//*******************************************************************|
+//                           Modifiers                               |
+//*******************************************************************|
+
+struct Clear : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (auto& Map : Data.Maps) {
+        Map.clear();
+        benchmark::DoNotOptimize(Map);
+      }
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
+      State.ResumeTiming();
+    }
+  }
+
+  std::string name() const { return "BM_Clear" + baseName(); }
+};
+
+template <class Mode, class Order>
+struct Insert : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(
+        MapSize, Mode(),
+        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (auto& Map : Data.Maps) {
+        for (auto K : Data.Keys) {
+#ifndef VALIDATE
+          benchmark::DoNotOptimize(Map.insert(std::make_pair(K, 1)));
+#else
+          bool Inserted = Map.insert(std::make_pair(K, 1)).second;
+          if (Mode() == ::Mode::Hit) {
+            if (Inserted)
+              State.SkipWithError("Inserted a duplicate element");
+          } else {
+            if (!Inserted)
+              State.SkipWithError("Failed to insert e new element");
+          }
+#endif
+        }
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode(),
+                             Order::value == ::Order::Random ? Shuffle::Keys
+                                                             : Shuffle::None,
+                             1000);
+      State.ResumeTiming();
+    }
+  }
+
+  std::string name() const {
+    return "BM_Insert" + baseName() + Mode::name() + Order::name();
+  }
+};
+
+template <class Mode, class Hint>
+struct InsertHint : Base {
+  using Base::Base;
+
+  template < ::Hint hint>
+  typename std::enable_if<hint == ::Hint::Correct>::type
+  run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (size_t I = 0; I < Data.Maps.size(); ++I) {
+        auto& Map = Data.Maps[I];
+        auto H = Data.Hints[I].begin();
+        for (auto K : Data.Keys) {
+#ifndef VALIDATE
+          benchmark::DoNotOptimize(Map.insert(*H, std::make_pair(K, 1)));
+#else
+          auto Inserted = Map.insert(*H, std::make_pair(K, 1));
+          if (Mode() == ::Mode::Hit) {
+            if (Inserted != *H)
+              State.SkipWithError("Inserted a duplicate element");
+          } else {
+            if (++Inserted != *H)
+              State.SkipWithError("Failed to insert a new element");
+          }
+#endif
+          ++H;
+        }
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+      State.ResumeTiming();
+    }
+  }
+
+  template < ::Hint hint>
+  typename std::enable_if<hint != ::Hint::Correct>::type
+  run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (size_t I = 0; I < Data.Maps.size(); ++I) {
+        auto& Map = Data.Maps[I];
+        auto Third = *(Data.Hints[I].begin() + 2);
+        for (auto K : Data.Keys) {
+          auto Itor = hint == ::Hint::Begin
+                          ? Map.begin()
+                          : hint == ::Hint::Third ? Third : Map.end();
+#ifndef VALIDATE
+          benchmark::DoNotOptimize(Map.insert(Itor, std::make_pair(K, 1)));
+#else
+          size_t Size = Map.size();
+          Map.insert(Itor, std::make_pair(K, 1));
+          if (Mode() == ::Mode::Hit) {
+            if (Size != Map.size())
+              State.SkipWithError("Inserted a duplicate element");
+          } else {
+            if (Size + 1 != Map.size())
+              State.SkipWithError("Failed to insert a new element");
+          }
+#endif
+        }
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+      State.ResumeTiming();
+    }
+  }
+
+  void run(benchmark::State& State) const {
+    static constexpr auto h = Hint();
+    run<h>(State);
+  }
+
+  std::string name() const {
+    return "BM_InsertHint" + baseName() + Mode::name() + Hint::name();
+  }
+};
+
+template <class Mode, class Order>
+struct InsertAssign : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(
+        MapSize, Mode(),
+        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (auto& Map : Data.Maps) {
+        for (auto K : Data.Keys) {
+#ifndef VALIDATE
+          benchmark::DoNotOptimize(Map.insert_or_assign(K, 1));
+#else
+          bool Inserted = Map.insert_or_assign(K, 1).second;
+          if (Mode() == ::Mode::Hit) {
+            if (Inserted)
+              State.SkipWithError("Inserted a duplicate element");
+          } else {
+            if (!Inserted)
+              State.SkipWithError("Failed to insert e new element");
+          }
+#endif
+        }
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode(),
+                             Order::value == ::Order::Random ? Shuffle::Keys
+                                                             : Shuffle::None,
+                             1000);
+      State.ResumeTiming();
+    }
+  }
+
+  std::string name() const {
+    return "BM_InsertAssign" + baseName() + Mode::name() + Order::name();
+  }
+};
+
+template <class Mode, class Hint>
+struct InsertAssignHint : Base {
+  using Base::Base;
+
+  template < ::Hint hint>
+  typename std::enable_if<hint == ::Hint::Correct>::type
+  run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (size_t I = 0; I < Data.Maps.size(); ++I) {
+        auto& Map = Data.Maps[I];
+        auto H = Data.Hints[I].begin();
+        for (auto K : Data.Keys) {
+#ifndef VALIDATE
+          benchmark::DoNotOptimize(Map.insert_or_assign(*H, K, 1));
+#else
+          auto Inserted = Map.insert_or_assign(*H, K, 1);
+          if (Mode() == ::Mode::Hit) {
+            if (Inserted != *H)
+              State.SkipWithError("Inserted a duplicate element");
+          } else {
+            if (++Inserted != *H)
+              State.SkipWithError("Failed to insert a new element");
+          }
+#endif
+          ++H;
+        }
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+      State.ResumeTiming();
+    }
+  }
+
+  template < ::Hint hint>
+  typename std::enable_if<hint != ::Hint::Correct>::type
+  run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (size_t I = 0; I < Data.Maps.size(); ++I) {
+        auto& Map = Data.Maps[I];
+        auto Third = *(Data.Hints[I].begin() + 2);
+        for (auto K : Data.Keys) {
+          auto Itor = hint == ::Hint::Begin
+                          ? Map.begin()
+                          : hint == ::Hint::Third ? Third : Map.end();
+#ifndef VALIDATE
+          benchmark::DoNotOptimize(Map.insert_or_assign(Itor, K, 1));
+#else
+          size_t Size = Map.size();
+          Map.insert_or_assign(Itor, K, 1);
+          if (Mode() == ::Mode::Hit) {
+            if (Size != Map.size())
+              State.SkipWithError("Inserted a duplicate element");
+          } else {
+            if (Size + 1 != Map.size())
+              State.SkipWithError("Failed to insert a new element");
+          }
+#endif
+        }
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+      State.ResumeTiming();
+    }
+  }
+
+  void run(benchmark::State& State) const {
+    static constexpr auto h = Hint();
+    run<h>(State);
+  }
+
+  std::string name() const {
+    return "BM_InsertAssignHint" + baseName() + Mode::name() + Hint::name();
+  }
+};
+
+template <class Mode, class Order>
+struct Emplace : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+
+    auto Data = makeTestingSets(
+        MapSize, Mode(),
+        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (auto& Map : Data.Maps) {
+        for (auto K : Data.Keys) {
+#ifndef VALIDATE
+          benchmark::DoNotOptimize(Map.emplace(K, 1));
+#else
+          bool Inserted = Map.emplace(K, 1).second;
+          if (Mode() == ::Mode::Hit) {
+            if (Inserted)
+              State.SkipWithError("Emplaced a duplicate element");
+          } else {
+            if (!Inserted)
+              State.SkipWithError("Failed to emplace a new element");
+          }
+#endif
+        }
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode(),
+                             Order::value == ::Order::Random ? Shuffle::Keys
+                                                             : Shuffle::None,
+                             1000);
+      State.ResumeTiming();
+    }
+  }
+
+  std::string name() const {
+    return "BM_Emplace" + baseName() + Mode::name() + Order::name();
+  }
+};
+
+template <class Mode, class Hint>
+struct EmplaceHint : Base {
+  using Base::Base;
+
+  template < ::Hint hint>
+  typename std::enable_if<hint == ::Hint::Correct>::type
+  run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (size_t I = 0; I < Data.Maps.size(); ++I) {
+        auto& Map = Data.Maps[I];
+        auto H = Data.Hints[I].begin();
+        for (auto K : Data.Keys) {
+#ifndef VALIDATE
+          benchmark::DoNotOptimize(Map.emplace_hint(*H, K, 1));
+#else
+          auto Inserted = Map.emplace_hint(*H, K, 1);
+          if (Mode() == ::Mode::Hit) {
+            if (Inserted != *H)
+              State.SkipWithError("Emplaced a duplicate element");
+          } else {
+            if (++Inserted != *H)
+              State.SkipWithError("Failed to emplace a new element");
+          }
+#endif
+          ++H;
+        }
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+      State.ResumeTiming();
+    }
+  }
+
+  template < ::Hint hint>
+  typename std::enable_if<hint != ::Hint::Correct>::type
+  run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (size_t I = 0; I < Data.Maps.size(); ++I) {
+        auto& Map = Data.Maps[I];
+        auto Third = *(Data.Hints[I].begin() + 2);
+        for (auto K : Data.Keys) {
+          auto Itor = hint == ::Hint::Begin
+                          ? Map.begin()
+                          : hint == ::Hint::Third ? Third : Map.end();
+#ifndef VALIDATE
+          benchmark::DoNotOptimize(Map.emplace_hint(Itor, K, 1));
+#else
+          size_t Size = Map.size();
+          Map.emplace_hint(Itor, K, 1);
+          if (Mode() == ::Mode::Hit) {
+            if (Size != Map.size())
+              State.SkipWithError("Emplaced a duplicate element");
+          } else {
+            if (Size + 1 != Map.size())
+              State.SkipWithError("Failed to emplace a new element");
+          }
+#endif
+        }
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+      State.ResumeTiming();
+    }
+  }
+
+  void run(benchmark::State& State) const {
+    static constexpr auto h = Hint();
+    run<h>(State);
+  }
+
+  std::string name() const {
+    return "BM_EmplaceHint" + baseName() + Mode::name() + Hint::name();
+  }
+};
+
+template <class Mode, class Order>
+struct TryEmplace : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+
+    auto Data = makeTestingSets(
+        MapSize, Mode(),
+        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (auto& Map : Data.Maps) {
+        for (auto K : Data.Keys) {
+#ifndef VALIDATE
+          benchmark::DoNotOptimize(Map.try_emplace(K, 1));
+#else
+          bool Inserted = Map.try_emplace(K, 1).second;
+          if (Mode() == ::Mode::Hit) {
+            if (Inserted)
+              State.SkipWithError("Emplaced a duplicate element");
+          } else {
+            if (!Inserted)
+              State.SkipWithError("Failed to emplace a new element");
+          }
+#endif
+        }
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode(),
+                             Order::value == ::Order::Random ? Shuffle::Keys
+                                                             : Shuffle::None,
+                             1000);
+      State.ResumeTiming();
+    }
+  }
+
+  std::string name() const {
+    return "BM_TryEmplace" + baseName() + Mode::name() + Order::name();
+  }
+};
+
+template <class Mode, class Hint>
+struct TryEmplaceHint : Base {
+  using Base::Base;
+
+  template < ::Hint hint>
+  typename std::enable_if<hint == ::Hint::Correct>::type
+  run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (size_t I = 0; I < Data.Maps.size(); ++I) {
+        auto& Map = Data.Maps[I];
+        auto H = Data.Hints[I].begin();
+        for (auto K : Data.Keys) {
+#ifndef VALIDATE
+          benchmark::DoNotOptimize(Map.try_emplace(*H, K, 1));
+#else
+          auto Inserted = Map.try_emplace(*H, K, 1);
+          if (Mode() == ::Mode::Hit) {
+            if (Inserted != *H)
+              State.SkipWithError("Emplaced a duplicate element");
+          } else {
+            if (++Inserted != *H)
+              State.SkipWithError("Failed to emplace a new element");
+          }
+#endif
+          ++H;
+        }
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+      State.ResumeTiming();
+    }
+  }
+
+  template < ::Hint hint>
+  typename std::enable_if<hint != ::Hint::Correct>::type
+  run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (size_t I = 0; I < Data.Maps.size(); ++I) {
+        auto& Map = Data.Maps[I];
+        auto Third = *(Data.Hints[I].begin() + 2);
+        for (auto K : Data.Keys) {
+          auto Itor = hint == ::Hint::Begin
+                          ? Map.begin()
+                          : hint == ::Hint::Third ? Third : Map.end();
+#ifndef VALIDATE
+          benchmark::DoNotOptimize(Map.try_emplace(Itor, K, 1));
+#else
+          size_t Size = Map.size();
+          Map.try_emplace(Itor, K, 1);
+          if (Mode() == ::Mode::Hit) {
+            if (Size != Map.size())
+              State.SkipWithError("Emplaced a duplicate element");
+          } else {
+            if (Size + 1 != Map.size())
+              State.SkipWithError("Failed to emplace a new element");
+          }
+#endif
+        }
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
+      State.ResumeTiming();
+    }
+  }
+
+  void run(benchmark::State& State) const {
+    static constexpr auto h = Hint();
+    run<h>(State);
+  }
+
+  std::string name() const {
+    return "BM_TryEmplaceHint" + baseName() + Mode::name() + Hint::name();
+  }
+};
+
+template <class Mode, class Order>
+struct Erase : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(
+        MapSize, Mode(),
+        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (auto& Map : Data.Maps) {
+        for (auto K : Data.Keys) {
+#ifndef VALIDATE
+          benchmark::DoNotOptimize(Map.erase(K));
+#else
+          size_t I = Map.erase(K);
+          if (Mode() == ::Mode::Hit) {
+            if (I == 0)
+              State.SkipWithError("Did not find the existing element");
+          } else {
+            if (I == 1)
+              State.SkipWithError("Did find the non-existing element");
+          }
+#endif
+        }
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode(),
+                             Order::value == ::Order::Random ? Shuffle::Keys
+                                                             : Shuffle::None,
+                             1000);
+      State.ResumeTiming();
+    }
+  }
+
+  std::string name() const {
+    return "BM_Erase" + baseName() + Mode::name() + Order::name();
+  }
+};
+
+template <class Order>
+struct EraseIterator : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(
+        MapSize, Mode::Hit,
+        Order::value == ::Order::Random ? Shuffle::Hints : Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (size_t I = 0; I < Data.Maps.size(); ++I) {
+        auto& Map = Data.Maps[I];
+        for (auto H : Data.Hints[I]) {
+          benchmark::DoNotOptimize(Map.erase(H));
+        }
+#ifdef VALIDATE
+        if (!Map.empty())
+          State.SkipWithError("Did not erase the entire map");
+#endif
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode::Hit,
+                             Order::value == ::Order::Random ? Shuffle::Hints
+                                                             : Shuffle::None,
+                             1000);
+      State.ResumeTiming();
+    }
+  }
+
+  std::string name() const {
+    return "BM_EraseIterator" + baseName() + Order::name();
+  }
+};
+
+struct EraseRange : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
+    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
+      for (auto& Map : Data.Maps) {
+#ifndef VALIDATE
+        benchmark::DoNotOptimize(Map.erase(Map.begin(), Map.end()));
+#else
+        Map.erase(Map.begin(), Map.end());
+        if (!Map.empty())
+          State.SkipWithError("Did not erase the entire map");
+#endif
+      }
+
+      State.PauseTiming();
+      Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
+      State.ResumeTiming();
+    }
+  }
+
+  std::string name() const { return "BM_EraseRange" + baseName(); }
+};
+
+//*******************************************************************|
+//                            Lookup                                 |
+//*******************************************************************|
+
+template <class Mode, class Order>
+struct Count : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(
+        MapSize, Mode(),
+        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
+    auto& Map = Data.Maps.front();
+    while (State.KeepRunningBatch(MapSize)) {
+      for (auto K : Data.Keys) {
+#ifndef VALIDATE
+        benchmark::DoNotOptimize(Map.count(K));
+#else
+        size_t I = Map.count(K);
+        if (Mode() == ::Mode::Hit) {
+          if (I == 0)
+            State.SkipWithError("Did not find the existing element");
+        } else {
+          if (I == 1)
+            State.SkipWithError("Did find the non-existing element");
+        }
+#endif
+      }
+    }
+  }
+
+  std::string name() const {
+    return "BM_Count" + baseName() + Mode::name() + Order::name();
+  }
+};
+
+template <class Mode, class Order>
+struct Find : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(
+        MapSize, Mode(),
+        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
+    auto& Map = Data.Maps.front();
+    while (State.KeepRunningBatch(MapSize)) {
+      for (auto K : Data.Keys) {
+#ifndef VALIDATE
+        benchmark::DoNotOptimize(Map.find(K));
+#else
+        auto Itor = Map.find(K);
+        if (Mode() == ::Mode::Hit) {
+          if (Itor == Map.end())
+            State.SkipWithError("Did not find the existing element");
+        } else {
+          if (Itor != Map.end())
+            State.SkipWithError("Did find the non-existing element");
+        }
+#endif
+      }
+    }
+  }
+
+  std::string name() const {
+    return "BM_Find" + baseName() + Mode::name() + Order::name();
+  }
+};
+
+template <class Mode, class Order>
+struct EqualRange : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(
+        MapSize, Mode(),
+        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
+    auto& Map = Data.Maps.front();
+    while (State.KeepRunningBatch(MapSize)) {
+      for (auto K : Data.Keys) {
+#ifndef VALIDATE
+        benchmark::DoNotOptimize(Map.equal_range(K));
+#else
+        auto Range = Map.equal_range(K);
+        if (Mode() == ::Mode::Hit) {
+          // Adjust validation for the last element.
+          auto Key = K;
+          if (Range.second == Map.end() && K == 2 * MapSize) {
+            --Range.second;
+            Key -= 2;
+          }
+          if (Range.first == Map.end() || Range.first->first != K ||
+              Range.second == Map.end() || Range.second->first - 2 != Key)
+            State.SkipWithError("Did not find the existing element");
+        } else {
+          if (Range.first == Map.end() || Range.first->first - 1 != K ||
+              Range.second == Map.end() || Range.second->first - 1 != K)
+            State.SkipWithError("Did find the non-existing element");
+        }
+#endif
+      }
+    }
+  }
+
+  std::string name() const {
+    return "BM_EqualRange" + baseName() + Mode::name() + Order::name();
+  }
+};
+
+template <class Mode, class Order>
+struct LowerBound : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(
+        MapSize, Mode(),
+        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
+    auto& Map = Data.Maps.front();
+    while (State.KeepRunningBatch(MapSize)) {
+      for (auto K : Data.Keys) {
+#ifndef VALIDATE
+        benchmark::DoNotOptimize(Map.lower_bound(K));
+#else
+        auto Itor = Map.lower_bound(K);
+        if (Mode() == ::Mode::Hit) {
+          if (Itor == Map.end() || Itor->first != K)
+            State.SkipWithError("Did not find the existing element");
+        } else {
+          if (Itor == Map.end() || Itor->first - 1 != K)
+            State.SkipWithError("Did find the non-existing element");
+        }
+#endif
+      }
+    }
+  }
+
+  std::string name() const {
+    return "BM_LowerBound" + baseName() + Mode::name() + Order::name();
+  }
+};
+
+template <class Mode, class Order>
+struct UpperBound : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(
+        MapSize, Mode(),
+        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
+    auto& Map = Data.Maps.front();
+    while (State.KeepRunningBatch(MapSize)) {
+      for (auto K : Data.Keys) {
+#ifndef VALIDATE
+        benchmark::DoNotOptimize(Map.upper_bound(K));
+#else
+        std::map<uint64_t, int64_t>::iterator Itor = Map.upper_bound(K);
+        if (Mode() == ::Mode::Hit) {
+          // Adjust validation for the last element.
+          auto Key = K;
+          if (Itor == Map.end() && K == 2 * MapSize) {
+            --Itor;
+            Key -= 2;
+          }
+          if (Itor == Map.end() || Itor->first - 2 != Key)
+            State.SkipWithError("Did not find the existing element");
+        } else {
+          if (Itor == Map.end() || Itor->first - 1 != K)
+            State.SkipWithError("Did find the non-existing element");
+        }
+#endif
+      }
+    }
+  }
+
+  std::string name() const {
+    return "BM_UpperBound" + baseName() + Mode::name() + Order::name();
+  }
+};
+
+} // namespace
+
+int main(int argc, char** argv) {
+  benchmark::Initialize(&argc, argv);
+  if (benchmark::ReportUnrecognizedArguments(argc, argv))
+    return 1;
+
+#ifdef VALIDATE
+  const std::vector<size_t> MapSize{10};
+#else
+  const std::vector<size_t> MapSize{10, 100, 1000, 10000, 100000, 1000000};
+#endif
+
+  // Member functions
+  makeCartesianProductBenchmark<ConstructorDefault>();
+  makeCartesianProductBenchmark<ConstructorIterator>(MapSize);
+  makeCartesianProductBenchmark<ConstructorCopy>(MapSize);
+  makeCartesianProductBenchmark<ConstructorMove>(MapSize);
+
+  // Capacity
+  makeCartesianProductBenchmark<Empty>(MapSize);
+  makeCartesianProductBenchmark<Size>(MapSize);
+
+  // Modifiers
+  makeCartesianProductBenchmark<Clear>(MapSize);
+  makeCartesianProductBenchmark<Insert, AllModes, AllOrders>(MapSize);
+  makeCartesianProductBenchmark<InsertHint, AllModes, AllHints>(MapSize);
+  makeCartesianProductBenchmark<InsertAssign, AllModes, AllOrders>(MapSize);
+  makeCartesianProductBenchmark<InsertAssignHint, AllModes, AllHints>(MapSize);
+
+  makeCartesianProductBenchmark<Emplace, AllModes, AllOrders>(MapSize);
+  makeCartesianProductBenchmark<EmplaceHint, AllModes, AllHints>(MapSize);
+  makeCartesianProductBenchmark<TryEmplace, AllModes, AllOrders>(MapSize);
+  makeCartesianProductBenchmark<TryEmplaceHint, AllModes, AllHints>(MapSize);
+  makeCartesianProductBenchmark<Erase, AllModes, AllOrders>(MapSize);
+  makeCartesianProductBenchmark<EraseIterator, AllOrders>(MapSize);
+  makeCartesianProductBenchmark<EraseRange>(MapSize);
+
+  // Lookup
+  makeCartesianProductBenchmark<Count, AllModes, AllOrders>(MapSize);
+  makeCartesianProductBenchmark<Find, AllModes, AllOrders>(MapSize);
+  makeCartesianProductBenchmark<EqualRange, AllModes, AllOrders>(MapSize);
+  makeCartesianProductBenchmark<LowerBound, AllModes, AllOrders>(MapSize);
+  makeCartesianProductBenchmark<UpperBound, AllModes, AllOrders>(MapSize);
+
+  benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/benchmarks/ordered_set.bench.cpp b/benchmarks/ordered_set.bench.cpp
new file mode 100644
index 0000000..a9d9c92
--- /dev/null
+++ b/benchmarks/ordered_set.bench.cpp
@@ -0,0 +1,248 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <random>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "CartesianBenchmarks.h"
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
+
+namespace {
+
+enum class HitType { Hit, Miss };
+
+struct AllHitTypes : EnumValuesAsTuple<AllHitTypes, HitType, 2> {
+  static constexpr const char* Names[] = {"Hit", "Miss"};
+};
+
+enum class AccessPattern { Ordered, Random };
+
+struct AllAccessPattern
+    : EnumValuesAsTuple<AllAccessPattern, AccessPattern, 2> {
+  static constexpr const char* Names[] = {"Ordered", "Random"};
+};
+
+void sortKeysBy(std::vector<uint64_t>& Keys, AccessPattern AP) {
+  if (AP == AccessPattern::Random) {
+    std::random_device R;
+    std::mt19937 M(R());
+    std::shuffle(std::begin(Keys), std::end(Keys), M);
+  }
+}
+
+struct TestSets {
+  std::vector<std::set<uint64_t> > Sets;
+  std::vector<uint64_t> Keys;
+};
+
+TestSets makeTestingSets(size_t TableSize, size_t NumTables, HitType Hit,
+                         AccessPattern Access) {
+  TestSets R;
+  R.Sets.resize(1);
+
+  for (uint64_t I = 0; I < TableSize; ++I) {
+    R.Sets[0].insert(2 * I);
+    R.Keys.push_back(Hit == HitType::Hit ? 2 * I : 2 * I + 1);
+  }
+  R.Sets.resize(NumTables, R.Sets[0]);
+  sortKeysBy(R.Keys, Access);
+
+  return R;
+}
+
+struct Base {
+  size_t TableSize;
+  size_t NumTables;
+  Base(size_t T, size_t N) : TableSize(T), NumTables(N) {}
+
+  bool skip() const {
+    size_t Total = TableSize * NumTables;
+    return Total < 100 || Total > 1000000;
+  }
+
+  std::string baseName() const {
+    return "_TableSize" + std::to_string(TableSize) + "_NumTables" +
+           std::to_string(NumTables);
+  }
+};
+
+template <class Access>
+struct Create : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    std::vector<uint64_t> Keys(TableSize);
+    std::iota(Keys.begin(), Keys.end(), uint64_t{0});
+    sortKeysBy(Keys, Access());
+
+    while (State.KeepRunningBatch(TableSize * NumTables)) {
+      std::vector<std::set<uint64_t>> Sets(NumTables);
+      for (auto K : Keys) {
+        for (auto& Set : Sets) {
+          benchmark::DoNotOptimize(Set.insert(K));
+        }
+      }
+    }
+  }
+
+  std::string name() const {
+    return "BM_Create" + Access::name() + baseName();
+  }
+};
+
+template <class Hit, class Access>
+struct Find : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(TableSize, NumTables, Hit(), Access());
+
+    while (State.KeepRunningBatch(TableSize * NumTables)) {
+      for (auto K : Data.Keys) {
+        for (auto& Set : Data.Sets) {
+          benchmark::DoNotOptimize(Set.find(K));
+        }
+      }
+    }
+  }
+
+  std::string name() const {
+    return "BM_Find" + Hit::name() + Access::name() + baseName();
+  }
+};
+
+template <class Hit, class Access>
+struct FindNeEnd : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(TableSize, NumTables, Hit(), Access());
+
+    while (State.KeepRunningBatch(TableSize * NumTables)) {
+      for (auto K : Data.Keys) {
+        for (auto& Set : Data.Sets) {
+          benchmark::DoNotOptimize(Set.find(K) != Set.end());
+        }
+      }
+    }
+  }
+
+  std::string name() const {
+    return "BM_FindNeEnd" + Hit::name() + Access::name() + baseName();
+  }
+};
+
+template <class Access>
+struct InsertHit : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(TableSize, NumTables, HitType::Hit, Access());
+
+    while (State.KeepRunningBatch(TableSize * NumTables)) {
+      for (auto K : Data.Keys) {
+        for (auto& Set : Data.Sets) {
+          benchmark::DoNotOptimize(Set.insert(K));
+        }
+      }
+    }
+  }
+
+  std::string name() const {
+    return "BM_InsertHit" + Access::name() + baseName();
+  }
+};
+
+template <class Access>
+struct InsertMissAndErase : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss, Access());
+
+    while (State.KeepRunningBatch(TableSize * NumTables)) {
+      for (auto K : Data.Keys) {
+        for (auto& Set : Data.Sets) {
+          benchmark::DoNotOptimize(Set.erase(Set.insert(K).first));
+        }
+      }
+    }
+  }
+
+  std::string name() const {
+    return "BM_InsertMissAndErase" + Access::name() + baseName();
+  }
+};
+
+struct IterateRangeFor : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss,
+                                AccessPattern::Ordered);
+
+    while (State.KeepRunningBatch(TableSize * NumTables)) {
+      for (auto& Set : Data.Sets) {
+        for (auto& V : Set) {
+          benchmark::DoNotOptimize(V);
+        }
+      }
+    }
+  }
+
+  std::string name() const { return "BM_IterateRangeFor" + baseName(); }
+};
+
+struct IterateBeginEnd : Base {
+  using Base::Base;
+
+  void run(benchmark::State& State) const {
+    auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss,
+                                AccessPattern::Ordered);
+
+    while (State.KeepRunningBatch(TableSize * NumTables)) {
+      for (auto& Set : Data.Sets) {
+        for (auto it = Set.begin(); it != Set.end(); ++it) {
+          benchmark::DoNotOptimize(*it);
+        }
+      }
+    }
+  }
+
+  std::string name() const { return "BM_IterateBeginEnd" + baseName(); }
+};
+
+}  // namespace
+
+int main(int argc, char** argv) {
+  benchmark::Initialize(&argc, argv);
+  if (benchmark::ReportUnrecognizedArguments(argc, argv))
+    return 1;
+
+  const std::vector<size_t> TableSize{1, 10, 100, 1000, 10000, 100000, 1000000};
+  const std::vector<size_t> NumTables{1, 10, 100, 1000, 10000, 100000, 1000000};
+
+  makeCartesianProductBenchmark<Create, AllAccessPattern>(TableSize, NumTables);
+  makeCartesianProductBenchmark<Find, AllHitTypes, AllAccessPattern>(
+      TableSize, NumTables);
+  makeCartesianProductBenchmark<FindNeEnd, AllHitTypes, AllAccessPattern>(
+      TableSize, NumTables);
+  makeCartesianProductBenchmark<InsertHit, AllAccessPattern>(
+      TableSize, NumTables);
+  makeCartesianProductBenchmark<InsertMissAndErase, AllAccessPattern>(
+      TableSize, NumTables);
+  makeCartesianProductBenchmark<IterateRangeFor>(TableSize, NumTables);
+  makeCartesianProductBenchmark<IterateBeginEnd>(TableSize, NumTables);
+  benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/benchmarks/string.bench.cpp b/benchmarks/string.bench.cpp
new file mode 100644
index 0000000..e43ad32
--- /dev/null
+++ b/benchmarks/string.bench.cpp
@@ -0,0 +1,628 @@
+
+#include <cstdint>
+#include <new>
+#include <vector>
+
+#include "CartesianBenchmarks.h"
+#include "GenerateInput.h"
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
+
+constexpr std::size_t MAX_STRING_LEN = 8 << 14;
+
+// Benchmark when there is no match.
+static void BM_StringFindNoMatch(benchmark::State &state) {
+  std::string s1(state.range(0), '-');
+  std::string s2(8, '*');
+  for (auto _ : state)
+    benchmark::DoNotOptimize(s1.find(s2));
+}
+BENCHMARK(BM_StringFindNoMatch)->Range(10, MAX_STRING_LEN);
+
+// Benchmark when the string matches first time.
+static void BM_StringFindAllMatch(benchmark::State &state) {
+  std::string s1(MAX_STRING_LEN, '-');
+  std::string s2(state.range(0), '-');
+  for (auto _ : state)
+    benchmark::DoNotOptimize(s1.find(s2));
+}
+BENCHMARK(BM_StringFindAllMatch)->Range(1, MAX_STRING_LEN);
+
+// Benchmark when the string matches somewhere in the end.
+static void BM_StringFindMatch1(benchmark::State &state) {
+  std::string s1(MAX_STRING_LEN / 2, '*');
+  s1 += std::string(state.range(0), '-');
+  std::string s2(state.range(0), '-');
+  for (auto _ : state)
+    benchmark::DoNotOptimize(s1.find(s2));
+}
+BENCHMARK(BM_StringFindMatch1)->Range(1, MAX_STRING_LEN / 4);
+
+// Benchmark when the string matches somewhere from middle to the end.
+static void BM_StringFindMatch2(benchmark::State &state) {
+  std::string s1(MAX_STRING_LEN / 2, '*');
+  s1 += std::string(state.range(0), '-');
+  s1 += std::string(state.range(0), '*');
+  std::string s2(state.range(0), '-');
+  for (auto _ : state)
+    benchmark::DoNotOptimize(s1.find(s2));
+}
+BENCHMARK(BM_StringFindMatch2)->Range(1, MAX_STRING_LEN / 4);
+
+static void BM_StringCtorDefault(benchmark::State &state) {
+  for (auto _ : state) {
+    std::string Default;
+    benchmark::DoNotOptimize(Default);
+  }
+}
+BENCHMARK(BM_StringCtorDefault);
+
+enum class Length { Empty, Small, Large, Huge };
+struct AllLengths : EnumValuesAsTuple<AllLengths, Length, 4> {
+  static constexpr const char* Names[] = {"Empty", "Small", "Large", "Huge"};
+};
+
+enum class Opacity { Opaque, Transparent };
+struct AllOpacity : EnumValuesAsTuple<AllOpacity, Opacity, 2> {
+  static constexpr const char* Names[] = {"Opaque", "Transparent"};
+};
+
+enum class DiffType { Control, ChangeFirst, ChangeMiddle, ChangeLast };
+struct AllDiffTypes : EnumValuesAsTuple<AllDiffTypes, DiffType, 4> {
+  static constexpr const char* Names[] = {"Control", "ChangeFirst",
+                                          "ChangeMiddle", "ChangeLast"};
+};
+
+static constexpr char SmallStringLiteral[] = "012345678";
+
+TEST_ALWAYS_INLINE const char* getSmallString(DiffType D) {
+  switch (D) {
+    case DiffType::Control:
+      return SmallStringLiteral;
+    case DiffType::ChangeFirst:
+      return "-12345678";
+    case DiffType::ChangeMiddle:
+      return "0123-5678";
+    case DiffType::ChangeLast:
+      return "01234567-";
+  }
+}
+
+static constexpr char LargeStringLiteral[] =
+    "012345678901234567890123456789012345678901234567890123456789012";
+
+TEST_ALWAYS_INLINE const char* getLargeString(DiffType D) {
+#define LARGE_STRING_FIRST "123456789012345678901234567890"
+#define LARGE_STRING_SECOND "234567890123456789012345678901"
+  switch (D) {
+    case DiffType::Control:
+      return "0" LARGE_STRING_FIRST "1" LARGE_STRING_SECOND "2";
+    case DiffType::ChangeFirst:
+      return "-" LARGE_STRING_FIRST "1" LARGE_STRING_SECOND "2";
+    case DiffType::ChangeMiddle:
+      return "0" LARGE_STRING_FIRST "-" LARGE_STRING_SECOND "2";
+    case DiffType::ChangeLast:
+      return "0" LARGE_STRING_FIRST "1" LARGE_STRING_SECOND "-";
+  }
+}
+
+TEST_ALWAYS_INLINE const char* getHugeString(DiffType D) {
+#define HUGE_STRING0 "0123456789"
+#define HUGE_STRING1 HUGE_STRING0 HUGE_STRING0 HUGE_STRING0 HUGE_STRING0
+#define HUGE_STRING2 HUGE_STRING1 HUGE_STRING1 HUGE_STRING1 HUGE_STRING1
+#define HUGE_STRING3 HUGE_STRING2 HUGE_STRING2 HUGE_STRING2 HUGE_STRING2
+#define HUGE_STRING4 HUGE_STRING3 HUGE_STRING3 HUGE_STRING3 HUGE_STRING3
+  switch (D) {
+    case DiffType::Control:
+      return "0123456789" HUGE_STRING4 "0123456789" HUGE_STRING4 "0123456789";
+    case DiffType::ChangeFirst:
+      return "-123456789" HUGE_STRING4 "0123456789" HUGE_STRING4 "0123456789";
+    case DiffType::ChangeMiddle:
+      return "0123456789" HUGE_STRING4 "01234-6789" HUGE_STRING4 "0123456789";
+    case DiffType::ChangeLast:
+      return "0123456789" HUGE_STRING4 "0123456789" HUGE_STRING4 "012345678-";
+  }
+}
+
+TEST_ALWAYS_INLINE const char* getString(Length L,
+                                         DiffType D = DiffType::Control) {
+  switch (L) {
+  case Length::Empty:
+    return "";
+  case Length::Small:
+    return getSmallString(D);
+  case Length::Large:
+    return getLargeString(D);
+  case Length::Huge:
+    return getHugeString(D);
+  }
+}
+
+TEST_ALWAYS_INLINE std::string makeString(Length L,
+                                          DiffType D = DiffType::Control,
+                                          Opacity O = Opacity::Transparent) {
+  switch (L) {
+  case Length::Empty:
+    return maybeOpaque("", O == Opacity::Opaque);
+  case Length::Small:
+    return maybeOpaque(getSmallString(D), O == Opacity::Opaque);
+  case Length::Large:
+    return maybeOpaque(getLargeString(D), O == Opacity::Opaque);
+  case Length::Huge:
+    return maybeOpaque(getHugeString(D), O == Opacity::Opaque);
+  }
+}
+
+template <class Length, class Opaque>
+struct StringConstructDestroyCStr {
+  static void run(benchmark::State& state) {
+    for (auto _ : state) {
+      benchmark::DoNotOptimize(
+          makeString(Length(), DiffType::Control, Opaque()));
+    }
+  }
+
+  static std::string name() {
+    return "BM_StringConstructDestroyCStr" + Length::name() + Opaque::name();
+  }
+};
+
+template <class Length, bool MeasureCopy, bool MeasureDestroy>
+static void StringCopyAndDestroy(benchmark::State& state) {
+  static constexpr size_t NumStrings = 1024;
+  auto Orig = makeString(Length());
+  std::aligned_storage<sizeof(std::string)>::type Storage[NumStrings];
+
+  while (state.KeepRunningBatch(NumStrings)) {
+    if (!MeasureCopy)
+      state.PauseTiming();
+    for (size_t I = 0; I < NumStrings; ++I) {
+      ::new (static_cast<void*>(Storage + I)) std::string(Orig);
+    }
+    if (!MeasureCopy)
+      state.ResumeTiming();
+    if (!MeasureDestroy)
+      state.PauseTiming();
+    for (size_t I = 0; I < NumStrings; ++I) {
+      using S = std::string;
+      reinterpret_cast<S*>(Storage + I)->~S();
+    }
+    if (!MeasureDestroy)
+      state.ResumeTiming();
+  }
+}
+
+template <class Length>
+struct StringCopy {
+  static void run(benchmark::State& state) {
+    StringCopyAndDestroy<Length, true, false>(state);
+  }
+
+  static std::string name() { return "BM_StringCopy" + Length::name(); }
+};
+
+template <class Length>
+struct StringDestroy {
+  static void run(benchmark::State& state) {
+    StringCopyAndDestroy<Length, false, true>(state);
+  }
+
+  static std::string name() { return "BM_StringDestroy" + Length::name(); }
+};
+
+template <class Length>
+struct StringMove {
+  static void run(benchmark::State& state) {
+    // Keep two object locations and move construct back and forth.
+    std::aligned_storage<sizeof(std::string), alignof(std::string)>::type Storage[2];
+    using S = std::string;
+    size_t I = 0;
+    S *newS = new (static_cast<void*>(Storage)) std::string(makeString(Length()));
+    for (auto _ : state) {
+      // Switch locations.
+      I ^= 1;
+      benchmark::DoNotOptimize(Storage);
+      // Move construct into the new location,
+      S *tmpS = new (static_cast<void*>(Storage + I)) S(std::move(*newS));
+      // then destroy the old one.
+      newS->~S();
+      newS = tmpS;
+    }
+    newS->~S();
+  }
+
+  static std::string name() { return "BM_StringMove" + Length::name(); }
+};
+
+template <class Length, class Opaque>
+struct StringResizeDefaultInit {
+  static void run(benchmark::State& state) {
+    constexpr bool opaque = Opaque{} == Opacity::Opaque;
+    constexpr int kNumStrings = 4 << 10;
+    size_t length = makeString(Length()).size();
+    std::string strings[kNumStrings];
+    while (state.KeepRunningBatch(kNumStrings)) {
+      state.PauseTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        std::string().swap(strings[i]);
+      }
+      benchmark::DoNotOptimize(strings);
+      state.ResumeTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        strings[i].__resize_default_init(maybeOpaque(length, opaque));
+      }
+    }
+  }
+
+  static std::string name() {
+    return "BM_StringResizeDefaultInit" + Length::name() + Opaque::name();
+  }
+};
+
+template <class Length, class Opaque>
+struct StringAssignStr {
+  static void run(benchmark::State& state) {
+    constexpr bool opaque = Opaque{} == Opacity::Opaque;
+    constexpr int kNumStrings = 4 << 10;
+    std::string src = makeString(Length());
+    std::string strings[kNumStrings];
+    while (state.KeepRunningBatch(kNumStrings)) {
+      state.PauseTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        std::string().swap(strings[i]);
+      }
+      benchmark::DoNotOptimize(strings);
+      state.ResumeTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        strings[i] = *maybeOpaque(&src, opaque);
+      }
+    }
+  }
+
+  static std::string name() {
+    return "BM_StringAssignStr" + Length::name() + Opaque::name();
+  }
+};
+
+template <class Length, class Opaque>
+struct StringAssignAsciiz {
+  static void run(benchmark::State& state) {
+    constexpr bool opaque = Opaque{} == Opacity::Opaque;
+    constexpr int kNumStrings = 4 << 10;
+    std::string strings[kNumStrings];
+    while (state.KeepRunningBatch(kNumStrings)) {
+      state.PauseTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        std::string().swap(strings[i]);
+      }
+      benchmark::DoNotOptimize(strings);
+      state.ResumeTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        strings[i] = maybeOpaque(getString(Length()), opaque);
+      }
+    }
+  }
+
+  static std::string name() {
+    return "BM_StringAssignAsciiz" + Length::name() + Opaque::name();
+  }
+};
+
+template <class Length, class Opaque>
+struct StringEraseToEnd {
+  static void run(benchmark::State& state) {
+    constexpr bool opaque = Opaque{} == Opacity::Opaque;
+    constexpr int kNumStrings = 4 << 10;
+    std::string strings[kNumStrings];
+    const int mid = makeString(Length()).size() / 2;
+    while (state.KeepRunningBatch(kNumStrings)) {
+      state.PauseTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        strings[i] = makeString(Length());
+      }
+      benchmark::DoNotOptimize(strings);
+      state.ResumeTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        strings[i].erase(maybeOpaque(mid, opaque),
+                         maybeOpaque(std::string::npos, opaque));
+      }
+    }
+  }
+
+  static std::string name() {
+    return "BM_StringEraseToEnd" + Length::name() + Opaque::name();
+  }
+};
+
+template <class Length, class Opaque>
+struct StringEraseWithMove {
+  static void run(benchmark::State& state) {
+    constexpr bool opaque = Opaque{} == Opacity::Opaque;
+    constexpr int kNumStrings = 4 << 10;
+    std::string strings[kNumStrings];
+    const int n = makeString(Length()).size() / 2;
+    const int pos = n / 2;
+    while (state.KeepRunningBatch(kNumStrings)) {
+      state.PauseTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        strings[i] = makeString(Length());
+      }
+      benchmark::DoNotOptimize(strings);
+      state.ResumeTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        strings[i].erase(maybeOpaque(pos, opaque), maybeOpaque(n, opaque));
+      }
+    }
+  }
+
+  static std::string name() {
+    return "BM_StringEraseWithMove" + Length::name() + Opaque::name();
+  }
+};
+
+template <class Opaque>
+struct StringAssignAsciizMix {
+  static void run(benchmark::State& state) {
+    constexpr auto O = Opaque{};
+    constexpr auto D = DiffType::Control;
+    constexpr int kNumStrings = 4 << 10;
+    std::string strings[kNumStrings];
+    while (state.KeepRunningBatch(kNumStrings)) {
+      state.PauseTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        std::string().swap(strings[i]);
+      }
+      benchmark::DoNotOptimize(strings);
+      state.ResumeTiming();
+      for (int i = 0; i < kNumStrings - 7; i += 8) {
+        strings[i + 0] = maybeOpaque(getSmallString(D), O == Opacity::Opaque);
+        strings[i + 1] = maybeOpaque(getSmallString(D), O == Opacity::Opaque);
+        strings[i + 2] = maybeOpaque(getLargeString(D), O == Opacity::Opaque);
+        strings[i + 3] = maybeOpaque(getSmallString(D), O == Opacity::Opaque);
+        strings[i + 4] = maybeOpaque(getSmallString(D), O == Opacity::Opaque);
+        strings[i + 5] = maybeOpaque(getSmallString(D), O == Opacity::Opaque);
+        strings[i + 6] = maybeOpaque(getLargeString(D), O == Opacity::Opaque);
+        strings[i + 7] = maybeOpaque(getSmallString(D), O == Opacity::Opaque);
+      }
+    }
+  }
+
+  static std::string name() {
+    return "BM_StringAssignAsciizMix" + Opaque::name();
+  }
+};
+
+enum class Relation { Eq, Less, Compare };
+struct AllRelations : EnumValuesAsTuple<AllRelations, Relation, 3> {
+  static constexpr const char* Names[] = {"Eq", "Less", "Compare"};
+};
+
+template <class Rel, class LHLength, class RHLength, class DiffType>
+struct StringRelational {
+  static void run(benchmark::State& state) {
+    auto Lhs = makeString(RHLength());
+    auto Rhs = makeString(LHLength(), DiffType());
+    for (auto _ : state) {
+      benchmark::DoNotOptimize(Lhs);
+      benchmark::DoNotOptimize(Rhs);
+      switch (Rel()) {
+      case Relation::Eq:
+        benchmark::DoNotOptimize(Lhs == Rhs);
+        break;
+      case Relation::Less:
+        benchmark::DoNotOptimize(Lhs < Rhs);
+        break;
+      case Relation::Compare:
+        benchmark::DoNotOptimize(Lhs.compare(Rhs));
+        break;
+      }
+    }
+  }
+
+  static bool skip() {
+    // Eq is commutative, so skip half the matrix.
+    if (Rel() == Relation::Eq && LHLength() > RHLength())
+      return true;
+    // We only care about control when the lengths differ.
+    if (LHLength() != RHLength() && DiffType() != ::DiffType::Control)
+      return true;
+    // For empty, only control matters.
+    if (LHLength() == Length::Empty && DiffType() != ::DiffType::Control)
+      return true;
+    return false;
+  }
+
+  static std::string name() {
+    return "BM_StringRelational" + Rel::name() + LHLength::name() +
+           RHLength::name() + DiffType::name();
+  }
+};
+
+template <class Rel, class LHLength, class RHLength, class DiffType>
+struct StringRelationalLiteral {
+  static void run(benchmark::State& state) {
+    auto Lhs = makeString(LHLength(), DiffType());
+    for (auto _ : state) {
+      benchmark::DoNotOptimize(Lhs);
+      constexpr const char* Literal = RHLength::value == Length::Empty
+                                          ? ""
+                                          : RHLength::value == Length::Small
+                                                ? SmallStringLiteral
+                                                : LargeStringLiteral;
+      switch (Rel()) {
+      case Relation::Eq:
+        benchmark::DoNotOptimize(Lhs == Literal);
+        break;
+      case Relation::Less:
+        benchmark::DoNotOptimize(Lhs < Literal);
+        break;
+      case Relation::Compare:
+        benchmark::DoNotOptimize(Lhs.compare(Literal));
+        break;
+      }
+    }
+  }
+
+  static bool skip() {
+    // Doesn't matter how they differ if they have different size.
+    if (LHLength() != RHLength() && DiffType() != ::DiffType::Control)
+      return true;
+    // We don't need huge. Doensn't give anything different than Large.
+    if (LHLength() == Length::Huge || RHLength() == Length::Huge)
+      return true;
+    return false;
+  }
+
+  static std::string name() {
+    return "BM_StringRelationalLiteral" + Rel::name() + LHLength::name() +
+           RHLength::name() + DiffType::name();
+  }
+};
+
+enum class Depth { Shallow, Deep };
+struct AllDepths : EnumValuesAsTuple<AllDepths, Depth, 2> {
+  static constexpr const char* Names[] = {"Shallow", "Deep"};
+};
+
+enum class Temperature { Hot, Cold };
+struct AllTemperatures : EnumValuesAsTuple<AllTemperatures, Temperature, 2> {
+  static constexpr const char* Names[] = {"Hot", "Cold"};
+};
+
+template <class Temperature, class Depth, class Length>
+struct StringRead {
+  void run(benchmark::State& state) const {
+    static constexpr size_t NumStrings =
+        Temperature() == ::Temperature::Hot
+            ? 1 << 10
+            : /* Enough strings to overflow the cache */ 1 << 20;
+    static_assert((NumStrings & (NumStrings - 1)) == 0,
+                  "NumStrings should be a power of two to reduce overhead.");
+
+    std::vector<std::string> Values(NumStrings, makeString(Length()));
+    size_t I = 0;
+    for (auto _ : state) {
+      // Jump long enough to defeat cache locality, and use a value that is
+      // coprime with NumStrings to ensure we visit every element.
+      I = (I + 17) % NumStrings;
+      const auto& V = Values[I];
+
+      // Read everything first. Escaping data() through DoNotOptimize might
+      // cause the compiler to have to recalculate information about `V` due to
+      // aliasing.
+      const char* const Data = V.data();
+      const size_t Size = V.size();
+      benchmark::DoNotOptimize(Data);
+      benchmark::DoNotOptimize(Size);
+      if (Depth() == ::Depth::Deep) {
+        // Read into the payload. This mainly shows the benefit of SSO when the
+        // data is cold.
+        benchmark::DoNotOptimize(*Data);
+      }
+    }
+  }
+
+  static bool skip() {
+    // Huge does not give us anything that Large doesn't have. Skip it.
+    if (Length() == ::Length::Huge) {
+      return true;
+    }
+    return false;
+  }
+
+  std::string name() const {
+    return "BM_StringRead" + Temperature::name() + Depth::name() +
+           Length::name();
+  }
+};
+
+void sanityCheckGeneratedStrings() {
+  for (auto Lhs : {Length::Empty, Length::Small, Length::Large, Length::Huge}) {
+    const auto LhsString = makeString(Lhs);
+    for (auto Rhs :
+         {Length::Empty, Length::Small, Length::Large, Length::Huge}) {
+      if (Lhs > Rhs)
+        continue;
+      const auto RhsString = makeString(Rhs);
+
+      // The smaller one must be a prefix of the larger one.
+      if (RhsString.find(LhsString) != 0) {
+        fprintf(stderr, "Invalid autogenerated strings for sizes (%d,%d).\n",
+                static_cast<int>(Lhs), static_cast<int>(Rhs));
+        std::abort();
+      }
+    }
+  }
+  // Verify the autogenerated diffs
+  for (auto L : {Length::Small, Length::Large, Length::Huge}) {
+    const auto Control = makeString(L);
+    const auto Verify = [&](std::string Exp, size_t Pos) {
+      // Only change on the Pos char.
+      if (Control[Pos] != Exp[Pos]) {
+        Exp[Pos] = Control[Pos];
+        if (Control == Exp)
+          return;
+      }
+      fprintf(stderr, "Invalid autogenerated diff with size %d\n",
+              static_cast<int>(L));
+      std::abort();
+    };
+    Verify(makeString(L, DiffType::ChangeFirst), 0);
+    Verify(makeString(L, DiffType::ChangeMiddle), Control.size() / 2);
+    Verify(makeString(L, DiffType::ChangeLast), Control.size() - 1);
+  }
+}
+
+// Some small codegen thunks to easily see generated code.
+bool StringEqString(const std::string& a, const std::string& b) {
+  return a == b;
+}
+bool StringEqCStr(const std::string& a, const char* b) { return a == b; }
+bool CStrEqString(const char* a, const std::string& b) { return a == b; }
+bool StringEqCStrLiteralEmpty(const std::string& a) {
+  return a == "";
+}
+bool StringEqCStrLiteralSmall(const std::string& a) {
+  return a == SmallStringLiteral;
+}
+bool StringEqCStrLiteralLarge(const std::string& a) {
+  return a == LargeStringLiteral;
+}
+
+int main(int argc, char** argv) {
+  benchmark::Initialize(&argc, argv);
+  if (benchmark::ReportUnrecognizedArguments(argc, argv))
+    return 1;
+
+  sanityCheckGeneratedStrings();
+
+  makeCartesianProductBenchmark<StringConstructDestroyCStr, AllLengths,
+                                AllOpacity>();
+
+  makeCartesianProductBenchmark<StringAssignStr, AllLengths, AllOpacity>();
+  makeCartesianProductBenchmark<StringAssignAsciiz, AllLengths, AllOpacity>();
+  makeCartesianProductBenchmark<StringAssignAsciizMix, AllOpacity>();
+
+  makeCartesianProductBenchmark<StringCopy, AllLengths>();
+  makeCartesianProductBenchmark<StringMove, AllLengths>();
+  makeCartesianProductBenchmark<StringDestroy, AllLengths>();
+  makeCartesianProductBenchmark<StringResizeDefaultInit, AllLengths,
+                                AllOpacity>();
+  makeCartesianProductBenchmark<StringEraseToEnd, AllLengths, AllOpacity>();
+  makeCartesianProductBenchmark<StringEraseWithMove, AllLengths, AllOpacity>();
+  makeCartesianProductBenchmark<StringRelational, AllRelations, AllLengths,
+                                AllLengths, AllDiffTypes>();
+  makeCartesianProductBenchmark<StringRelationalLiteral, AllRelations,
+                                AllLengths, AllLengths, AllDiffTypes>();
+  makeCartesianProductBenchmark<StringRead, AllTemperatures, AllDepths,
+                                AllLengths>();
+  benchmark::RunSpecifiedBenchmarks();
+
+  if (argc < 0) {
+    // ODR-use the functions to force them being generated in the binary.
+    auto functions = std::make_tuple(
+        StringEqString, StringEqCStr, CStrEqString, StringEqCStrLiteralEmpty,
+        StringEqCStrLiteralSmall, StringEqCStrLiteralLarge);
+    printf("%p", &functions);
+  }
+}
diff --git a/benchmarks/stringstream.bench.cpp b/benchmarks/stringstream.bench.cpp
new file mode 100644
index 0000000..828ef4b
--- /dev/null
+++ b/benchmarks/stringstream.bench.cpp
@@ -0,0 +1,40 @@
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
+
+#include <sstream>
+
+TEST_NOINLINE double istream_numbers();
+
+double istream_numbers() {
+  const char *a[] = {
+    "-6  69 -71  2.4882e-02 -100 101 -2.00005 5000000 -50000000",
+    "-25 71   7 -9.3262e+01 -100 101 -2.00005 5000000 -50000000",
+    "-14 53  46 -6.7026e-02 -100 101 -2.00005 5000000 -50000000"
+  };
+
+  int a1, a2, a3, a4, a5, a6, a7;
+  double f1 = 0.0, f2 = 0.0, q = 0.0;
+  for (int i=0; i < 3; i++) {
+    std::istringstream s(a[i]);
+    s >> a1
+      >> a2
+      >> a3
+      >> f1
+      >> a4
+      >> a5
+      >> f2
+      >> a6
+      >> a7;
+    q += (a1 + a2 + a3 + a4 + a5 + a6 + a7 + f1 + f2)/1000000;
+  }
+  return q;
+}
+
+static void BM_Istream_numbers(benchmark::State &state) {
+  double i = 0;
+  while (state.KeepRunning())
+    benchmark::DoNotOptimize(i += istream_numbers());
+}
+
+BENCHMARK(BM_Istream_numbers)->RangeMultiplier(2)->Range(1024, 4096);
+BENCHMARK_MAIN();
diff --git a/benchmarks/to_chars.bench.cpp b/benchmarks/to_chars.bench.cpp
new file mode 100644
index 0000000..1a3dc64
--- /dev/null
+++ b/benchmarks/to_chars.bench.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <array>
+#include <charconv>
+#include <random>
+
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
+
+static const std::array<unsigned, 1000> input = [] {
+  std::mt19937 generator;
+  std::uniform_int_distribution<unsigned> distribution(0, std::numeric_limits<unsigned>::max());
+  std::array<unsigned, 1000> result;
+  std::generate_n(result.begin(), result.size(), [&] { return distribution(generator); });
+  return result;
+}();
+
+static void BM_to_chars_good(benchmark::State& state) {
+  char buffer[128];
+  int base = state.range(0);
+  while (state.KeepRunningBatch(input.size()))
+    for (auto value : input)
+      benchmark::DoNotOptimize(std::to_chars(buffer, &buffer[128], value, base));
+}
+BENCHMARK(BM_to_chars_good)->DenseRange(2, 36, 1);
+
+static void BM_to_chars_bad(benchmark::State& state) {
+  char buffer[128];
+  int base = state.range(0);
+  struct sample {
+    unsigned size;
+    unsigned value;
+  };
+  std::array<sample, 1000> data;
+  // Assume the failure occurs, on average, halfway during the conversion.
+  std::transform(input.begin(), input.end(), data.begin(), [&](unsigned value) {
+    std::to_chars_result result = std::to_chars(buffer, &buffer[128], value, base);
+    return sample{unsigned((result.ptr - buffer) / 2), value};
+  });
+
+  while (state.KeepRunningBatch(data.size()))
+    for (auto element : data)
+      benchmark::DoNotOptimize(std::to_chars(buffer, &buffer[element.size], element.value, base));
+}
+BENCHMARK(BM_to_chars_bad)->DenseRange(2, 36, 1);
+
+int main(int argc, char** argv) {
+  benchmark::Initialize(&argc, argv);
+  if (benchmark::ReportUnrecognizedArguments(argc, argv))
+    return 1;
+
+  benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/benchmarks/unordered_set_operations.bench.cpp b/benchmarks/unordered_set_operations.bench.cpp
new file mode 100644
index 0000000..e0030d6
--- /dev/null
+++ b/benchmarks/unordered_set_operations.bench.cpp
@@ -0,0 +1,307 @@
+#include <unordered_set>
+#include <vector>
+#include <functional>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+
+#include "benchmark/benchmark.h"
+
+#include "ContainerBenchmarks.h"
+#include "GenerateInput.h"
+#include "test_macros.h"
+
+using namespace ContainerBenchmarks;
+
+constexpr std::size_t TestNumInputs = 1024;
+
+template <class _Size>
+inline TEST_ALWAYS_INLINE
+_Size loadword(const void* __p) {
+    _Size __r;
+    std::memcpy(&__r, __p, sizeof(__r));
+    return __r;
+}
+
+inline TEST_ALWAYS_INLINE
+std::size_t rotate_by_at_least_1(std::size_t __val, int __shift) {
+    return (__val >> __shift) | (__val << (64 - __shift));
+}
+
+inline TEST_ALWAYS_INLINE
+std::size_t hash_len_16(std::size_t __u, std::size_t __v) {
+    const  std::size_t __mul = 0x9ddfea08eb382d69ULL;
+    std::size_t __a = (__u ^ __v) * __mul;
+    __a ^= (__a >> 47);
+    std::size_t __b = (__v ^ __a) * __mul;
+    __b ^= (__b >> 47);
+    __b *= __mul;
+    return __b;
+}
+
+
+template <std::size_t _Len>
+inline TEST_ALWAYS_INLINE
+std::size_t hash_len_0_to_8(const char* __s) {
+    static_assert(_Len == 4 || _Len == 8, "");
+    const uint64_t __a = loadword<uint32_t>(__s);
+    const uint64_t __b = loadword<uint32_t>(__s + _Len - 4);
+    return hash_len_16(_Len + (__a << 3), __b);
+}
+
+struct UInt32Hash {
+  UInt32Hash() = default;
+  inline TEST_ALWAYS_INLINE
+  std::size_t operator()(uint32_t data) const {
+      return hash_len_0_to_8<4>(reinterpret_cast<const char*>(&data));
+  }
+};
+
+struct UInt64Hash {
+  UInt64Hash() = default;
+  inline TEST_ALWAYS_INLINE
+  std::size_t operator()(uint64_t data) const {
+      return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data));
+  }
+};
+
+struct UInt128Hash {
+  UInt128Hash() = default;
+  inline TEST_ALWAYS_INLINE
+  std::size_t operator()(__uint128_t data) const {
+      const __uint128_t __mask = static_cast<std::size_t>(-1);
+      const std::size_t __a = (std::size_t)(data & __mask);
+      const std::size_t __b = (std::size_t)((data & (__mask << 64)) >> 64);
+      return hash_len_16(__a, rotate_by_at_least_1(__b + 16, 16)) ^ __b;
+  }
+};
+
+struct UInt32Hash2 {
+  UInt32Hash2() = default;
+  inline TEST_ALWAYS_INLINE
+  std::size_t operator()(uint32_t data) const {
+      const uint32_t __m = 0x5bd1e995;
+      const uint32_t __r = 24;
+      uint32_t __h = 4;
+      uint32_t __k = data;
+        __k *= __m;
+        __k ^= __k >> __r;
+        __k *= __m;
+        __h *= __m;
+        __h ^= __k;
+        __h ^= __h >> 13;
+        __h *= __m;
+        __h ^= __h >> 15;
+    return __h;
+  }
+};
+
+struct UInt64Hash2 {
+  UInt64Hash2() = default;
+  inline TEST_ALWAYS_INLINE
+  std::size_t operator()(uint64_t data) const {
+      return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data));
+  }
+};
+
+//----------------------------------------------------------------------------//
+//                               BM_Hash
+// ---------------------------------------------------------------------------//
+
+template <class HashFn, class GenInputs>
+void BM_Hash(benchmark::State& st, HashFn fn, GenInputs gen) {
+    auto in = gen(st.range(0));
+    const auto end = in.data() + in.size();
+    std::size_t last_hash = 0;
+    benchmark::DoNotOptimize(&last_hash);
+    while (st.KeepRunning()) {
+        for (auto it = in.data(); it != end; ++it) {
+            benchmark::DoNotOptimize(last_hash += fn(*it));
+        }
+        benchmark::ClobberMemory();
+    }
+}
+
+BENCHMARK_CAPTURE(BM_Hash,
+    uint32_random_std_hash,
+    std::hash<uint32_t>{},
+    getRandomIntegerInputs<uint32_t>) -> Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_Hash,
+    uint32_random_custom_hash,
+    UInt32Hash{},
+    getRandomIntegerInputs<uint32_t>) -> Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_Hash,
+    uint32_top_std_hash,
+    std::hash<uint32_t>{},
+    getSortedTopBitsIntegerInputs<uint32_t>) -> Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_Hash,
+    uint32_top_custom_hash,
+    UInt32Hash{},
+    getSortedTopBitsIntegerInputs<uint32_t>) -> Arg(TestNumInputs);
+
+
+//----------------------------------------------------------------------------//
+//                       BM_InsertValue
+// ---------------------------------------------------------------------------//
+
+
+// Sorted Ascending //
+BENCHMARK_CAPTURE(BM_InsertValue,
+    unordered_set_uint32,
+    std::unordered_set<uint32_t>{},
+    getRandomIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_InsertValue,
+    unordered_set_uint32_sorted,
+    std::unordered_set<uint32_t>{},
+    getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+
+// Top Bytes //
+BENCHMARK_CAPTURE(BM_InsertValue,
+    unordered_set_top_bits_uint32,
+    std::unordered_set<uint32_t>{},
+    getSortedTopBitsIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_InsertValueRehash,
+    unordered_set_top_bits_uint32,
+    std::unordered_set<uint32_t, UInt32Hash>{},
+    getSortedTopBitsIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+
+// String //
+BENCHMARK_CAPTURE(BM_InsertValue,
+    unordered_set_string,
+    std::unordered_set<std::string>{},
+    getRandomStringInputs)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_InsertValueRehash,
+    unordered_set_string,
+    std::unordered_set<std::string>{},
+    getRandomStringInputs)->Arg(TestNumInputs);
+
+//----------------------------------------------------------------------------//
+//                         BM_Find
+// ---------------------------------------------------------------------------//
+
+// Random //
+BENCHMARK_CAPTURE(BM_Find,
+    unordered_set_random_uint64,
+    std::unordered_set<uint64_t>{},
+    getRandomIntegerInputs<uint64_t>)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_FindRehash,
+    unordered_set_random_uint64,
+    std::unordered_set<uint64_t, UInt64Hash>{},
+    getRandomIntegerInputs<uint64_t>)->Arg(TestNumInputs);
+
+// Sorted //
+BENCHMARK_CAPTURE(BM_Find,
+    unordered_set_sorted_uint64,
+    std::unordered_set<uint64_t>{},
+    getSortedIntegerInputs<uint64_t>)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_FindRehash,
+    unordered_set_sorted_uint64,
+    std::unordered_set<uint64_t, UInt64Hash>{},
+    getSortedIntegerInputs<uint64_t>)->Arg(TestNumInputs);
+
+
+// Sorted //
+#if 1
+BENCHMARK_CAPTURE(BM_Find,
+    unordered_set_sorted_uint128,
+    std::unordered_set<__uint128_t, UInt128Hash>{},
+    getSortedTopBitsIntegerInputs<__uint128_t>)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_FindRehash,
+    unordered_set_sorted_uint128,
+    std::unordered_set<__uint128_t, UInt128Hash>{},
+    getSortedTopBitsIntegerInputs<__uint128_t>)->Arg(TestNumInputs);
+#endif
+
+// Sorted //
+BENCHMARK_CAPTURE(BM_Find,
+    unordered_set_sorted_uint32,
+    std::unordered_set<uint32_t>{},
+    getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_FindRehash,
+    unordered_set_sorted_uint32,
+    std::unordered_set<uint32_t, UInt32Hash2>{},
+    getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+
+// Sorted Ascending //
+BENCHMARK_CAPTURE(BM_Find,
+    unordered_set_sorted_large_uint64,
+    std::unordered_set<uint64_t>{},
+    getSortedLargeIntegerInputs<uint64_t>)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_FindRehash,
+    unordered_set_sorted_large_uint64,
+    std::unordered_set<uint64_t, UInt64Hash>{},
+    getSortedLargeIntegerInputs<uint64_t>)->Arg(TestNumInputs);
+
+
+// Top Bits //
+BENCHMARK_CAPTURE(BM_Find,
+    unordered_set_top_bits_uint64,
+    std::unordered_set<uint64_t>{},
+    getSortedTopBitsIntegerInputs<uint64_t>)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_FindRehash,
+    unordered_set_top_bits_uint64,
+    std::unordered_set<uint64_t, UInt64Hash>{},
+    getSortedTopBitsIntegerInputs<uint64_t>)->Arg(TestNumInputs);
+
+// String //
+BENCHMARK_CAPTURE(BM_Find,
+    unordered_set_string,
+    std::unordered_set<std::string>{},
+    getRandomStringInputs)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_FindRehash,
+    unordered_set_string,
+    std::unordered_set<std::string>{},
+    getRandomStringInputs)->Arg(TestNumInputs);
+
+///////////////////////////////////////////////////////////////////////////////
+BENCHMARK_CAPTURE(BM_InsertDuplicate,
+    unordered_set_int,
+    std::unordered_set<int>{},
+    getRandomIntegerInputs<int>)->Arg(TestNumInputs);
+BENCHMARK_CAPTURE(BM_InsertDuplicate,
+    unordered_set_string,
+    std::unordered_set<std::string>{},
+    getRandomStringInputs)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_EmplaceDuplicate,
+    unordered_set_int,
+    std::unordered_set<int>{},
+    getRandomIntegerInputs<int>)->Arg(TestNumInputs);
+BENCHMARK_CAPTURE(BM_EmplaceDuplicate,
+    unordered_set_string,
+    std::unordered_set<std::string>{},
+    getRandomStringInputs)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_InsertDuplicate,
+    unordered_set_int_insert_arg,
+    std::unordered_set<int>{},
+    getRandomIntegerInputs<int>)->Arg(TestNumInputs);
+BENCHMARK_CAPTURE(BM_InsertDuplicate,
+    unordered_set_string_insert_arg,
+    std::unordered_set<std::string>{},
+    getRandomStringInputs)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_EmplaceDuplicate,
+    unordered_set_int_insert_arg,
+    std::unordered_set<int>{},
+    getRandomIntegerInputs<unsigned>)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_EmplaceDuplicate,
+    unordered_set_string_arg,
+    std::unordered_set<std::string>{},
+    getRandomCStringInputs)->Arg(TestNumInputs);
+
+BENCHMARK_MAIN();
diff --git a/benchmarks/util_smartptr.bench.cpp b/benchmarks/util_smartptr.bench.cpp
new file mode 100644
index 0000000..053cbd6
--- /dev/null
+++ b/benchmarks/util_smartptr.bench.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <memory>
+
+#include "benchmark/benchmark.h"
+
+static void BM_SharedPtrCreateDestroy(benchmark::State& st) {
+  while (st.KeepRunning()) {
+    auto sp = std::make_shared<int>(42);
+    benchmark::DoNotOptimize(sp.get());
+  }
+}
+BENCHMARK(BM_SharedPtrCreateDestroy);
+
+static void BM_SharedPtrIncDecRef(benchmark::State& st) {
+  auto sp = std::make_shared<int>(42);
+  benchmark::DoNotOptimize(sp.get());
+  while (st.KeepRunning()) {
+    std::shared_ptr<int> sp2(sp);
+    benchmark::ClobberMemory();
+  }
+}
+BENCHMARK(BM_SharedPtrIncDecRef);
+
+static void BM_WeakPtrIncDecRef(benchmark::State& st) {
+  auto sp = std::make_shared<int>(42);
+  benchmark::DoNotOptimize(sp.get());
+  while (st.KeepRunning()) {
+    std::weak_ptr<int> wp(sp);
+    benchmark::ClobberMemory();
+  }
+}
+BENCHMARK(BM_WeakPtrIncDecRef);
+
+BENCHMARK_MAIN();
diff --git a/benchmarks/variant_visit_1.bench.cpp b/benchmarks/variant_visit_1.bench.cpp
new file mode 100644
index 0000000..7d736f8
--- /dev/null
+++ b/benchmarks/variant_visit_1.bench.cpp
@@ -0,0 +1,27 @@
+#include "benchmark/benchmark.h"
+
+#include "VariantBenchmarks.h"
+
+using namespace VariantBenchmarks;
+
+BENCHMARK_TEMPLATE(BM_Visit, 1, 1);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 2);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 3);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 4);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 5);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 6);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 7);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 8);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 9);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 10);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 20);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 30);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 40);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 50);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 60);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 70);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 80);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 90);
+BENCHMARK_TEMPLATE(BM_Visit, 1, 100);
+
+BENCHMARK_MAIN();
diff --git a/benchmarks/variant_visit_2.bench.cpp b/benchmarks/variant_visit_2.bench.cpp
new file mode 100644
index 0000000..ed26cd4
--- /dev/null
+++ b/benchmarks/variant_visit_2.bench.cpp
@@ -0,0 +1,22 @@
+#include "benchmark/benchmark.h"
+
+#include "VariantBenchmarks.h"
+
+using namespace VariantBenchmarks;
+
+BENCHMARK_TEMPLATE(BM_Visit, 2, 1);
+BENCHMARK_TEMPLATE(BM_Visit, 2, 2);
+BENCHMARK_TEMPLATE(BM_Visit, 2, 3);
+BENCHMARK_TEMPLATE(BM_Visit, 2, 4);
+BENCHMARK_TEMPLATE(BM_Visit, 2, 5);
+BENCHMARK_TEMPLATE(BM_Visit, 2, 6);
+BENCHMARK_TEMPLATE(BM_Visit, 2, 7);
+BENCHMARK_TEMPLATE(BM_Visit, 2, 8);
+BENCHMARK_TEMPLATE(BM_Visit, 2, 9);
+BENCHMARK_TEMPLATE(BM_Visit, 2, 10);
+BENCHMARK_TEMPLATE(BM_Visit, 2, 20);
+BENCHMARK_TEMPLATE(BM_Visit, 2, 30);
+BENCHMARK_TEMPLATE(BM_Visit, 2, 40);
+BENCHMARK_TEMPLATE(BM_Visit, 2, 50);
+
+BENCHMARK_MAIN();
diff --git a/benchmarks/variant_visit_3.bench.cpp b/benchmarks/variant_visit_3.bench.cpp
new file mode 100644
index 0000000..b20d503
--- /dev/null
+++ b/benchmarks/variant_visit_3.bench.cpp
@@ -0,0 +1,20 @@
+#include "benchmark/benchmark.h"
+
+#include "VariantBenchmarks.h"
+
+using namespace VariantBenchmarks;
+
+BENCHMARK_TEMPLATE(BM_Visit, 3, 1);
+BENCHMARK_TEMPLATE(BM_Visit, 3, 2);
+BENCHMARK_TEMPLATE(BM_Visit, 3, 3);
+BENCHMARK_TEMPLATE(BM_Visit, 3, 4);
+BENCHMARK_TEMPLATE(BM_Visit, 3, 5);
+BENCHMARK_TEMPLATE(BM_Visit, 3, 6);
+BENCHMARK_TEMPLATE(BM_Visit, 3, 7);
+BENCHMARK_TEMPLATE(BM_Visit, 3, 8);
+BENCHMARK_TEMPLATE(BM_Visit, 3, 9);
+BENCHMARK_TEMPLATE(BM_Visit, 3, 10);
+BENCHMARK_TEMPLATE(BM_Visit, 3, 15);
+BENCHMARK_TEMPLATE(BM_Visit, 3, 20);
+
+BENCHMARK_MAIN();
diff --git a/benchmarks/vector_operations.bench.cpp b/benchmarks/vector_operations.bench.cpp
new file mode 100644
index 0000000..70a317d
--- /dev/null
+++ b/benchmarks/vector_operations.bench.cpp
@@ -0,0 +1,40 @@
+#include <vector>
+#include <functional>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+
+#include "benchmark/benchmark.h"
+
+#include "ContainerBenchmarks.h"
+#include "GenerateInput.h"
+
+using namespace ContainerBenchmarks;
+
+constexpr std::size_t TestNumInputs = 1024;
+
+BENCHMARK_CAPTURE(BM_ConstructSize,
+    vector_byte,
+    std::vector<unsigned char>{})->Arg(5140480);
+
+BENCHMARK_CAPTURE(BM_ConstructSizeValue,
+    vector_byte,
+    std::vector<unsigned char>{}, 0)->Arg(5140480);
+
+BENCHMARK_CAPTURE(BM_ConstructIterIter,
+  vector_char,
+  std::vector<char>{},
+  getRandomIntegerInputs<char>)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_ConstructIterIter,
+  vector_size_t,
+  std::vector<size_t>{},
+  getRandomIntegerInputs<size_t>)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_ConstructIterIter,
+  vector_string,
+  std::vector<std::string>{},
+  getRandomStringInputs)->Arg(TestNumInputs);
+
+
+BENCHMARK_MAIN();
diff --git a/cmake/Modules/CodeCoverage.cmake b/cmake/Modules/CodeCoverage.cmake
new file mode 100644
index 0000000..1bd3a78
--- /dev/null
+++ b/cmake/Modules/CodeCoverage.cmake
@@ -0,0 +1,50 @@
+find_program(CODE_COVERAGE_LCOV lcov)
+if (NOT CODE_COVERAGE_LCOV)
+  message(FATAL_ERROR "Cannot find lcov...")
+endif()
+
+find_program(CODE_COVERAGE_LLVM_COV llvm-cov)
+if (NOT CODE_COVERAGE_LLVM_COV)
+  message(FATAL_ERROR "Cannot find llvm-cov...")
+endif()
+
+find_program(CODE_COVERAGE_GENHTML genhtml)
+if (NOT CODE_COVERAGE_GENHTML)
+  message(FATAL_ERROR "Cannot find genhtml...")
+endif()
+
+set(CMAKE_CXX_FLAGS_COVERAGE "-g -O0 --coverage")
+
+function(setup_lcov_test_target_coverage target_name output_dir capture_dirs source_dirs)
+  if (NOT DEFINED LIBCXX_BINARY_DIR)
+    message(FATAL_ERROR "Variable must be set")
+  endif()
+
+  set(GCOV_TOOL "${LIBCXX_BINARY_DIR}/llvm-cov-wrapper")
+  file(GENERATE OUTPUT ${GCOV_TOOL}
+    CONTENT "#!/usr/bin/env bash\n${CODE_COVERAGE_LLVM_COV} gcov \"$@\"\n")
+
+  file(MAKE_DIRECTORY ${output_dir})
+
+  set(CAPTURE_DIRS "")
+  foreach(cdir ${capture_dirs})
+    list(APPEND CAPTURE_DIRS "-d;${cdir}")
+  endforeach()
+
+  set(EXTRACT_DIRS "")
+  foreach(sdir ${source_dirs})
+    list(APPEND EXTRACT_DIRS "'${sdir}/*'")
+  endforeach()
+
+  message(STATUS "Capture Directories: ${CAPTURE_DIRS}")
+  message(STATUS "Extract Directories: ${EXTRACT_DIRS}")
+
+  add_custom_target(generate-lib${target_name}-coverage
+        COMMAND chmod +x ${GCOV_TOOL}
+        COMMAND ${CODE_COVERAGE_LCOV} --gcov-tool ${GCOV_TOOL} --capture ${CAPTURE_DIRS} -o test_coverage.info
+        COMMAND ${CODE_COVERAGE_LCOV} --gcov-tool ${GCOV_TOOL} --extract test_coverage.info ${EXTRACT_DIRS} -o test_coverage.info
+        COMMAND ${CODE_COVERAGE_GENHTML} --demangle-cpp test_coverage.info -o test_coverage
+        COMMAND ${CMAKE_COMMAND} -E remove test_coverage.info
+        WORKING_DIRECTORY ${output_dir}
+        COMMENT "Generating coverage results")
+endfunction()
diff --git a/cmake/Modules/DefineLinkerScript.cmake b/cmake/Modules/DefineLinkerScript.cmake
new file mode 100644
index 0000000..be7f026
--- /dev/null
+++ b/cmake/Modules/DefineLinkerScript.cmake
@@ -0,0 +1,56 @@
+# This function defines a linker script in place of the symlink traditionally
+# created for shared libraries.
+#
+# More specifically, this function goes through the PUBLIC and INTERFACE
+# library dependencies of <target> and gathers them into a linker script,
+# such that those libraries are linked against when the shared library for
+# <target> is linked against.
+#
+# Arguments:
+#   <target>: A target representing a shared library. A linker script will be
+#             created in place of that target's TARGET_LINKER_FILE, which is
+#             the symlink pointing to the actual shared library (usually
+#             libFoo.so pointing to libFoo.so.1, which itself points to
+#             libFoo.so.1.0).
+
+function(define_linker_script target)
+  if (NOT TARGET "${target}")
+    message(FATAL_ERROR "The provided target '${target}' is not actually a target.")
+  endif()
+
+  get_target_property(target_type "${target}" TYPE)
+  if (NOT "${target_type}" STREQUAL "SHARED_LIBRARY")
+    message(FATAL_ERROR "The provided target '${target}' is not a shared library (its type is '${target_type}').")
+  endif()
+
+  set(symlink "$<TARGET_LINKER_FILE:${target}>")
+  set(soname "$<TARGET_SONAME_FILE_NAME:${target}>")
+
+  get_target_property(interface_libs "${target}" INTERFACE_LINK_LIBRARIES)
+
+  set(link_libraries)
+  if (interface_libs)
+    foreach(lib IN LISTS interface_libs)
+      if ("${lib}" STREQUAL "cxx-headers")
+        continue()
+      endif()
+      # If ${lib} is not a target, we use a dummy target which we know will
+      # have an OUTPUT_NAME property so that CMake doesn't fail when evaluating
+      # the non-selected branch of the `IF`. It doesn't matter what it evaluates
+      # to because it's not selected, but it must not cause an error.
+      # See https://gitlab.kitware.com/cmake/cmake/-/issues/21045.
+      set(output_name_tgt "$<IF:$<TARGET_EXISTS:${lib}>,${lib},${target}>")
+      set(libname "$<IF:$<TARGET_EXISTS:${lib}>,$<TARGET_PROPERTY:${output_name_tgt},OUTPUT_NAME>,${lib}>")
+      list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}${libname}")
+    endforeach()
+  endif()
+  string(REPLACE ";" " " link_libraries "${link_libraries}")
+
+  set(linker_script "INPUT(${soname} ${link_libraries})")
+  add_custom_command(TARGET "${target}" POST_BUILD
+    COMMAND "${CMAKE_COMMAND}" -E remove "${symlink}"
+    COMMAND "${CMAKE_COMMAND}" -E echo "${linker_script}" > "${symlink}"
+    COMMENT "Generating linker script: '${linker_script}' as file ${symlink}"
+    VERBATIM
+  )
+endfunction()
diff --git a/cmake/Modules/GetTriple.cmake b/cmake/Modules/GetTriple.cmake
deleted file mode 100644
index c555931..0000000
--- a/cmake/Modules/GetTriple.cmake
+++ /dev/null
@@ -1,53 +0,0 @@
-# Define functions to get the host and target triple.
-
-function(get_host_triple out out_arch out_vendor out_os)
-  # Get the architecture.
-  set(arch ${CMAKE_HOST_SYSTEM_PROCESSOR})
-  if (arch STREQUAL "x86")
-    set(arch "i686")
-  endif()
-  # Get the vendor.
-  if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin")
-    set(vendor "apple")
-  else()
-    set(vendor "pc")
-  endif()
-  # Get os.
-  if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows")
-    set(os "win32")
-  else()
-    string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} os)
-  endif()
-  set(triple "${arch}-${vendor}-${os}")
-  set(${out} ${triple} PARENT_SCOPE)
-  set(${out_arch} ${arch} PARENT_SCOPE)
-  set(${out_vendor} ${vendor} PARENT_SCOPE)
-  set(${out_os} ${os} PARENT_SCOPE)
-  message(STATUS "Host triple: ${triple}")
-endfunction()
-
-function(get_target_triple out out_arch out_vendor out_os)
-  # Get the architecture.
-  set(arch ${CMAKE_SYSTEM_PROCESSOR})
-  if (arch STREQUAL "x86")
-    set(arch "i686")
-  endif()
-  # Get the vendor.
-  if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
-    set(vendor "apple")
-  else()
-    set(vendor "pc")
-  endif()
-  # Get os.
-  if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
-    set(os "win32")
-  else()
-    string(TOLOWER ${CMAKE_SYSTEM_NAME} os)
-  endif()
-  set(triple "${arch}-${vendor}-${os}")
-  set(${out} ${triple} PARENT_SCOPE)
-  set(${out_arch} ${arch} PARENT_SCOPE)
-  set(${out_vendor} ${vendor} PARENT_SCOPE)
-  set(${out_os} ${os} PARENT_SCOPE)
-  message(STATUS "Target triple: ${triple}")
-endfunction()
diff --git a/cmake/Modules/HandleCompilerRT.cmake b/cmake/Modules/HandleCompilerRT.cmake
new file mode 100644
index 0000000..1ce2565
--- /dev/null
+++ b/cmake/Modules/HandleCompilerRT.cmake
@@ -0,0 +1,64 @@
+function(find_compiler_rt_library name dest)
+  if (NOT DEFINED LIBCXX_COMPILE_FLAGS)
+    message(FATAL_ERROR "LIBCXX_COMPILE_FLAGS must be defined when using this function")
+  endif()
+  set(dest "" PARENT_SCOPE)
+  set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXX_COMPILE_FLAGS}
+      "--rtlib=compiler-rt" "--print-libgcc-file-name")
+  if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_CXX_COMPILER_TARGET)
+    list(APPEND CLANG_COMMAND "--target=${CMAKE_CXX_COMPILER_TARGET}")
+  endif()
+  get_property(LIBCXX_CXX_FLAGS CACHE CMAKE_CXX_FLAGS PROPERTY VALUE)
+  string(REPLACE " " ";" LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS}")
+  list(APPEND CLANG_COMMAND ${LIBCXX_CXX_FLAGS})
+  execute_process(
+      COMMAND ${CLANG_COMMAND}
+      RESULT_VARIABLE HAD_ERROR
+      OUTPUT_VARIABLE LIBRARY_FILE
+  )
+  string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE)
+  file(TO_CMAKE_PATH "${LIBRARY_FILE}" LIBRARY_FILE)
+  string(REPLACE "builtins" "${name}" LIBRARY_FILE "${LIBRARY_FILE}")
+  if (NOT HAD_ERROR AND EXISTS "${LIBRARY_FILE}")
+    message(STATUS "Found compiler-rt library: ${LIBRARY_FILE}")
+    set(${dest} "${LIBRARY_FILE}" PARENT_SCOPE)
+  else()
+    message(STATUS "Failed to find compiler-rt library")
+  endif()
+endfunction()
+
+function(find_compiler_rt_dir dest)
+  if (NOT DEFINED LIBCXX_COMPILE_FLAGS)
+    message(FATAL_ERROR "LIBCXX_COMPILE_FLAGS must be defined when using this function")
+  endif()
+  set(dest "" PARENT_SCOPE)
+  if (APPLE)
+    set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXX_COMPILE_FLAGS}
+        "-print-file-name=lib")
+    execute_process(
+        COMMAND ${CLANG_COMMAND}
+        RESULT_VARIABLE HAD_ERROR
+        OUTPUT_VARIABLE LIBRARY_DIR
+    )
+    string(STRIP "${LIBRARY_DIR}" LIBRARY_DIR)
+    file(TO_CMAKE_PATH "${LIBRARY_DIR}" LIBRARY_DIR)
+    set(LIBRARY_DIR "${LIBRARY_DIR}/darwin")
+  else()
+    set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXX_COMPILE_FLAGS}
+        "--rtlib=compiler-rt" "--print-libgcc-file-name")
+    execute_process(
+        COMMAND ${CLANG_COMMAND}
+        RESULT_VARIABLE HAD_ERROR
+        OUTPUT_VARIABLE LIBRARY_FILE
+    )
+    string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE)
+    file(TO_CMAKE_PATH "${LIBRARY_FILE}" LIBRARY_FILE)
+    get_filename_component(LIBRARY_DIR "${LIBRARY_FILE}" DIRECTORY)
+  endif()
+  if (NOT HAD_ERROR AND EXISTS "${LIBRARY_DIR}")
+    message(STATUS "Found compiler-rt directory: ${LIBRARY_DIR}")
+    set(${dest} "${LIBRARY_DIR}" PARENT_SCOPE)
+  else()
+    message(STATUS "Failed to find compiler-rt directory")
+  endif()
+endfunction()
diff --git a/cmake/Modules/HandleLibCXXABI.cmake b/cmake/Modules/HandleLibCXXABI.cmake
new file mode 100644
index 0000000..5a8a4a2
--- /dev/null
+++ b/cmake/Modules/HandleLibCXXABI.cmake
@@ -0,0 +1,142 @@
+
+#===============================================================================
+# Add an ABI library if appropriate
+#===============================================================================
+
+#
+# _setup_abi: Set up the build to use an ABI library
+#
+# Parameters:
+#   abidefines: A list of defines needed to compile libc++ with the ABI library
+#   abishared : The shared ABI library to link against.
+#   abistatic : The static ABI library to link against.
+#   abifiles  : A list of files (which may be relative paths) to copy into the
+#               libc++ build tree for the build.  These files will be copied
+#               twice: once into include/, so the libc++ build itself can find
+#               them, and once into include/c++/v1, so that a clang built into
+#               the same build area will find them.  These files will also be
+#               installed alongside the libc++ headers.
+#   abidirs   : A list of relative paths to create under an include directory
+#               in the libc++ build directory.
+#
+
+macro(setup_abi_lib abidefines abishared abistatic abifiles abidirs)
+  list(APPEND LIBCXX_COMPILE_FLAGS ${abidefines})
+  set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_CXX_ABI_INCLUDE_PATHS}"
+    CACHE PATH
+    "Paths to C++ ABI header directories separated by ';'." FORCE
+    )
+  set(LIBCXX_CXX_ABI_LIBRARY_PATH "${LIBCXX_CXX_ABI_LIBRARY_PATH}"
+    CACHE PATH
+    "Paths to C++ ABI library directory"
+    )
+  set(LIBCXX_CXX_SHARED_ABI_LIBRARY ${abishared})
+  set(LIBCXX_CXX_STATIC_ABI_LIBRARY ${abistatic})
+  set(LIBCXX_ABILIB_FILES ${abifiles})
+
+  foreach(fpath ${LIBCXX_ABILIB_FILES})
+    set(found FALSE)
+    foreach(incpath ${LIBCXX_CXX_ABI_INCLUDE_PATHS})
+      message(STATUS "Looking for ${fpath} in ${incpath}")
+      if (EXISTS "${incpath}/${fpath}")
+        set(found TRUE)
+        message(STATUS "Looking for ${fpath} in ${incpath} - found")
+        get_filename_component(dstdir ${fpath} PATH)
+        get_filename_component(ifile ${fpath} NAME)
+        set(src ${incpath}/${fpath})
+
+        set(dst ${LIBCXX_BINARY_INCLUDE_DIR}/${dstdir}/${ifile})
+        add_custom_command(OUTPUT ${dst}
+            DEPENDS ${src}
+            COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
+            COMMENT "Copying C++ ABI header ${fpath}...")
+        list(APPEND abilib_headers "${dst}")
+
+        # TODO: libc++ shouldn't be responsible for copying the libc++abi
+        # headers into the right location.
+        set(dst "${LIBCXX_GENERATED_INCLUDE_DIR}/${dstdir}/${fpath}")
+        add_custom_command(OUTPUT ${dst}
+            DEPENDS ${src}
+            COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
+            COMMENT "Copying C++ ABI header ${fpath}...")
+        list(APPEND abilib_headers "${dst}")
+
+        if (LIBCXX_INSTALL_HEADERS)
+          install(FILES "${LIBCXX_BINARY_INCLUDE_DIR}/${fpath}"
+            DESTINATION include/c++/v1/${dstdir}
+            COMPONENT cxx-headers
+            PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+            )
+        endif()
+      else()
+        message(STATUS "Looking for ${fpath} in ${incpath} - not found")
+      endif()
+    endforeach()
+    if (NOT found)
+      message(WARNING "Failed to find ${fpath} in ${LIBCXX_CXX_ABI_INCLUDE_PATHS}")
+    endif()
+  endforeach()
+
+  include_directories("${LIBCXX_BINARY_INCLUDE_DIR}")
+  add_custom_target(cxx_abi_headers ALL DEPENDS ${abilib_headers})
+  set(LIBCXX_CXX_ABI_HEADER_TARGET "cxx_abi_headers")
+endmacro()
+
+
+# Configure based on the selected ABI library.
+if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++" OR
+    "${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libsupc++")
+  set(_LIBSUPCXX_INCLUDE_FILES
+    cxxabi.h bits/c++config.h bits/os_defines.h bits/cpu_defines.h
+    bits/cxxabi_tweaks.h bits/cxxabi_forced.h
+    )
+  if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++")
+    set(_LIBSUPCXX_DEFINES "-DLIBSTDCXX")
+    set(_LIBSUPCXX_LIBNAME stdc++)
+  else()
+    set(_LIBSUPCXX_DEFINES "")
+    set(_LIBSUPCXX_LIBNAME supc++)
+  endif()
+  setup_abi_lib(
+    "-D__GLIBCXX__ ${_LIBSUPCXX_DEFINES}"
+    "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_INCLUDE_FILES}" "bits"
+    )
+elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxabi")
+  if(NOT LIBCXX_CXX_ABI_INCLUDE_PATHS)
+    set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_SOURCE_DIR}/../libcxxabi/include")
+  endif()
+
+  if(LIBCXX_STANDALONE_BUILD AND NOT (LIBCXX_CXX_ABI_INTREE OR HAVE_LIBCXXABI))
+    set(shared c++abi)
+    set(static c++abi)
+  else()
+    set(shared cxxabi_shared)
+    set(static cxxabi_static)
+  endif()
+
+  setup_abi_lib(
+    "-DLIBCXX_BUILDING_LIBCXXABI"
+    "${shared}" "${static}" "cxxabi.h;__cxxabi_config.h" "")
+elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxrt")
+  if(NOT LIBCXX_CXX_ABI_INCLUDE_PATHS)
+    set(LIBCXX_CXX_ABI_INCLUDE_PATHS "/usr/include/c++/v1")
+  endif()
+  # libcxxrt does not provide aligned new and delete operators
+  set(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON)
+  setup_abi_lib(
+    "-DLIBCXXRT"
+    "cxxrt" "cxxrt" "cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h" ""
+    )
+elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "vcruntime")
+ # Nothing to do
+elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "none")
+  list(APPEND LIBCXX_COMPILE_FLAGS "-D_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY")
+elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "default")
+  # Nothing to do
+else()
+  message(FATAL_ERROR
+    "Unsupported c++ abi: '${LIBCXX_CXX_ABI_LIBNAME}'. \
+     Currently libstdc++, libsupc++, libcxxabi, libcxxrt, default and none are
+     supported for c++ abi."
+    )
+endif ()
diff --git a/cmake/Modules/HandleLibcxxFlags.cmake b/cmake/Modules/HandleLibcxxFlags.cmake
new file mode 100644
index 0000000..859cfc4
--- /dev/null
+++ b/cmake/Modules/HandleLibcxxFlags.cmake
@@ -0,0 +1,254 @@
+# HandleLibcxxFlags - A set of macros used to setup the flags used to compile
+# and link libc++. These macros add flags to the following CMake variables.
+# - LIBCXX_COMPILE_FLAGS: flags used to compile libc++
+# - LIBCXX_LINK_FLAGS: flags used to link libc++
+# - LIBCXX_LIBRARIES: libraries to link libc++ to.
+
+include(CheckCXXCompilerFlag)
+
+unset(add_flag_if_supported)
+
+# Mangle the name of a compiler flag into a valid CMake identifier.
+# Ex: --std=c++11 -> STD_EQ_CXX11
+macro(mangle_name str output)
+  string(STRIP "${str}" strippedStr)
+  string(REGEX REPLACE "^/" "" strippedStr "${strippedStr}")
+  string(REGEX REPLACE "^-+" "" strippedStr "${strippedStr}")
+  string(REGEX REPLACE "-+$" "" strippedStr "${strippedStr}")
+  string(REPLACE "-" "_" strippedStr "${strippedStr}")
+  string(REPLACE ":" "_COLON_" strippedStr "${strippedStr}")
+  string(REPLACE "=" "_EQ_" strippedStr "${strippedStr}")
+  string(REPLACE "+" "X" strippedStr "${strippedStr}")
+  string(TOUPPER "${strippedStr}" ${output})
+endmacro()
+
+# Remove a list of flags from all CMake variables that affect compile flags.
+# This can be used to remove unwanted flags specified on the command line
+# or added in other parts of LLVM's cmake configuration.
+macro(remove_flags)
+  foreach(var ${ARGN})
+    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
+    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}")
+    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
+    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
+    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+    string(REPLACE "${var}" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+    string(REPLACE "${var}" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
+    string(REPLACE "${var}" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
+    string(REPLACE "${var}" "" CMAKE_SHARED_MODULE_FLAGS "${CMAKE_SHARED_MODULE_FLAGS}")
+    remove_definitions(${var})
+  endforeach()
+endmacro(remove_flags)
+
+macro(check_flag_supported flag)
+    mangle_name("${flag}" flagname)
+    check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
+endmacro()
+
+macro(append_flags DEST)
+  foreach(value ${ARGN})
+    list(APPEND ${DEST} ${value})
+    list(APPEND ${DEST} ${value})
+  endforeach()
+endmacro()
+
+# If the specified 'condition' is true then append the specified list of flags to DEST
+macro(append_flags_if condition DEST)
+  if (${condition})
+    list(APPEND ${DEST} ${ARGN})
+  endif()
+endmacro()
+
+# Add each flag in the list specified by DEST if that flag is supported by the current compiler.
+macro(append_flags_if_supported DEST)
+  foreach(flag ${ARGN})
+    mangle_name("${flag}" flagname)
+    check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
+    append_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${DEST} ${flag})
+  endforeach()
+endmacro()
+
+# Add a macro definition if condition is true.
+macro(define_if condition def)
+  if (${condition})
+    add_definitions(${def})
+  endif()
+endmacro()
+
+# Add a macro definition if condition is not true.
+macro(define_if_not condition def)
+  if (NOT ${condition})
+    add_definitions(${def})
+  endif()
+endmacro()
+
+# Add a 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)
+  endif()
+endmacro()
+
+macro(config_define_if_not condition def)
+  if (NOT ${condition})
+    set(${def} ON)
+  endif()
+endmacro()
+
+macro(config_define value def)
+  set(${def} ${value})
+endmacro()
+
+# Add a list of flags to all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS',
+# 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS'.
+macro(add_target_flags)
+  foreach(value ${ARGN})
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${value}")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${value}")
+    list(APPEND LIBCXX_COMPILE_FLAGS ${value})
+    list(APPEND LIBCXX_LINK_FLAGS ${value})
+  endforeach()
+endmacro()
+
+# If the specified 'condition' is true then add a list of flags to
+# all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', 'LIBCXX_COMPILE_FLAGS'
+# and 'LIBCXX_LINK_FLAGS'.
+macro(add_target_flags_if condition)
+  if (${condition})
+    add_target_flags(${ARGN})
+  endif()
+endmacro()
+
+# Add all the flags supported by the compiler to all of
+# 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', 'LIBCXX_COMPILE_FLAGS'
+# and 'LIBCXX_LINK_FLAGS'.
+macro(add_target_flags_if_supported)
+  foreach(flag ${ARGN})
+    mangle_name("${flag}" flagname)
+    check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
+    add_target_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag})
+  endforeach()
+endmacro()
+
+# Add a specified list of flags to both 'LIBCXX_COMPILE_FLAGS' and
+# 'LIBCXX_LINK_FLAGS'.
+macro(add_flags)
+  foreach(value ${ARGN})
+    list(APPEND LIBCXX_COMPILE_FLAGS ${value})
+    list(APPEND LIBCXX_LINK_FLAGS ${value})
+  endforeach()
+endmacro()
+
+# If the specified 'condition' is true then add a list of flags to both
+# 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS'.
+macro(add_flags_if condition)
+  if (${condition})
+    add_flags(${ARGN})
+  endif()
+endmacro()
+
+# Add each flag in the list to LIBCXX_COMPILE_FLAGS and LIBCXX_LINK_FLAGS
+# if that flag is supported by the current compiler.
+macro(add_flags_if_supported)
+  foreach(flag ${ARGN})
+      mangle_name("${flag}" flagname)
+      check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
+      add_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag})
+  endforeach()
+endmacro()
+
+# Add a list of flags to 'LIBCXX_COMPILE_FLAGS'.
+macro(add_compile_flags)
+  foreach(f ${ARGN})
+    list(APPEND LIBCXX_COMPILE_FLAGS ${f})
+  endforeach()
+endmacro()
+
+# If 'condition' is true then add the specified list of flags to
+# 'LIBCXX_COMPILE_FLAGS'
+macro(add_compile_flags_if condition)
+  if (${condition})
+    add_compile_flags(${ARGN})
+  endif()
+endmacro()
+
+# For each specified flag, add that flag to 'LIBCXX_COMPILE_FLAGS' if the
+# flag is supported by the C++ compiler.
+macro(add_compile_flags_if_supported)
+  foreach(flag ${ARGN})
+      mangle_name("${flag}" flagname)
+      check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
+      add_compile_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag})
+  endforeach()
+endmacro()
+
+# Add a list of flags to 'LIBCXX_LINK_FLAGS'.
+macro(add_link_flags)
+  foreach(f ${ARGN})
+    list(APPEND LIBCXX_LINK_FLAGS ${f})
+  endforeach()
+endmacro()
+
+# If 'condition' is true then add the specified list of flags to
+# 'LIBCXX_LINK_FLAGS'
+macro(add_link_flags_if condition)
+  if (${condition})
+    add_link_flags(${ARGN})
+  endif()
+endmacro()
+
+# For each specified flag, add that flag to 'LIBCXX_LINK_FLAGS' if the
+# flag is supported by the C++ compiler.
+macro(add_link_flags_if_supported)
+  foreach(flag ${ARGN})
+    mangle_name("${flag}" flagname)
+    check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
+    add_link_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag})
+  endforeach()
+endmacro()
+
+# Add a list of libraries or link flags to 'LIBCXX_LIBRARIES'.
+macro(add_library_flags)
+  foreach(lib ${ARGN})
+    list(APPEND LIBCXX_LIBRARIES ${lib})
+  endforeach()
+endmacro()
+
+# if 'condition' is true then add the specified list of libraries and flags
+# to 'LIBCXX_LIBRARIES'.
+macro(add_library_flags_if condition)
+  if(${condition})
+    add_library_flags(${ARGN})
+  endif()
+endmacro()
+
+# Turn a comma separated CMake list into a space separated string.
+macro(split_list listname)
+  string(REPLACE ";" " " ${listname} "${${listname}}")
+endmacro()
+
+# For each specified flag, add that link flag to the provided target.
+# The flags are added with the given visibility, i.e. PUBLIC|PRIVATE|INTERFACE.
+function(target_add_link_flags_if_supported target visibility)
+  foreach(flag ${ARGN})
+    mangle_name("${flag}" flagname)
+    check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
+    if (LIBCXX_SUPPORTS_${flagname}_FLAG)
+      target_link_libraries(${target} ${visibility} ${flag})
+    endif()
+  endforeach()
+endfunction()
+
+# For each specified flag, add that compile flag to the provided target.
+# The flags are added with the given visibility, i.e. PUBLIC|PRIVATE|INTERFACE.
+function(target_add_compile_flags_if_supported target visibility)
+  foreach(flag ${ARGN})
+    mangle_name("${flag}" flagname)
+    check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
+    if (LIBCXX_SUPPORTS_${flagname}_FLAG)
+      target_compile_options(${target} ${visibility} ${flag})
+    endif()
+  endforeach()
+endfunction()
diff --git a/cmake/Modules/HandleOutOfTreeLLVM.cmake b/cmake/Modules/HandleOutOfTreeLLVM.cmake
new file mode 100644
index 0000000..ad2820b
--- /dev/null
+++ b/cmake/Modules/HandleOutOfTreeLLVM.cmake
@@ -0,0 +1,78 @@
+if (NOT DEFINED LLVM_PATH)
+  set(LLVM_PATH ${CMAKE_CURRENT_LIST_DIR}/../../../llvm CACHE PATH "" FORCE)
+endif()
+
+if(NOT IS_DIRECTORY ${LLVM_PATH})
+  message(FATAL_ERROR
+    "The provided LLVM_PATH (${LLVM_PATH}) is not a valid directory. Note that "
+    "building libc++ outside of the monorepo is not supported anymore. Please "
+    "use a Standalone build against the monorepo, a Runtimes build or a classic "
+    "monorepo build.")
+endif()
+
+set(LLVM_INCLUDE_DIR ${LLVM_PATH}/include CACHE PATH "Path to llvm/include")
+set(LLVM_PATH ${LLVM_PATH} CACHE PATH "Path to LLVM source tree")
+set(LLVM_MAIN_SRC_DIR ${LLVM_PATH})
+set(LLVM_CMAKE_PATH "${LLVM_PATH}/cmake/modules")
+
+if (EXISTS "${LLVM_CMAKE_PATH}")
+  list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
+elseif (EXISTS "${LLVM_MAIN_SRC_DIR}/cmake/modules")
+  list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules")
+else()
+  message(FATAL_ERROR "Neither ${LLVM_CMAKE_PATH} nor ${LLVM_MAIN_SRC_DIR}/cmake/modules found. "
+                      "This is not a supported configuration.")
+endif()
+
+message(STATUS "Configuring for standalone build.")
+
+# By default, we target the host, but this can be overridden at CMake invocation time.
+include(GetHostTriple)
+get_host_triple(LLVM_INFERRED_HOST_TRIPLE)
+set(LLVM_HOST_TRIPLE "${LLVM_INFERRED_HOST_TRIPLE}" CACHE STRING "Host on which LLVM binaries will run")
+set(LLVM_DEFAULT_TARGET_TRIPLE "${LLVM_HOST_TRIPLE}" CACHE STRING "Target triple used by default.")
+
+# Add LLVM Functions --------------------------------------------------------
+if (WIN32)
+  set(LLVM_ON_UNIX 0)
+  set(LLVM_ON_WIN32 1)
+else()
+  set(LLVM_ON_UNIX 1)
+  set(LLVM_ON_WIN32 0)
+endif()
+
+include(AddLLVM OPTIONAL)
+
+# LLVM Options --------------------------------------------------------------
+if (NOT DEFINED LLVM_INCLUDE_TESTS)
+  set(LLVM_INCLUDE_TESTS ON)
+endif()
+if (NOT DEFINED LLVM_INCLUDE_DOCS)
+  set(LLVM_INCLUDE_DOCS ON)
+endif()
+if (NOT DEFINED LLVM_ENABLE_SPHINX)
+  set(LLVM_ENABLE_SPHINX OFF)
+endif()
+
+if (LLVM_INCLUDE_TESTS)
+  # Required LIT Configuration ------------------------------------------------
+  # Define the default arguments to use with 'lit', and an option for the user
+  # to override.
+  set(LLVM_DEFAULT_EXTERNAL_LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py")
+  set(LIT_ARGS_DEFAULT "-sv --show-xfail --show-unsupported")
+  if (MSVC OR XCODE)
+    set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar")
+  endif()
+  set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
+endif()
+
+# Required doc configuration
+if (LLVM_ENABLE_SPHINX)
+  find_package(Sphinx REQUIRED)
+endif()
+
+if (LLVM_ON_UNIX AND NOT APPLE)
+  set(LLVM_HAVE_LINK_VERSION_SCRIPT 1)
+else()
+  set(LLVM_HAVE_LINK_VERSION_SCRIPT 0)
+endif()
diff --git a/cmake/caches/AArch64.cmake b/cmake/caches/AArch64.cmake
new file mode 100644
index 0000000..33356a7
--- /dev/null
+++ b/cmake/caches/AArch64.cmake
@@ -0,0 +1,2 @@
+set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
+set(LIBCXX_TARGET_TRIPLE "aarch64-linux-gnu" CACHE STRING "")
diff --git a/cmake/caches/Apple.cmake b/cmake/caches/Apple.cmake
new file mode 100644
index 0000000..c884eb5
--- /dev/null
+++ b/cmake/caches/Apple.cmake
@@ -0,0 +1,20 @@
+set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "")
+set(CMAKE_POSITION_INDEPENDENT_CODE OFF CACHE BOOL "")
+
+set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
+set(LIBCXX_ENABLE_ASSERTIONS OFF CACHE BOOL "")
+set(LIBCXX_ABI_VERSION "1" CACHE STRING "")
+set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "")
+set(LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
+set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "")
+set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "")
+set(LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT ON CACHE BOOL "")
+set(LIBCXX_ENABLE_DEBUG_MODE_SUPPORT OFF CACHE BOOL "")
+set(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS ON CACHE BOOL "")
+set(LIBCXX_ENABLE_INCOMPLETE_FEATURES OFF CACHE BOOL "")
+
+set(LIBCXX_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "")
+set(LIBCXXABI_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "")
+
+set(LIBCXXABI_ENABLE_ASSERTIONS OFF CACHE BOOL "")
+set(LIBCXXABI_ENABLE_FORGIVING_DYNAMIC_CAST ON CACHE BOOL "")
diff --git a/cmake/caches/Armv7Arm.cmake b/cmake/caches/Armv7Arm.cmake
new file mode 100644
index 0000000..8b2b54e
--- /dev/null
+++ b/cmake/caches/Armv7Arm.cmake
@@ -0,0 +1,4 @@
+set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
+set(LIBCXX_TARGET_TRIPLE "armv7-linux-gnueabihf" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "-marm" CACHE STRING "")
+set(CMAKE_C_FLAGS "-marm" CACHE STRING "")
diff --git a/cmake/caches/Armv7Thumb-noexceptions.cmake b/cmake/caches/Armv7Thumb-noexceptions.cmake
new file mode 100644
index 0000000..67ec43b
--- /dev/null
+++ b/cmake/caches/Armv7Thumb-noexceptions.cmake
@@ -0,0 +1,6 @@
+set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
+set(LIBCXX_TARGET_TRIPLE "armv7-linux-gnueabihf" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "-mthumb" CACHE STRING "")
+set(CMAKE_C_FLAGS "-mthumb" CACHE STRING "")
+set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
+set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
diff --git a/cmake/caches/Armv8Arm.cmake b/cmake/caches/Armv8Arm.cmake
new file mode 100644
index 0000000..55dfa90
--- /dev/null
+++ b/cmake/caches/Armv8Arm.cmake
@@ -0,0 +1,4 @@
+set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
+set(LIBCXX_TARGET_TRIPLE "armv8-linux-gnueabihf" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "-marm" CACHE STRING "")
+set(CMAKE_C_FLAGS "-marm" CACHE STRING "")
diff --git a/cmake/caches/Armv8Thumb-noexceptions.cmake b/cmake/caches/Armv8Thumb-noexceptions.cmake
new file mode 100644
index 0000000..fb1d10e
--- /dev/null
+++ b/cmake/caches/Armv8Thumb-noexceptions.cmake
@@ -0,0 +1,6 @@
+set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
+set(LIBCXX_TARGET_TRIPLE "armv8-linux-gnueabihf" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "-mthumb" CACHE STRING "")
+set(CMAKE_C_FLAGS "-mthumb" CACHE STRING "")
+set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
+set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
diff --git a/cmake/caches/FreeBSD.cmake b/cmake/caches/FreeBSD.cmake
new file mode 100644
index 0000000..9e66e37
--- /dev/null
+++ b/cmake/caches/FreeBSD.cmake
@@ -0,0 +1,9 @@
+set(CMAKE_BUILD_TYPE Release CACHE STRING "")
+set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "")
+
+set(LIBCXX_ENABLE_ASSERTIONS OFF CACHE BOOL "")
+set(LIBCXX_ABI_VERSION "1" CACHE STRING "")
+set(LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
+set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "")
+set(LIBCXX_CXX_ABI libcxxrt CACHE STRING "")
+set(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON CACHE BOOL "")
diff --git a/cmake/caches/Generic-32bits.cmake b/cmake/caches/Generic-32bits.cmake
new file mode 100644
index 0000000..ae7b2ac
--- /dev/null
+++ b/cmake/caches/Generic-32bits.cmake
@@ -0,0 +1 @@
+set(LLVM_BUILD_32_BITS ON CACHE BOOL "")
diff --git a/cmake/caches/Generic-asan.cmake b/cmake/caches/Generic-asan.cmake
new file mode 100644
index 0000000..cf91976
--- /dev/null
+++ b/cmake/caches/Generic-asan.cmake
@@ -0,0 +1 @@
+set(LLVM_USE_SANITIZER "Address" CACHE STRING "")
diff --git a/cmake/caches/Generic-assertions.cmake b/cmake/caches/Generic-assertions.cmake
new file mode 100644
index 0000000..e8ef72a
--- /dev/null
+++ b/cmake/caches/Generic-assertions.cmake
@@ -0,0 +1 @@
+set(LIBCXX_ENABLE_ASSERTIONS ON CACHE BOOL "")
diff --git a/cmake/caches/Generic-cxx03.cmake b/cmake/caches/Generic-cxx03.cmake
new file mode 100644
index 0000000..5edb1c4
--- /dev/null
+++ b/cmake/caches/Generic-cxx03.cmake
@@ -0,0 +1,2 @@
+set(LIBCXX_TEST_PARAMS "std=c++03" CACHE STRING "")
+set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
diff --git a/cmake/caches/Generic-cxx11.cmake b/cmake/caches/Generic-cxx11.cmake
new file mode 100644
index 0000000..f0f89c4
--- /dev/null
+++ b/cmake/caches/Generic-cxx11.cmake
@@ -0,0 +1,2 @@
+set(LIBCXX_TEST_PARAMS "std=c++11" CACHE STRING "")
+set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
diff --git a/cmake/caches/Generic-cxx14.cmake b/cmake/caches/Generic-cxx14.cmake
new file mode 100644
index 0000000..29c688d
--- /dev/null
+++ b/cmake/caches/Generic-cxx14.cmake
@@ -0,0 +1,2 @@
+set(LIBCXX_TEST_PARAMS "std=c++14" CACHE STRING "")
+set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
diff --git a/cmake/caches/Generic-cxx17.cmake b/cmake/caches/Generic-cxx17.cmake
new file mode 100644
index 0000000..35bac92
--- /dev/null
+++ b/cmake/caches/Generic-cxx17.cmake
@@ -0,0 +1,2 @@
+set(LIBCXX_TEST_PARAMS "std=c++17" CACHE STRING "")
+set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
diff --git a/cmake/caches/Generic-cxx20.cmake b/cmake/caches/Generic-cxx20.cmake
new file mode 100644
index 0000000..3c44fda
--- /dev/null
+++ b/cmake/caches/Generic-cxx20.cmake
@@ -0,0 +1,2 @@
+set(LIBCXX_TEST_PARAMS "std=c++20" CACHE STRING "")
+set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
diff --git a/cmake/caches/Generic-cxx2b.cmake b/cmake/caches/Generic-cxx2b.cmake
new file mode 100644
index 0000000..be767dd
--- /dev/null
+++ b/cmake/caches/Generic-cxx2b.cmake
@@ -0,0 +1,2 @@
+set(LIBCXX_TEST_PARAMS "std=c++2b" CACHE STRING "")
+set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
diff --git a/cmake/caches/Generic-debug-iterators.cmake b/cmake/caches/Generic-debug-iterators.cmake
new file mode 100644
index 0000000..2e9cbf7
--- /dev/null
+++ b/cmake/caches/Generic-debug-iterators.cmake
@@ -0,0 +1,2 @@
+set(LIBCXX_TEST_PARAMS "debug_level=1" "additional_features=LIBCXX-DEBUG-FIXME" CACHE STRING "")
+set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
diff --git a/cmake/caches/Generic-modules.cmake b/cmake/caches/Generic-modules.cmake
new file mode 100644
index 0000000..29b4d4b
--- /dev/null
+++ b/cmake/caches/Generic-modules.cmake
@@ -0,0 +1,2 @@
+set(LIBCXX_TEST_PARAMS "enable_modules=True" CACHE STRING "")
+set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
diff --git a/cmake/caches/Generic-msan.cmake b/cmake/caches/Generic-msan.cmake
new file mode 100644
index 0000000..7c948f5
--- /dev/null
+++ b/cmake/caches/Generic-msan.cmake
@@ -0,0 +1 @@
+set(LLVM_USE_SANITIZER "MemoryWithOrigins" CACHE STRING "")
diff --git a/cmake/caches/Generic-no-debug.cmake b/cmake/caches/Generic-no-debug.cmake
new file mode 100644
index 0000000..a62760f
--- /dev/null
+++ b/cmake/caches/Generic-no-debug.cmake
@@ -0,0 +1 @@
+set(LIBCXX_ENABLE_DEBUG_MODE_SUPPORT OFF CACHE BOOL "")
diff --git a/cmake/caches/Generic-no-filesystem.cmake b/cmake/caches/Generic-no-filesystem.cmake
new file mode 100644
index 0000000..4000f3a
--- /dev/null
+++ b/cmake/caches/Generic-no-filesystem.cmake
@@ -0,0 +1 @@
+set(LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
diff --git a/cmake/caches/Generic-no-localization.cmake b/cmake/caches/Generic-no-localization.cmake
new file mode 100644
index 0000000..79d6b44
--- /dev/null
+++ b/cmake/caches/Generic-no-localization.cmake
@@ -0,0 +1 @@
+set(LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
diff --git a/cmake/caches/Generic-no-random_device.cmake b/cmake/caches/Generic-no-random_device.cmake
new file mode 100644
index 0000000..e9b4cc6
--- /dev/null
+++ b/cmake/caches/Generic-no-random_device.cmake
@@ -0,0 +1 @@
+set(LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
diff --git a/cmake/caches/Generic-noexceptions.cmake b/cmake/caches/Generic-noexceptions.cmake
new file mode 100644
index 0000000..f0dffef
--- /dev/null
+++ b/cmake/caches/Generic-noexceptions.cmake
@@ -0,0 +1,2 @@
+set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
+set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
diff --git a/cmake/caches/Generic-singlethreaded.cmake b/cmake/caches/Generic-singlethreaded.cmake
new file mode 100644
index 0000000..616baef
--- /dev/null
+++ b/cmake/caches/Generic-singlethreaded.cmake
@@ -0,0 +1,3 @@
+set(LIBCXX_ENABLE_THREADS OFF CACHE BOOL "")
+set(LIBCXXABI_ENABLE_THREADS OFF CACHE BOOL "")
+set(LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "")
diff --git a/cmake/caches/Generic-static.cmake b/cmake/caches/Generic-static.cmake
new file mode 100644
index 0000000..ed2bf85
--- /dev/null
+++ b/cmake/caches/Generic-static.cmake
@@ -0,0 +1,3 @@
+set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
+set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "")
+set(LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "")
diff --git a/cmake/caches/Generic-tsan.cmake b/cmake/caches/Generic-tsan.cmake
new file mode 100644
index 0000000..a4b599e
--- /dev/null
+++ b/cmake/caches/Generic-tsan.cmake
@@ -0,0 +1 @@
+set(LLVM_USE_SANITIZER "Thread" CACHE STRING "")
diff --git a/cmake/caches/Generic-ubsan.cmake b/cmake/caches/Generic-ubsan.cmake
new file mode 100644
index 0000000..7ad891e
--- /dev/null
+++ b/cmake/caches/Generic-ubsan.cmake
@@ -0,0 +1,2 @@
+set(LLVM_USE_SANITIZER "Undefined" CACHE STRING "")
+set(LIBCXX_ABI_UNSTABLE ON CACHE BOOL "")
diff --git a/cmake/caches/README.md b/cmake/caches/README.md
new file mode 100644
index 0000000..60837ee
--- /dev/null
+++ b/cmake/caches/README.md
@@ -0,0 +1,13 @@
+# libc++ / libc++abi configuration caches
+
+This directory contains CMake caches for the supported configurations of libc++.
+Some of the configurations are specific to a vendor, others are generic and not
+tied to any vendor.
+
+While we won't explicitly work to break configurations not listed here, any
+configuration not listed here is not explicitly supported. If you use or ship
+libc++ under a configuration not listed here, you should work with the libc++
+maintainers to make it into a supported configuration and add it here.
+
+Similarly, adding any new configuration that's not already covered must be
+discussed with the libc++ maintainers as it entails a maintenance burden.
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index e8adafd..a2f1ff9 100644
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -1,32 +1,118 @@
+include(CMakePushCheckState)
 include(CheckLibraryExists)
+include(CheckCCompilerFlag)
 include(CheckCXXCompilerFlag)
+include(CheckCSourceCompiles)
 
-# Check compiler flags
-check_cxx_compiler_flag(-std=c++0x            LIBCXX_HAS_STDCXX0X_FLAG)
-check_cxx_compiler_flag(-fPIC                 LIBCXX_HAS_FPIC_FLAG)
-check_cxx_compiler_flag(-nodefaultlibs        LIBCXX_HAS_NODEFAULTLIBS_FLAG)
-check_cxx_compiler_flag(-nostdinc++           LIBCXX_HAS_NOSTDINCXX_FLAG)
-check_cxx_compiler_flag(-Wall                 LIBCXX_HAS_WALL_FLAG)
-check_cxx_compiler_flag(-W                    LIBCXX_HAS_W_FLAG)
-check_cxx_compiler_flag(-Wno-unused-parameter LIBCXX_HAS_WNO_UNUSED_PARAMETER_FLAG)
-check_cxx_compiler_flag(-Wwrite-strings       LIBCXX_HAS_WWRITE_STRINGS_FLAG)
-check_cxx_compiler_flag(-Wno-long-long        LIBCXX_HAS_WNO_LONG_LONG_FLAG)
-check_cxx_compiler_flag(-pedantic             LIBCXX_HAS_PEDANTIC_FLAG)
-check_cxx_compiler_flag(-Werror               LIBCXX_HAS_WERROR_FLAG)
-check_cxx_compiler_flag(-Wno-error            LIBCXX_HAS_WNO_ERROR_FLAG)
-check_cxx_compiler_flag(-fno-exceptions       LIBCXX_HAS_FNO_EXCEPTIONS_FLAG)
-check_cxx_compiler_flag(-fno-rtti             LIBCXX_HAS_FNO_RTTI_FLAG)
-check_cxx_compiler_flag(/WX                   LIBCXX_HAS_WX_FLAG)
-check_cxx_compiler_flag(/WX-                  LIBCXX_HAS_NO_WX_FLAG)
-check_cxx_compiler_flag(/EHsc                 LIBCXX_HAS_EHSC_FLAG)
-check_cxx_compiler_flag(/EHs-                 LIBCXX_HAS_NO_EHS_FLAG)
-check_cxx_compiler_flag(/EHa-                 LIBCXX_HAS_NO_EHA_FLAG)
-check_cxx_compiler_flag(/GR-                  LIBCXX_HAS_NO_GR_FLAG)
+if(WIN32 AND NOT MINGW)
+  # NOTE(compnerd) this is technically a lie, there is msvcrt, but for now, lets
+  # let the default linking take care of that.
+  set(LIBCXX_HAS_C_LIB NO)
+else()
+  check_library_exists(c fopen "" LIBCXX_HAS_C_LIB)
+endif()
+
+if (NOT LIBCXX_USE_COMPILER_RT)
+  if(WIN32 AND NOT MINGW)
+    set(LIBCXX_HAS_GCC_S_LIB NO)
+  else()
+    if(ANDROID)
+      check_library_exists(gcc __gcc_personality_v0 "" LIBCXX_HAS_GCC_LIB)
+    else()
+      check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB)
+    endif()
+  endif()
+endif()
+
+# libc++ is using -nostdlib++ at the link step when available,
+# otherwise -nodefaultlibs is used. We want all our checks to also
+# use one of these options, otherwise we may end up with an inconsistency between
+# the flags we think we require during configuration (if the checks are
+# performed without one of those options) and the flags that are actually
+# required during compilation (which has the -nostdlib++ or -nodefaultlibs). libc is
+# required for the link to go through. We remove sanitizers from the
+# configuration checks to avoid spurious link errors.
+
+check_c_compiler_flag(-nostdlib++ LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG)
+if (LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG)
+  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdlib++")
+else()
+  check_c_compiler_flag(-nodefaultlibs LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG)
+  if (LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG)
+    set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs")
+  endif()
+endif()
+
+if (LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG OR LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG)
+  if (LIBCXX_HAS_C_LIB)
+    list(APPEND CMAKE_REQUIRED_LIBRARIES c)
+  endif ()
+  if (LIBCXX_USE_COMPILER_RT)
+    list(APPEND CMAKE_REQUIRED_FLAGS -rtlib=compiler-rt)
+    find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY)
+    list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBCXX_BUILTINS_LIBRARY}")
+  elseif (LIBCXX_HAS_GCC_LIB)
+    list(APPEND CMAKE_REQUIRED_LIBRARIES gcc)
+  elseif (LIBCXX_HAS_GCC_S_LIB)
+    list(APPEND CMAKE_REQUIRED_LIBRARIES gcc_s)
+  endif ()
+  if (MINGW)
+    # Mingw64 requires quite a few "C" runtime libraries in order for basic
+    # programs to link successfully with -nodefaultlibs.
+    if (LIBCXX_USE_COMPILER_RT)
+      set(MINGW_RUNTIME ${LIBCXX_BUILTINS_LIBRARY})
+    else ()
+      set(MINGW_RUNTIME gcc_s gcc)
+    endif()
+    set(MINGW_LIBRARIES mingw32 ${MINGW_RUNTIME} moldname mingwex msvcrt advapi32
+                        shell32 user32 kernel32 mingw32 ${MINGW_RUNTIME}
+                        moldname mingwex msvcrt)
+    list(APPEND CMAKE_REQUIRED_LIBRARIES ${MINGW_LIBRARIES})
+  endif()
+  if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize)
+    set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all")
+  endif ()
+  if (CMAKE_C_FLAGS MATCHES -fsanitize-coverage OR CMAKE_CXX_FLAGS MATCHES -fsanitize-coverage)
+    set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters")
+  endif ()
+endif ()
+
+# Check compiler pragmas
+if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+  cmake_push_check_state()
+  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror=unknown-pragmas")
+  check_c_source_compiles("
+#pragma comment(lib, \"c\")
+int main() { return 0; }
+" LIBCXX_HAS_COMMENT_LIB_PRAGMA)
+  cmake_pop_check_state()
+endif()
 
 # Check libraries
-check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB)
-check_library_exists(c printf "" 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)
-
+if(WIN32 AND NOT MINGW)
+  # TODO(compnerd) do we want to support an emulation layer that allows for the
+  # use of pthread-win32 or similar libraries to emulate pthreads on Windows?
+  set(LIBCXX_HAS_PTHREAD_LIB NO)
+  set(LIBCXX_HAS_M_LIB NO)
+  set(LIBCXX_HAS_RT_LIB NO)
+  set(LIBCXX_HAS_SYSTEM_LIB NO)
+  set(LIBCXX_HAS_ATOMIC_LIB NO)
+elseif(APPLE)
+  check_library_exists(System write "" LIBCXX_HAS_SYSTEM_LIB)
+  set(LIBCXX_HAS_PTHREAD_LIB NO)
+  set(LIBCXX_HAS_M_LIB NO)
+  set(LIBCXX_HAS_RT_LIB NO)
+  set(LIBCXX_HAS_ATOMIC_LIB NO)
+elseif(FUCHSIA)
+  set(LIBCXX_HAS_M_LIB NO)
+  set(LIBCXX_HAS_PTHREAD_LIB NO)
+  set(LIBCXX_HAS_RT_LIB NO)
+  set(LIBCXX_HAS_SYSTEM_LIB NO)
+  check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
+else()
+  check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB)
+  check_library_exists(m ccos "" LIBCXX_HAS_M_LIB)
+  check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB)
+  set(LIBCXX_HAS_SYSTEM_LIB NO)
+  check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
+endif()
diff --git a/docs/AddingNewCIJobs.rst b/docs/AddingNewCIJobs.rst
new file mode 100644
index 0000000..bd94a9d
--- /dev/null
+++ b/docs/AddingNewCIJobs.rst
@@ -0,0 +1,68 @@
+.. _AddingNewCIJobs:
+
+==================
+Adding New CI Jobs
+==================
+
+.. contents::
+  :local:
+
+Adding The Job
+==============
+
+libc++ uses Buildkite for running its CI. Setting up new CI jobs is easy, and
+these jobs can run either on our existing infrastructure, or on your own.
+
+If you need to run the job on your own machines, please follow the
+`Buildkite guide <https://buildkite.com/docs/agent/v3>`_ to setup your
+own agents. Make sure you tag your agents in a way that you'll be able
+to recognize them when defining your job below. Finally, in order for the
+agent to register itself to Buildkite, it will need a BuildKite Agent token.
+Please contact a maintainer to get your token.
+
+Then, simply add a job to the Buildkite pipeline by editing ``libcxx/utils/ci/buildkite-pipeline.yml``.
+Take a look at how the surrounding jobs are defined and do something similar.
+An example of a job definition is:
+
+.. code-block:: yaml
+
+  - label: "C++11"
+    command: "libcxx/utils/ci/run-buildbot generic-cxx11"
+    artifact_paths:
+      - "**/test-results.xml"
+    agents:
+      queue: "libcxx-builders"
+      os: "linux"
+    retry:
+      automatic:
+        - exit_status: -1  # Agent was lost
+          limit: 2
+
+If you create your own agents, put them in the ``libcxx-builders`` queue and
+use agent tags to allow targetting your agents from the Buildkite pipeline
+config appropriately.
+
+We try to keep the pipeline definition file as simple as possible, and to
+keep any script used for CI inside ``libcxx/utils/ci``. This ensures that
+it's possible to reproduce CI issues locally with ease, understanding of
+course that some setups may require access to special hardware that is not
+available.
+
+Testing Your New Job
+====================
+
+Testing your new job is easy -- once your agent is set up (if any), just open
+a code review and the libc++ CI pipeline will run, including any changes you
+might have made to the pipeline definition itself.
+
+Service Level Agreement
+=======================
+
+To keep the libc++ CI useful for everyone, we aim for a quick turnaround time
+for all CI jobs. This allows the overall pipeline to finish in a reasonable
+amount of time, which is important because it directly affects our development
+velocity. We also try to make sure that jobs run on reliable infrastructure in
+order to avoid flaky failures, which reduce the value of CI for everyone.
+
+We may be reluctant to add and support CI jobs that take a long time to finish
+or that are too flaky.
diff --git a/docs/BuildingLibcxx.rst b/docs/BuildingLibcxx.rst
new file mode 100644
index 0000000..a29a05b
--- /dev/null
+++ b/docs/BuildingLibcxx.rst
@@ -0,0 +1,563 @@
+.. _BuildingLibcxx:
+
+===============
+Building libc++
+===============
+
+.. contents::
+  :local:
+
+.. _build instructions:
+
+The instructions on this page are aimed at vendors who ship libc++ as part of an
+operating system distribution, a toolchain or similar shipping vehicules. If you
+are a user merely trying to use libc++ in your program, you most likely want to
+refer to your vendor's documentation, or to the general documentation for using
+libc++ :ref:`here <using-libcxx>`.
+
+.. warning::
+  If your operating system already provides libc++, it is important to be careful
+  not to replace it. Replacing your system's libc++ installation could render it
+  non-functional. Use the CMake option ``CMAKE_INSTALL_PREFIX`` to select a safe
+  place to install libc++.
+
+
+The default build
+=================
+
+By default, libc++ and libc++abi are built as sub-projects of the LLVM project.
+This can be achieved with the usual CMake invocation:
+
+.. code-block:: bash
+
+  $ git clone https://github.com/llvm/llvm-project.git
+  $ cd llvm-project
+  $ mkdir build
+  $ cmake -G Ninja -S llvm -B build -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" # Configure
+  $ ninja -C build cxx cxxabi                                                 # Build
+  $ ninja -C build check-cxx check-cxxabi                                     # Test
+  $ ninja -C build install-cxx install-cxxabi                                 # Install
+
+.. note::
+  See :ref:`CMake Options` below for more configuration options.
+
+After building the ``install-cxx`` and ``install-cxxabi`` targets, shared libraries
+for libc++ and libc++abi should now be present in ``<CMAKE_INSTALL_PREFIX>/lib``, and
+headers in ``<CMAKE_INSTALL_PREFIX>/include/c++/v1``. See :ref:`using an alternate
+libc++ installation <alternate libcxx>` for information on how to use this libc++ over
+the default one.
+
+In the default configuration, libc++ and libc++abi will be built using the compiler available
+by default on your system. It is also possible to bootstrap Clang and build libc++ with it.
+
+
+Bootstrapping build
+===================
+
+It is also possible to build Clang and then build libc++ and libc++abi using that
+just-built compiler. This is the correct way to build libc++ when putting together
+a toolchain, or when the system compiler is not adequate to build libc++ (too old,
+unsupported, etc.). This type of build is also commonly called a "Runtimes build":
+
+.. code-block:: bash
+
+  $ mkdir build
+  $ cmake -G Ninja -S llvm -B build -DLLVM_ENABLE_PROJECTS="clang"            \  # Configure
+                                    -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
+                                    -DLLVM_RUNTIME_TARGETS="<target-triple>"
+  $ ninja -C build runtimes                                                      # Build
+  $ ninja -C build check-runtimes                                                # Test
+  $ ninja -C build install-runtimes                                              # Install
+
+
+Support for Windows
+===================
+
+libcxx supports being built with clang-cl, but not with MSVC's cl.exe, as
+cl doesn't support the ``#include_next`` extension. Furthermore, VS 2017 or
+newer (19.14) is required.
+
+libcxx also supports being built with clang targeting MinGW environments.
+
+CMake + Visual Studio
+---------------------
+
+Building with Visual Studio currently does not permit running tests. However,
+it is the simplest way to build.
+
+.. code-block:: batch
+
+  > cmake -G "Visual Studio 16 2019" -S libcxx -B build ^
+          -T "ClangCL"                                  ^
+          -DLIBCXX_ENABLE_SHARED=YES                    ^
+          -DLIBCXX_ENABLE_STATIC=NO                     ^
+          -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO
+  > cmake --build build
+
+CMake + ninja (MSVC)
+--------------------
+
+Building with ninja is required for development to enable tests.
+A couple of tests require Bash to be available, and a couple dozens
+of tests require other posix tools (cp, grep and similar - LLVM's tests
+require the same). Without those tools the vast majority of tests
+can still be ran successfully.
+
+If Git for Windows is available, that can be used to provide the bash
+shell by adding the right bin directory to the path, e.g.
+``set PATH=%PATH%;C:\Program Files\Git\usr\bin``.
+
+Alternatively, one can also choose to run the whole build in a MSYS2
+shell. That can be set up e.g. by starting a Visual Studio Tools Command
+Prompt (for getting the environment variables pointing to the headers and
+import libraries), and making sure that clang-cl is available in the
+path. From there, launch an MSYS2 shell via e.g.
+``C:\msys64\msys2_shell.cmd -full-path -mingw64`` (preserving the earlier
+environment, allowing the MSVC headers/libraries and clang-cl to be found).
+
+In either case, then run:
+
+.. code-block:: batch
+
+  > cmake -G Ninja -S libcxx -B build                                                 ^
+          -DCMAKE_C_COMPILER=clang-cl                                                 ^
+          -DCMAKE_CXX_COMPILER=clang-cl                                               ^
+          -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO
+  > ninja -C build cxx
+  > ninja -C build check-cxx
+
+If you are running in an MSYS2 shell and you have installed the
+MSYS2-provided clang package (which defaults to a non-MSVC target), you
+should add e.g. ``-DLIBCXX_TARGET_TRIPLE=x86_64-windows-msvc`` (replacing
+``x86_64`` with the architecture you're targeting) to the ``cmake`` command
+line above. This will instruct ``check-cxx`` to use the right target triple
+when invoking ``clang++``.
+
+Also note that if not building in Release mode, a failed assert in the tests
+pops up a blocking dialog box, making it hard to run a larger number of tests.
+
+CMake + ninja (MinGW)
+---------------------
+
+libcxx can also be built in MinGW environments, e.g. with the MinGW
+compilers in MSYS2. This requires clang to be available (installed with
+e.g. the ``mingw-w64-x86_64-clang`` package), together with CMake and ninja.
+
+.. code-block:: bash
+
+  > cmake -G Ninja -S libcxx -B build                                                 \
+          -DCMAKE_C_COMPILER=clang                                                    \
+          -DCMAKE_CXX_COMPILER=clang++                                                \
+          -DLIBCXX_HAS_WIN32_THREAD_API=ON                                            \
+          -DLIBCXX_CXX_ABI=libstdc++                                                  \
+          -DLIBCXX_TARGET_INFO="libcxx.test.target_info.MingwLocalTI"
+  > ninja -C build cxx
+  > cp /mingw64/bin/{libstdc++-6,libgcc_s_seh-1,libwinpthread-1}.dll lib
+  > ninja -C build check-cxx
+
+As this build configuration ends up depending on a couple other DLLs that
+aren't available in path while running tests, copy them into the same
+directory as the tested libc++ DLL.
+
+(Building a libc++ that depends on libstdc++ isn't necessarily a config one
+would want to deploy, but it simplifies the config for testing purposes.)
+
+.. _`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**: ``OFF``
+
+  Build libc++ with assertions enabled.
+
+.. option:: LIBCXX_BUILD_32_BITS:BOOL
+
+  **Default**: ``OFF``
+
+  Build libc++ as a 32 bit library. Also see `LLVM_BUILD_32_BITS`.
+
+.. option:: LIBCXX_ENABLE_SHARED:BOOL
+
+  **Default**: ``ON``
+
+  Build libc++ as a shared library. Either `LIBCXX_ENABLE_SHARED` or
+  `LIBCXX_ENABLE_STATIC` has to be enabled.
+
+.. option:: LIBCXX_ENABLE_STATIC:BOOL
+
+  **Default**: ``ON``
+
+  Build libc++ as a static library. Either `LIBCXX_ENABLE_SHARED` or
+  `LIBCXX_ENABLE_STATIC` has to be enabled.
+
+.. option:: LIBCXX_LIBDIR_SUFFIX:STRING
+
+  Extra suffix to append to the directory where libraries are to be installed.
+  This option overrides `LLVM_LIBDIR_SUFFIX`.
+
+.. option:: LIBCXX_HERMETIC_STATIC_LIBRARY:BOOL
+
+  **Default**: ``OFF``
+
+  Do not export any symbols from the static libc++ library.
+  This is useful when the static libc++ library is being linked into shared
+  libraries that may be used in with other shared libraries that use different
+  C++ library. We want to avoid exporting any libc++ symbols in that case.
+
+.. option:: LIBCXX_ENABLE_FILESYSTEM:BOOL
+
+   **Default**: ``ON`` except on Windows when using MSVC.
+
+   This option can be used to enable or disable the filesystem components on
+   platforms that may not support them. For example on Windows when using MSVC.
+
+.. option:: LIBCXX_ENABLE_INCOMPLETE_FEATURES:BOOL
+
+  **Default**: ``ON``
+
+  Whether to enable support for incomplete library features. Incomplete features
+  are new library features under development. These features don't guarantee
+  ABI stability nor the quality of completed library features. Vendors
+  shipping the library may want to disable this option.
+
+.. option:: LIBCXX_INSTALL_LIBRARY_DIR:PATH
+
+  **Default**: ``lib${LIBCXX_LIBDIR_SUFFIX}``
+
+  Path where built libc++ libraries should be installed. If a relative path,
+  relative to ``CMAKE_INSTALL_PREFIX``.
+
+.. option:: LIBCXX_INSTALL_INCLUDE_DIR:PATH
+
+  **Default**: ``include/c++/v1``
+
+  Path where target-agnostic libc++ headers should be installed. If a relative
+  path, relative to ``CMAKE_INSTALL_PREFIX``.
+
+.. option:: LIBCXX_INSTALL_INCLUDE_TARGET_DIR:PATH
+
+  **Default**: ``include/c++/v1`` or
+  ``include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1``
+
+  Path where target-specific libc++ headers should be installed. If a relative
+  path, relative to ``CMAKE_INSTALL_PREFIX``.
+
+.. _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**: ``LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY AND LIBCXX_INSTALL_LIBRARY``
+
+  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.
+
+.. option:: LIBCXX_INCLUDE_TESTS:BOOL
+
+  **Default**: ``ON`` (or value of ``LLVM_INCLUDE_TESTS``)
+
+  Build the libc++ tests.
+
+.. option:: LIBCXX_INCLUDE_BENCHMARKS:BOOL
+
+  **Default**: ``ON``
+
+  Build the libc++ benchmark tests and the Google Benchmark library needed
+  to support them.
+
+.. option:: LIBCXX_BENCHMARK_TEST_ARGS:STRING
+
+  **Default**: ``--benchmark_min_time=0.01``
+
+  A semicolon list of arguments to pass when running the libc++ benchmarks using the
+  ``check-cxx-benchmarks`` rule. By default we run the benchmarks for a very short amount of time,
+  since the primary use of ``check-cxx-benchmarks`` is to get test and sanitizer coverage, not to
+  get accurate measurements.
+
+.. option:: LIBCXX_BENCHMARK_NATIVE_STDLIB:STRING
+
+  **Default**:: ``""``
+
+  **Values**:: ``libc++``, ``libstdc++``
+
+  Build the libc++ benchmark tests and Google Benchmark library against the
+  specified standard library on the platform. On Linux this can be used to
+  compare libc++ to libstdc++ by building the benchmark tests against both
+  standard libraries.
+
+.. option:: LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN:STRING
+
+  Use the specified GCC toolchain and standard library when building the native
+  stdlib benchmark tests.
+
+.. option:: LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT:BOOL
+
+  **Default**: ``OFF``
+
+  Pick the default for whether to constrain ABI-unstable symbols to
+  each individual translation unit. This setting controls whether
+  `_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT` is defined by default --
+  see the documentation of that macro for details.
+
+
+libc++ ABI 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.
+
+.. option:: LIBCXX_ABI_NAMESPACE:STRING
+
+  **Default**: ``__n`` where ``n`` is the current ABI version.
+
+  This option defines the name of the inline ABI versioning namespace. It can be used for building
+  custom versions of libc++ with unique symbol names in order to prevent conflicts or ODR issues
+  with other libc++ versions.
+
+  .. warning::
+    When providing a custom namespace, it's the users responsibility to ensure the name won't cause
+    conflicts with other names defined by libc++, both now and in the future. In particular, inline
+    namespaces of the form ``__[0-9]+`` are strictly reserved by libc++ and may not be used by users.
+    Doing otherwise could cause conflicts and hinder libc++ ABI evolution.
+
+.. option:: LIBCXX_ABI_DEFINES:STRING
+
+  **Default**: ``""``
+
+  A semicolon-separated list of ABI macros to persist in the site config header.
+  See ``include/__config`` for the list of ABI macros.
+
+
+.. _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
+=============================
+
+In order to implement various features like exceptions, RTTI, ``dynamic_cast`` and
+more, libc++ requires what we refer to as an ABI library. Typically, that library
+implements the `Itanium C++ ABI <https://itanium-cxx-abi.github.io/cxx-abi/abi.html>`_.
+
+By default, libc++ uses libc++abi as an ABI library. However, it is possible to use
+other ABI libraries too.
+
+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 all platforms.
+
+We can now run CMake:
+
+.. code-block:: bash
+
+  $ cmake -G Ninja -S llvm -B build           \
+    -DLLVM_ENABLE_PROJECTS="libcxx"           \
+    -DLIBCXX_CXX_ABI=libstdc++                \
+    -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/"
+  $ ninja -C build install-cxx
+
+
+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.
+
+Using libcxxrt on Linux
+------------------------
+
+You will need to keep the source tree of `libcxxrt`_ available
+on your build machine and your copy of the libcxxrt shared library must
+be placed where your linker will find it.
+
+We can now run CMake like:
+
+.. code-block:: bash
+
+  $ cmake -G Ninja -S llvm -B build                                   \
+          -DLLVM_ENABLE_PROJECTS="libcxx"                             \
+          -DLIBCXX_CXX_ABI=libcxxrt                                   \
+          -DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/libcxxrt-sources/src
+  $ ninja -C build install-cxx
+
+Unfortunately you can't simply run clang with "-stdlib=libc++" at this point, as
+clang is set up to link for libc++ linked to libsupc++.  To get around this
+you'll have to set up your linker yourself (or patch clang).  For example,
+
+.. code-block:: bash
+
+  $ clang++ -stdlib=libc++ helloworld.cpp \
+            -nodefaultlibs -lc++ -lcxxrt -lm -lc -lgcc_s -lgcc
+
+Alternately, you could just add libcxxrt to your libraries list, which in most
+situations will give the same result:
+
+.. code-block:: bash
+
+  $ clang++ -stdlib=libc++ helloworld.cpp -lcxxrt
+
+.. _`libcxxrt`: https://github.com/libcxxrt/libcxxrt
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
new file mode 100644
index 0000000..d679761
--- /dev/null
+++ b/docs/CMakeLists.txt
@@ -0,0 +1,9 @@
+
+if (LLVM_ENABLE_SPHINX)
+  include(AddSphinxTarget)
+  if (SPHINX_FOUND)
+    if (${SPHINX_OUTPUT_HTML})
+      add_sphinx_target(html libcxx)
+    endif()
+  endif()
+endif()
diff --git a/docs/Contributing.rst b/docs/Contributing.rst
new file mode 100644
index 0000000..9d52445
--- /dev/null
+++ b/docs/Contributing.rst
@@ -0,0 +1,68 @@
+.. _ContributingToLibcxx:
+
+======================
+Contributing to libc++
+======================
+
+This file contains notes about various tasks and processes specific to contributing
+to libc++. If this is your first time contributing, please also read `this document
+<https://www.llvm.org/docs/Contributing.html>`__ on general rules for contributing to LLVM.
+
+For libc++, please make sure you follow `these instructions <https://www.llvm.org/docs/Phabricator.html#requesting-a-review-via-the-command-line>`_
+for submitting a code review from the command-line using ``arc``, since we have some
+automation (e.g. CI) that depends on the review being submitted that way.
+
+Looking for pre-existing reviews
+================================
+
+Before you start working on any feature, please take a look at the open reviews
+to avoid duplicating someone else's work. You can do that by going to the website
+where code reviews are held, `Differential <https://reviews.llvm.org/differential>`__,
+and clicking on ``Libc++ Open Reviews`` in the sidebar to the left. If you see
+that your feature is already being worked on, please consider chiming in instead
+of duplicating work!
+
+Pre-commit check list
+=====================
+
+Before committing or creating a review, please go through this check-list to make
+sure you don't forget anything:
+
+- Do you have tests for every public class and/or function you're adding or modifying?
+- Did you update the synopsis of the relevant headers?
+- Did you update the relevant files to track implementation status (in ``docs/Status/``)?
+- Did you mark all functions and type declarations with the :ref:`proper visibility macro <visibility-macros>`?
+- If you added a header:
+
+  - Did you add it to ``include/module.modulemap``?
+  - Did you add it to ``include/CMakeLists.txt``?
+  - If it's a public header, did you add a test under ``test/libcxx`` that the new header defines ``_LIBCPP_VERSION``? See ``test/libcxx/algorithms/version.pass.cpp`` for an example. NOTE: This should be automated.
+  - If it's a public header, did you update ``utils/generate_header_inclusion_tests.py``?
+
+- Did you add the relevant feature test macro(s) for your feature? Did you update the ``generate_feature_test_macro_components.py`` script with it?
+- Did you run the ``libcxx-generate-files`` target and verify its output?
+
+Post-release check list
+=======================
+
+After branching for an LLVM release:
+
+1. Update ``_LIBCPP_VERSION`` in ``include/__config``
+2. Update the ``include/__libcpp_version`` file
+3. Update the version number in ``docs/conf.py``
+
+Exporting new symbols from the library
+======================================
+
+When exporting new symbols from libc++, you must update the ABI lists located in ``lib/abi``.
+To test whether the lists are up-to-date, please run the target ``check-cxx-abilist``.
+To regenerate the lists, use the target ``generate-cxx-abilist``.
+The ABI lists must be updated for all supported platforms; currently Linux and
+Apple.  If you don't have access to one of these platforms, you can download an
+updated list from the failed build at
+`Buildkite <https://buildkite.com/llvm-project/libcxx-ci>`__.
+Look for the failed build and select the ``artifacts`` tab. There, download the
+abilist for the platform, e.g.:
+
+* C++20 for the Linux platform.
+* MacOS C++20 for the Apple platform.
diff --git a/docs/DesignDocs/ABIVersioning.rst b/docs/DesignDocs/ABIVersioning.rst
new file mode 100644
index 0000000..3b82f3c
--- /dev/null
+++ b/docs/DesignDocs/ABIVersioning.rst
@@ -0,0 +1,24 @@
+
+====================
+Libc++ ABI stability
+====================
+
+Libc++ aims to preserve a stable ABI to avoid subtle bugs when code built under the old ABI
+is linked with code built under the new ABI. At the same time, libc++ wants to make
+ABI-breaking improvements and bugfixes in scenarios where the user doesn't mind ABI breaks.
+
+To support both cases, libc++ allows specifying an ABI version at
+build time. The version is defined with CMake option ``LIBCXX_ABI_VERSION``.
+Currently supported values are ``1`` (the stable default)
+and ``2`` (the unstable "next" version). At some point "ABI version 2" will be
+frozen and new ABI-breaking changes will start being applied to version ``3``;
+but this has not happened yet.
+
+To always use the most cutting-edge, most unstable ABI (which is currently ``2``
+but at some point will become ``3``), set the CMake option ``LIBCXX_ABI_UNSTABLE``.
+
+Internally, each ABI-changing feature is placed under its own C++ macro,
+``_LIBCPP_ABI_XXX``. These macros' definitions are controlled by the C++ macro
+``_LIBCPP_ABI_VERSION``, which is controlled by the ``LIBCXX_ABI_VERSION`` set
+at build time. Libc++ does not intend users to interact with these C++ macros
+directly.
diff --git a/docs/DesignDocs/AtomicDesign.rst b/docs/DesignDocs/AtomicDesign.rst
new file mode 100644
index 0000000..4b28ab2
--- /dev/null
+++ b/docs/DesignDocs/AtomicDesign.rst
@@ -0,0 +1,797 @@
+
+====================
+``<atomic>`` Design
+====================
+
+There were originally 3 designs under consideration. They differ in where most
+of the implementation work is done. The functionality exposed to the customer
+should be identical (and conforming) for all three designs.
+
+
+Design A: Minimal work for the library
+======================================
+The compiler supplies all of the intrinsics as described below. This list of
+intrinsics roughly parallels the requirements of the C and C++ atomics proposals.
+The C and C++ library implementations simply drop through to these intrinsics.
+Anything the platform does not support in hardware, the compiler
+arranges for a (compiler-rt) library call to be made which will do the job with
+a mutex, and in this case ignoring the memory ordering parameter (effectively
+implementing ``memory_order_seq_cst``).
+
+Ultimate efficiency is preferred over run time error checking. Undefined
+behavior is acceptable when the inputs do not conform as defined below.
+
+.. code-block:: cpp
+
+    // In every intrinsic signature below, type* atomic_obj may be a pointer to a
+    // volatile-qualified type. Memory ordering values map to the following meanings:
+    //  memory_order_relaxed == 0
+    //  memory_order_consume == 1
+    //  memory_order_acquire == 2
+    //  memory_order_release == 3
+    //  memory_order_acq_rel == 4
+    //  memory_order_seq_cst == 5
+
+    // type must be trivially copyable
+    // type represents a "type argument"
+    bool __atomic_is_lock_free(type);
+
+    // type must be trivially copyable
+    // Behavior is defined for mem_ord = 0, 1, 2, 5
+    type __atomic_load(const type* atomic_obj, int mem_ord);
+
+    // type must be trivially copyable
+    // Behavior is defined for mem_ord = 0, 3, 5
+    void __atomic_store(type* atomic_obj, type desired, int mem_ord);
+
+    // type must be trivially copyable
+    // Behavior is defined for mem_ord = [0 ... 5]
+    type __atomic_exchange(type* atomic_obj, type desired, int mem_ord);
+
+    // type must be trivially copyable
+    // Behavior is defined for mem_success = [0 ... 5],
+    //   mem_failure <= mem_success
+    //   mem_failure != 3
+    //   mem_failure != 4
+    bool __atomic_compare_exchange_strong(type* atomic_obj,
+                                        type* expected, type desired,
+                                        int mem_success, int mem_failure);
+
+    // type must be trivially copyable
+    // Behavior is defined for mem_success = [0 ... 5],
+    //   mem_failure <= mem_success
+    //   mem_failure != 3
+    //   mem_failure != 4
+    bool __atomic_compare_exchange_weak(type* atomic_obj,
+                                        type* expected, type desired,
+                                        int mem_success, int mem_failure);
+
+    // type is one of: char, signed char, unsigned char, short, unsigned short, int,
+    //      unsigned int, long, unsigned long, long long, unsigned long long,
+    //      char16_t, char32_t, wchar_t
+    // Behavior is defined for mem_ord = [0 ... 5]
+    type __atomic_fetch_add(type* atomic_obj, type operand, int mem_ord);
+
+    // type is one of: char, signed char, unsigned char, short, unsigned short, int,
+    //      unsigned int, long, unsigned long, long long, unsigned long long,
+    //      char16_t, char32_t, wchar_t
+    // Behavior is defined for mem_ord = [0 ... 5]
+    type __atomic_fetch_sub(type* atomic_obj, type operand, int mem_ord);
+
+    // type is one of: char, signed char, unsigned char, short, unsigned short, int,
+    //      unsigned int, long, unsigned long, long long, unsigned long long,
+    //      char16_t, char32_t, wchar_t
+    // Behavior is defined for mem_ord = [0 ... 5]
+    type __atomic_fetch_and(type* atomic_obj, type operand, int mem_ord);
+
+    // type is one of: char, signed char, unsigned char, short, unsigned short, int,
+    //      unsigned int, long, unsigned long, long long, unsigned long long,
+    //      char16_t, char32_t, wchar_t
+    // Behavior is defined for mem_ord = [0 ... 5]
+    type __atomic_fetch_or(type* atomic_obj, type operand, int mem_ord);
+
+    // type is one of: char, signed char, unsigned char, short, unsigned short, int,
+    //      unsigned int, long, unsigned long, long long, unsigned long long,
+    //      char16_t, char32_t, wchar_t
+    // Behavior is defined for mem_ord = [0 ... 5]
+    type __atomic_fetch_xor(type* atomic_obj, type operand, int mem_ord);
+
+    // Behavior is defined for mem_ord = [0 ... 5]
+    void* __atomic_fetch_add(void** atomic_obj, ptrdiff_t operand, int mem_ord);
+    void* __atomic_fetch_sub(void** atomic_obj, ptrdiff_t operand, int mem_ord);
+
+    // Behavior is defined for mem_ord = [0 ... 5]
+    void __atomic_thread_fence(int mem_ord);
+    void __atomic_signal_fence(int mem_ord);
+
+If desired the intrinsics taking a single ``mem_ord`` parameter can default
+this argument to 5.
+
+If desired the intrinsics taking two ordering parameters can default ``mem_success``
+to 5, and ``mem_failure`` to ``translate_memory_order(mem_success)`` where
+``translate_memory_order(mem_success)`` is defined as:
+
+.. code-block:: cpp
+
+    int translate_memory_order(int o) {
+        switch (o) {
+        case 4:
+            return 2;
+        case 3:
+            return 0;
+        }
+        return o;
+    }
+
+Below are representative C++ implementations of all of the operations. Their
+purpose is to document the desired semantics of each operation, assuming
+``memory_order_seq_cst``. This is essentially the code that will be called
+if the front end calls out to compiler-rt.
+
+.. code-block:: cpp
+
+    template <class T>
+    T __atomic_load(T const volatile* obj) {
+        unique_lock<mutex> _(some_mutex);
+        return *obj;
+    }
+
+    template <class T>
+    void __atomic_store(T volatile* obj, T desr) {
+        unique_lock<mutex> _(some_mutex);
+        *obj = desr;
+    }
+
+    template <class T>
+    T __atomic_exchange(T volatile* obj, T desr) {
+        unique_lock<mutex> _(some_mutex);
+        T r = *obj;
+        *obj = desr;
+        return r;
+    }
+
+    template <class T>
+    bool __atomic_compare_exchange_strong(T volatile* obj, T* exp, T desr) {
+        unique_lock<mutex> _(some_mutex);
+        if (std::memcmp(const_cast<T*>(obj), exp, sizeof(T)) == 0) // if (*obj == *exp)
+        {
+            std::memcpy(const_cast<T*>(obj), &desr, sizeof(T)); // *obj = desr;
+            return true;
+        }
+        std::memcpy(exp, const_cast<T*>(obj), sizeof(T)); // *exp = *obj;
+        return false;
+    }
+
+    // May spuriously return false (even if *obj == *exp)
+    template <class T>
+    bool __atomic_compare_exchange_weak(T volatile* obj, T* exp, T desr) {
+        unique_lock<mutex> _(some_mutex);
+        if (std::memcmp(const_cast<T*>(obj), exp, sizeof(T)) == 0) // if (*obj == *exp)
+        {
+            std::memcpy(const_cast<T*>(obj), &desr, sizeof(T)); // *obj = desr;
+            return true;
+        }
+        std::memcpy(exp, const_cast<T*>(obj), sizeof(T)); // *exp = *obj;
+        return false;
+    }
+
+    template <class T>
+    T __atomic_fetch_add(T volatile* obj, T operand) {
+        unique_lock<mutex> _(some_mutex);
+        T r = *obj;
+        *obj += operand;
+        return r;
+    }
+
+    template <class T>
+    T __atomic_fetch_sub(T volatile* obj, T operand) {
+        unique_lock<mutex> _(some_mutex);
+        T r = *obj;
+        *obj -= operand;
+        return r;
+    }
+
+    template <class T>
+    T __atomic_fetch_and(T volatile* obj, T operand) {
+        unique_lock<mutex> _(some_mutex);
+        T r = *obj;
+        *obj &= operand;
+        return r;
+    }
+
+    template <class T>
+    T __atomic_fetch_or(T volatile* obj, T operand) {
+        unique_lock<mutex> _(some_mutex);
+        T r = *obj;
+        *obj |= operand;
+        return r;
+    }
+
+    template <class T>
+    T __atomic_fetch_xor(T volatile* obj, T operand) {
+        unique_lock<mutex> _(some_mutex);
+        T r = *obj;
+        *obj ^= operand;
+        return r;
+    }
+
+    void* __atomic_fetch_add(void* volatile* obj, ptrdiff_t operand) {
+        unique_lock<mutex> _(some_mutex);
+        void* r = *obj;
+        (char*&)(*obj) += operand;
+        return r;
+    }
+
+    void* __atomic_fetch_sub(void* volatile* obj, ptrdiff_t operand) {
+        unique_lock<mutex> _(some_mutex);
+        void* r = *obj;
+        (char*&)(*obj) -= operand;
+        return r;
+    }
+
+    void __atomic_thread_fence() {
+        unique_lock<mutex> _(some_mutex);
+    }
+
+    void __atomic_signal_fence() {
+        unique_lock<mutex> _(some_mutex);
+    }
+
+
+Design B: Something in between
+==============================
+This is a variation of design A which puts the burden on the library to arrange
+for the correct manipulation of the run time memory ordering arguments, and only
+calls the compiler for well-defined memory orderings. I think of this design as
+the worst of A and C, instead of the best of A and C. But I offer it as an
+option in the spirit of completeness.
+
+.. code-block:: cpp
+
+    // type must be trivially copyable
+    bool __atomic_is_lock_free(const type* atomic_obj);
+
+    // type must be trivially copyable
+    type __atomic_load_relaxed(const volatile type* atomic_obj);
+    type __atomic_load_consume(const volatile type* atomic_obj);
+    type __atomic_load_acquire(const volatile type* atomic_obj);
+    type __atomic_load_seq_cst(const volatile type* atomic_obj);
+
+    // type must be trivially copyable
+    type __atomic_store_relaxed(volatile type* atomic_obj, type desired);
+    type __atomic_store_release(volatile type* atomic_obj, type desired);
+    type __atomic_store_seq_cst(volatile type* atomic_obj, type desired);
+
+    // type must be trivially copyable
+    type __atomic_exchange_relaxed(volatile type* atomic_obj, type desired);
+    type __atomic_exchange_consume(volatile type* atomic_obj, type desired);
+    type __atomic_exchange_acquire(volatile type* atomic_obj, type desired);
+    type __atomic_exchange_release(volatile type* atomic_obj, type desired);
+    type __atomic_exchange_acq_rel(volatile type* atomic_obj, type desired);
+    type __atomic_exchange_seq_cst(volatile type* atomic_obj, type desired);
+
+    // type must be trivially copyable
+    bool __atomic_compare_exchange_strong_relaxed_relaxed(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_consume_relaxed(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_consume_consume(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_acquire_relaxed(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_acquire_consume(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_acquire_acquire(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_release_relaxed(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_release_consume(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_release_acquire(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_acq_rel_relaxed(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_acq_rel_consume(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_acq_rel_acquire(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_seq_cst_relaxed(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_seq_cst_consume(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_seq_cst_acquire(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_strong_seq_cst_seq_cst(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+
+    // type must be trivially copyable
+    bool __atomic_compare_exchange_weak_relaxed_relaxed(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_consume_relaxed(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_consume_consume(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_acquire_relaxed(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_acquire_consume(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_acquire_acquire(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_release_relaxed(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_release_consume(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_release_acquire(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_acq_rel_relaxed(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_acq_rel_consume(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_acq_rel_acquire(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_seq_cst_relaxed(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_seq_cst_consume(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_seq_cst_acquire(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+    bool __atomic_compare_exchange_weak_seq_cst_seq_cst(volatile type* atomic_obj,
+                                                        type* expected,
+                                                        type desired);
+
+    // type is one of: char, signed char, unsigned char, short, unsigned short, int,
+    //      unsigned int, long, unsigned long, long long, unsigned long long,
+    //      char16_t, char32_t, wchar_t
+    type __atomic_fetch_add_relaxed(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_add_consume(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_add_acquire(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_add_release(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_add_acq_rel(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_add_seq_cst(volatile type* atomic_obj, type operand);
+
+    // type is one of: char, signed char, unsigned char, short, unsigned short, int,
+    //      unsigned int, long, unsigned long, long long, unsigned long long,
+    //      char16_t, char32_t, wchar_t
+    type __atomic_fetch_sub_relaxed(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_sub_consume(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_sub_acquire(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_sub_release(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_sub_acq_rel(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_sub_seq_cst(volatile type* atomic_obj, type operand);
+
+    // type is one of: char, signed char, unsigned char, short, unsigned short, int,
+    //      unsigned int, long, unsigned long, long long, unsigned long long,
+    //      char16_t, char32_t, wchar_t
+    type __atomic_fetch_and_relaxed(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_and_consume(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_and_acquire(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_and_release(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_and_acq_rel(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_and_seq_cst(volatile type* atomic_obj, type operand);
+
+    // type is one of: char, signed char, unsigned char, short, unsigned short, int,
+    //      unsigned int, long, unsigned long, long long, unsigned long long,
+    //      char16_t, char32_t, wchar_t
+    type __atomic_fetch_or_relaxed(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_or_consume(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_or_acquire(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_or_release(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_or_acq_rel(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_or_seq_cst(volatile type* atomic_obj, type operand);
+
+    // type is one of: char, signed char, unsigned char, short, unsigned short, int,
+    //      unsigned int, long, unsigned long, long long, unsigned long long,
+    //      char16_t, char32_t, wchar_t
+    type __atomic_fetch_xor_relaxed(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_xor_consume(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_xor_acquire(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_xor_release(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_xor_acq_rel(volatile type* atomic_obj, type operand);
+    type __atomic_fetch_xor_seq_cst(volatile type* atomic_obj, type operand);
+
+    void* __atomic_fetch_add_relaxed(void* volatile* atomic_obj, ptrdiff_t operand);
+    void* __atomic_fetch_add_consume(void* volatile* atomic_obj, ptrdiff_t operand);
+    void* __atomic_fetch_add_acquire(void* volatile* atomic_obj, ptrdiff_t operand);
+    void* __atomic_fetch_add_release(void* volatile* atomic_obj, ptrdiff_t operand);
+    void* __atomic_fetch_add_acq_rel(void* volatile* atomic_obj, ptrdiff_t operand);
+    void* __atomic_fetch_add_seq_cst(void* volatile* atomic_obj, ptrdiff_t operand);
+
+    void* __atomic_fetch_sub_relaxed(void* volatile* atomic_obj, ptrdiff_t operand);
+    void* __atomic_fetch_sub_consume(void* volatile* atomic_obj, ptrdiff_t operand);
+    void* __atomic_fetch_sub_acquire(void* volatile* atomic_obj, ptrdiff_t operand);
+    void* __atomic_fetch_sub_release(void* volatile* atomic_obj, ptrdiff_t operand);
+    void* __atomic_fetch_sub_acq_rel(void* volatile* atomic_obj, ptrdiff_t operand);
+    void* __atomic_fetch_sub_seq_cst(void* volatile* atomic_obj, ptrdiff_t operand);
+
+    void __atomic_thread_fence_relaxed();
+    void __atomic_thread_fence_consume();
+    void __atomic_thread_fence_acquire();
+    void __atomic_thread_fence_release();
+    void __atomic_thread_fence_acq_rel();
+    void __atomic_thread_fence_seq_cst();
+
+    void __atomic_signal_fence_relaxed();
+    void __atomic_signal_fence_consume();
+    void __atomic_signal_fence_acquire();
+    void __atomic_signal_fence_release();
+    void __atomic_signal_fence_acq_rel();
+    void __atomic_signal_fence_seq_cst();
+
+Design C: Minimal work for the front end
+========================================
+The ``<atomic>`` header is one of the most closely coupled headers to the compiler.
+Ideally when you invoke any function from ``<atomic>``, it should result in highly
+optimized assembly being inserted directly into your application -- assembly that
+is not otherwise representable by higher level C or C++ expressions. The design of
+the libc++ ``<atomic>`` header started with this goal in mind. A secondary, but
+still very important goal is that the compiler should have to do minimal work to
+facilitate the implementation of ``<atomic>``.  Without this second goal, then
+practically speaking, the libc++ ``<atomic>`` header would be doomed to be a
+barely supported, second class citizen on almost every platform.
+
+Goals:
+
+- Optimal code generation for atomic operations
+- Minimal effort for the compiler to achieve goal 1 on any given platform
+- Conformance to the C++0X draft standard
+
+The purpose of this document is to inform compiler writers what they need to do
+to enable a high performance libc++ ``<atomic>`` with minimal effort.
+
+The minimal work that must be done for a conforming ``<atomic>``
+----------------------------------------------------------------
+The only "atomic" operations that must actually be lock free in
+``<atomic>`` are represented by the following compiler intrinsics:
+
+.. code-block:: cpp
+
+    __atomic_flag__ __atomic_exchange_seq_cst(__atomic_flag__ volatile* obj, __atomic_flag__ desr) {
+        unique_lock<mutex> _(some_mutex);
+        __atomic_flag__ result = *obj;
+        *obj = desr;
+        return result;
+    }
+
+    void __atomic_store_seq_cst(__atomic_flag__ volatile* obj, __atomic_flag__ desr) {
+        unique_lock<mutex> _(some_mutex);
+        *obj = desr;
+    }
+
+Where:
+
+- If ``__has_feature(__atomic_flag)`` evaluates to 1 in the preprocessor then
+  the compiler must define ``__atomic_flag__`` (e.g. as a typedef to ``int``).
+- If ``__has_feature(__atomic_flag)`` evaluates to 0 in the preprocessor then
+  the library defines ``__atomic_flag__`` as a typedef to ``bool``.
+- To communicate that the above intrinsics are available, the compiler must
+  arrange for ``__has_feature`` to return 1 when fed the intrinsic name
+  appended with an '_' and the mangled type name of ``__atomic_flag__``.
+
+For example if ``__atomic_flag__`` is ``unsigned int``:
+
+.. code-block:: cpp
+
+    // __has_feature(__atomic_flag) == 1
+    // __has_feature(__atomic_exchange_seq_cst_j) == 1
+    // __has_feature(__atomic_store_seq_cst_j) == 1
+
+    typedef unsigned int __atomic_flag__;
+
+    unsigned int __atomic_exchange_seq_cst(unsigned int volatile*, unsigned int) {
+        // ...
+    }
+
+    void __atomic_store_seq_cst(unsigned int volatile*, unsigned int) {
+        // ...
+    }
+
+That's it! Compiler writers do the above and you've got a fully conforming
+(though sub-par performance) ``<atomic>`` header!
+
+
+Recommended work for a higher performance ``<atomic>``
+------------------------------------------------------
+It would be good if the above intrinsics worked with all integral types plus
+``void*``. Because this may not be possible to do in a lock-free manner for
+all integral types on all platforms, a compiler must communicate each type that
+an intrinsic works with. For example, if ``__atomic_exchange_seq_cst`` works
+for all types except for ``long long`` and ``unsigned long long`` then:
+
+.. code-block:: cpp
+
+    __has_feature(__atomic_exchange_seq_cst_b) == 1  // bool
+    __has_feature(__atomic_exchange_seq_cst_c) == 1  // char
+    __has_feature(__atomic_exchange_seq_cst_a) == 1  // signed char
+    __has_feature(__atomic_exchange_seq_cst_h) == 1  // unsigned char
+    __has_feature(__atomic_exchange_seq_cst_Ds) == 1 // char16_t
+    __has_feature(__atomic_exchange_seq_cst_Di) == 1 // char32_t
+    __has_feature(__atomic_exchange_seq_cst_w) == 1  // wchar_t
+    __has_feature(__atomic_exchange_seq_cst_s) == 1  // short
+    __has_feature(__atomic_exchange_seq_cst_t) == 1  // unsigned short
+    __has_feature(__atomic_exchange_seq_cst_i) == 1  // int
+    __has_feature(__atomic_exchange_seq_cst_j) == 1  // unsigned int
+    __has_feature(__atomic_exchange_seq_cst_l) == 1  // long
+    __has_feature(__atomic_exchange_seq_cst_m) == 1  // unsigned long
+    __has_feature(__atomic_exchange_seq_cst_Pv) == 1 // void*
+
+Note that only the ``__has_feature`` flag is decorated with the argument
+type. The name of the compiler intrinsic is not decorated, but instead works
+like a C++ overloaded function.
+
+Additionally, there are other intrinsics besides ``__atomic_exchange_seq_cst``
+and ``__atomic_store_seq_cst``. They are optional. But if the compiler can
+generate faster code than provided by the library, then clients will benefit
+from the compiler writer's expertise and knowledge of the targeted platform.
+
+Below is the complete list of *sequentially consistent* intrinsics, and
+their library implementations. Template syntax is used to indicate the desired
+overloading for integral and ``void*`` types. The template does not represent a
+requirement that the intrinsic operate on **any** type!
+
+.. code-block:: cpp
+
+    // T is one of:
+    // bool, char, signed char, unsigned char, short, unsigned short,
+    // int, unsigned int, long, unsigned long,
+    // long long, unsigned long long, char16_t, char32_t, wchar_t, void*
+
+    template <class T>
+    T __atomic_load_seq_cst(T const volatile* obj) {
+        unique_lock<mutex> _(some_mutex);
+        return *obj;
+    }
+
+    template <class T>
+    void __atomic_store_seq_cst(T volatile* obj, T desr) {
+        unique_lock<mutex> _(some_mutex);
+        *obj = desr;
+    }
+
+    template <class T>
+    T __atomic_exchange_seq_cst(T volatile* obj, T desr) {
+        unique_lock<mutex> _(some_mutex);
+        T r = *obj;
+        *obj = desr;
+        return r;
+    }
+
+    template <class T>
+    bool __atomic_compare_exchange_strong_seq_cst_seq_cst(T volatile* obj, T* exp, T desr) {
+        unique_lock<mutex> _(some_mutex);
+        if (std::memcmp(const_cast<T*>(obj), exp, sizeof(T)) == 0) {
+            std::memcpy(const_cast<T*>(obj), &desr, sizeof(T));
+            return true;
+        }
+        std::memcpy(exp, const_cast<T*>(obj), sizeof(T));
+        return false;
+    }
+
+    template <class T>
+    bool __atomic_compare_exchange_weak_seq_cst_seq_cst(T volatile* obj, T* exp, T desr) {
+        unique_lock<mutex> _(some_mutex);
+        if (std::memcmp(const_cast<T*>(obj), exp, sizeof(T)) == 0)
+        {
+            std::memcpy(const_cast<T*>(obj), &desr, sizeof(T));
+            return true;
+        }
+        std::memcpy(exp, const_cast<T*>(obj), sizeof(T));
+        return false;
+    }
+
+    // T is one of:
+    // char, signed char, unsigned char, short, unsigned short,
+    // int, unsigned int, long, unsigned long,
+    // long long, unsigned long long, char16_t, char32_t, wchar_t
+
+    template <class T>
+    T __atomic_fetch_add_seq_cst(T volatile* obj, T operand) {
+        unique_lock<mutex> _(some_mutex);
+        T r = *obj;
+        *obj += operand;
+        return r;
+    }
+
+    template <class T>
+    T __atomic_fetch_sub_seq_cst(T volatile* obj, T operand) {
+        unique_lock<mutex> _(some_mutex);
+        T r = *obj;
+        *obj -= operand;
+        return r;
+    }
+
+    template <class T>
+    T __atomic_fetch_and_seq_cst(T volatile* obj, T operand) {
+        unique_lock<mutex> _(some_mutex);
+        T r = *obj;
+        *obj &= operand;
+        return r;
+    }
+
+    template <class T>
+    T __atomic_fetch_or_seq_cst(T volatile* obj, T operand) {
+        unique_lock<mutex> _(some_mutex);
+        T r = *obj;
+        *obj |= operand;
+        return r;
+    }
+
+    template <class T>
+    T __atomic_fetch_xor_seq_cst(T volatile* obj, T operand) {
+        unique_lock<mutex> _(some_mutex);
+        T r = *obj;
+        *obj ^= operand;
+        return r;
+    }
+
+    void* __atomic_fetch_add_seq_cst(void* volatile* obj, ptrdiff_t operand) {
+        unique_lock<mutex> _(some_mutex);
+        void* r = *obj;
+        (char*&)(*obj) += operand;
+        return r;
+    }
+
+    void* __atomic_fetch_sub_seq_cst(void* volatile* obj, ptrdiff_t operand) {
+        unique_lock<mutex> _(some_mutex);
+        void* r = *obj;
+        (char*&)(*obj) -= operand;
+        return r;
+    }
+
+    void __atomic_thread_fence_seq_cst() {
+        unique_lock<mutex> _(some_mutex);
+    }
+
+    void __atomic_signal_fence_seq_cst() {
+        unique_lock<mutex> _(some_mutex);
+    }
+
+One should consult the (currently draft) `C++ Standard <https://wg21.link/n3126>`_
+for the details of the definitions for these operations. For example,
+``__atomic_compare_exchange_weak_seq_cst_seq_cst`` is allowed to fail
+spuriously while ``__atomic_compare_exchange_strong_seq_cst_seq_cst`` is not.
+
+If on your platform the lock-free definition of ``__atomic_compare_exchange_weak_seq_cst_seq_cst``
+would be the same as ``__atomic_compare_exchange_strong_seq_cst_seq_cst``, you may omit the
+``__atomic_compare_exchange_weak_seq_cst_seq_cst`` intrinsic without a performance cost. The
+library will prefer your implementation of ``__atomic_compare_exchange_strong_seq_cst_seq_cst``
+over its own definition for implementing ``__atomic_compare_exchange_weak_seq_cst_seq_cst``.
+That is, the library will arrange for ``__atomic_compare_exchange_weak_seq_cst_seq_cst`` to call
+``__atomic_compare_exchange_strong_seq_cst_seq_cst`` if you supply an intrinsic for the strong
+version but not the weak.
+
+Taking advantage of weaker memory synchronization
+-------------------------------------------------
+So far, all of the intrinsics presented require a **sequentially consistent** memory ordering.
+That is, no loads or stores can move across the operation (just as if the library had locked
+that internal mutex). But ``<atomic>`` supports weaker memory ordering operations. In all,
+there are six memory orderings (listed here from strongest to weakest):
+
+.. code-block:: cpp
+
+    memory_order_seq_cst
+    memory_order_acq_rel
+    memory_order_release
+    memory_order_acquire
+    memory_order_consume
+    memory_order_relaxed
+
+(See the `C++ Standard <https://wg21.link/n3126>`_ for the detailed definitions of each of these orderings).
+
+On some platforms, the compiler vendor can offer some or even all of the above
+intrinsics at one or more weaker levels of memory synchronization. This might
+lead for example to not issuing an ``mfence`` instruction on the x86.
+
+If the compiler does not offer any given operation, at any given memory ordering
+level, the library will automatically attempt to call the next highest memory
+ordering operation. This continues up to ``seq_cst``, and if that doesn't
+exist, then the library takes over and does the job with a ``mutex``. This
+is a compile-time search and selection operation. At run time, the application
+will only see the few inlined assembly instructions for the selected intrinsic.
+
+Each intrinsic is appended with the 7-letter name of the memory ordering it
+addresses. For example a ``load`` with ``relaxed`` ordering is defined by:
+
+.. code-block:: cpp
+
+    T __atomic_load_relaxed(const volatile T* obj);
+
+And announced with:
+
+.. code-block:: cpp
+
+    __has_feature(__atomic_load_relaxed_b) == 1  // bool
+    __has_feature(__atomic_load_relaxed_c) == 1  // char
+    __has_feature(__atomic_load_relaxed_a) == 1  // signed char
+    ...
+
+The ``__atomic_compare_exchange_strong(weak)`` intrinsics are parameterized
+on two memory orderings. The first ordering applies when the operation returns
+``true`` and the second ordering applies when the operation returns ``false``.
+
+Not every memory ordering is appropriate for every operation. ``exchange``
+and the ``fetch_XXX`` operations support all 6. But ``load`` only supports
+``relaxed``, ``consume``, ``acquire`` and ``seq_cst``. ``store`` only supports
+``relaxed``, ``release``, and ``seq_cst``. The ``compare_exchange`` operations
+support the following 16 combinations out of the possible 36:
+
+.. code-block:: cpp
+
+    relaxed_relaxed
+    consume_relaxed
+    consume_consume
+    acquire_relaxed
+    acquire_consume
+    acquire_acquire
+    release_relaxed
+    release_consume
+    release_acquire
+    acq_rel_relaxed
+    acq_rel_consume
+    acq_rel_acquire
+    seq_cst_relaxed
+    seq_cst_consume
+    seq_cst_acquire
+    seq_cst_seq_cst
+
+Again, the compiler supplies intrinsics only for the strongest orderings where
+it can make a difference. The library takes care of calling the weakest
+supplied intrinsic that is as strong or stronger than the customer asked for.
+
+Note about ABI
+==============
+With any design, the (back end) compiler writer should note that the decision to
+implement lock-free operations on any given type (or not) is an ABI-binding decision.
+One can not change from treating a type as not lock free, to lock free (or vice-versa)
+without breaking your ABI.
+
+For example:
+
+**TU1.cpp**:
+
+.. code-block:: cpp
+
+    extern atomic<long long> A;
+    int foo() { return A.compare_exchange_strong(w, x); }
+
+
+**TU2.cpp**:
+
+.. code-block:: cpp
+
+    extern atomic<long long> A;
+    void bar() { return A.compare_exchange_strong(y, z); }
+
+If only **one** of these calls to ``compare_exchange_strong`` is implemented with
+mutex-locked code, then that mutex-locked code will not be executed mutually
+exclusively of the one implemented in a lock-free manner.
diff --git a/docs/DesignDocs/CapturingConfigInfo.rst b/docs/DesignDocs/CapturingConfigInfo.rst
new file mode 100644
index 0000000..8f2d0cd
--- /dev/null
+++ b/docs/DesignDocs/CapturingConfigInfo.rst
@@ -0,0 +1,86 @@
+=======================================================
+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 dependent 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 prepended 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
+
+  //===----------------------------------------------------------------------===//
+  //
+  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+  // See https://llvm.org/LICENSE.txt for license information.
+  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+  //
+  //===----------------------------------------------------------------------===//
+
+  #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 ---------------------------------===//
+  //
+  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+  // See https://llvm.org/LICENSE.txt for license information.
+  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+  //
+  //===----------------------------------------------------------------------===//
+
+  #ifndef _LIBCPP_CONFIG
+  #define _LIBCPP_CONFIG
diff --git a/docs/DesignDocs/DebugMode.rst b/docs/DesignDocs/DebugMode.rst
new file mode 100644
index 0000000..abcd5e5
--- /dev/null
+++ b/docs/DesignDocs/DebugMode.rst
@@ -0,0 +1,82 @@
+==========
+Debug Mode
+==========
+
+.. contents::
+   :local:
+
+.. _using-debug-mode:
+
+Using the debug mode
+====================
+
+Libc++ provides a debug mode that enables special debugging checks meant to detect
+incorrect usage of the standard library. These checks are disabled by default, but
+they can be enabled using the ``_LIBCPP_DEBUG`` macro.
+
+Note that using the debug mode discussed in this document requires that the library
+has been compiled with support for the debug mode (see ``LIBCXX_ENABLE_DEBUG_MODE_SUPPORT``).
+
+Also note that while the debug mode has no effect on libc++'s ABI, it does have broad ODR
+implications. Users should compile their whole program at the same debugging level.
+
+The various levels of checking provided by the debug mode follow.
+
+No debugging checks (``_LIBCPP_DEBUG`` not defined)
+---------------------------------------------------
+When ``_LIBCPP_DEBUG`` is not defined, there are no debugging checks performed by
+the library. This is the default.
+
+Basic checks (``_LIBCPP_DEBUG == 0``)
+-------------------------------------
+When ``_LIBCPP_DEBUG`` is defined to ``0`` (to be understood as level ``0``), some
+debugging checks are enabled. The non-exhaustive list of things is:
+
+- Many algorithms, such as ``binary_search``, ``merge``, ``next_permutation``, and ``sort``,
+  wrap the user-provided comparator to assert that `!comp(y, x)` whenever
+  `comp(x, y)`. This can cause the user-provided comparator to be evaluated
+  up to twice as many times as it would be without ``_LIBCPP_DEBUG``, and
+  causes the library to violate some of the Standard's complexity clauses.
+
+- FIXME: Update this list
+
+Iterator debugging checks (``_LIBCPP_DEBUG == 1``)
+--------------------------------------------------
+Defining ``_LIBCPP_DEBUG`` to ``1`` enables "iterator debugging", which provides
+additional assertions about the validity of iterators used by the program.
+
+The following containers and classes support iterator debugging:
+
+- ``std::string``
+- ``std::vector<T>`` (``T != bool``)
+- ``std::list``
+- ``std::unordered_map``
+- ``std::unordered_multimap``
+- ``std::unordered_set``
+- ``std::unordered_multiset``
+
+The remaining containers do not currently support iterator debugging.
+Patches welcome.
+
+Handling Assertion Failures
+===========================
+When a debug assertion fails the assertion handler is called via the
+``std::__libcpp_debug_function`` function pointer. It is possible to override
+this function pointer using a different handler function. Libc++ provides a
+the default handler, ``std::__libcpp_abort_debug_handler``, which aborts the
+program. The handler may not return. Libc++ can be changed to use a custom
+assertion handler as follows.
+
+.. code-block:: cpp
+
+  #define _LIBCPP_DEBUG 1
+  #include <string>
+  void my_handler(std::__libcpp_debug_info const&);
+  int main(int, char**) {
+    std::__libcpp_debug_function = &my_handler;
+
+    std::string::iterator bad_it;
+    std::string str("hello world");
+    str.insert(bad_it, '!'); // causes debug assertion
+    // control flow doesn't return
+  }
diff --git a/docs/DesignDocs/ExperimentalFeatures.rst b/docs/DesignDocs/ExperimentalFeatures.rst
new file mode 100644
index 0000000..2241496
--- /dev/null
+++ b/docs/DesignDocs/ExperimentalFeatures.rst
@@ -0,0 +1,203 @@
+=====================
+Experimental Features
+=====================
+
+.. contents::
+   :local:
+
+.. _experimental features:
+
+Overview
+========
+
+Libc++ implements technical specifications (TSes) and ships them as experimental
+features that users are free to try out. The goal is to allow getting feedback
+on those experimental features.
+
+However, libc++ does not provide the same guarantees about those features as
+it does for the rest of the library. In particular, no ABI or API stability
+is guaranteed, and experimental features are deprecated once the non-experimental
+equivalent has shipped in the library. This document outlines the details of
+that process.
+
+Background
+==========
+
+The "end game" of a Technical Specification (TS) is to have the features in
+there added to a future version of the C++ Standard. When this happens, the TS
+can be retired. Sometimes, only part of at TS is added to the standard, and
+the rest of the features may be incorporated into the next version of the TS.
+
+Adoption leaves library implementors with two implementations of a feature,
+one in namespace ``std``, and the other in namespace ``std::experimental``.
+The first one will continue to evolve (via issues and papers), while the other
+will not. Gradually they will diverge. It's not good for users to have two
+(subtly) different implementations of the same functionality in the same library.
+
+Design
+======
+
+When a feature is adopted into the main standard, we implement it in namespace
+``std``. Once that implementation is complete, we then create a deprecation
+warning for the corresponding experimental feature warning users to move off
+of it and to the now-standardized feature.
+
+These deprecation warnings are guarded by a macro of the form
+``_LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_<FEATURE>``, which
+can be defined by users to disable the deprecation warning. Whenever
+possible, deprecation warnings are put on a per-declaration basis
+using the ``[[deprecated]]`` attribute, which also allows disabling
+the warnings using ``-Wno-deprecated-declarations``.
+
+After **2 releases** of LLVM, the experimental feature is removed completely
+(and the deprecation notice too). Using the experimental feature simply becomes
+an error. Furthermore, when an experimental header becomes empty due to the
+removal of the corresponding experimental feature, the header is removed.
+Keeping the header around creates incorrect assumptions from users and breaks
+``__has_include``.
+
+
+Status of TSes
+==============
+
+Library Fundamentals TS `V1 <https://wg21.link/N4480>`__ and `V2 <https://wg21.link/N4617>`__
+---------------------------------------------------------------------------------------------
+
+Most (but not all) of the features of the LFTS were accepted into C++17.
+
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| Section | Feature                                               | Shipped in ``std`` | To be removed from ``std::experimental`` | Notes                   |
++=========+=======================================================+====================+==========================================+=========================+
+| 2.1     | ``uses_allocator construction``                       | 5.0                | 7.0                                      |                         |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 3.1.2   | ``erased_type``                                       |                    | n/a                                      | Not part of C++17       |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 3.2.1   | ``tuple_size_v``                                      | 5.0                | 7.0                                      | Removed                 |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 3.2.2   | ``apply``                                             | 5.0                | 7.0                                      | Removed                 |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 3.3.1   | All of the ``_v`` traits in ``<type_traits>``         | 5.0                | 7.0                                      | Removed                 |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 3.3.2   | ``invocation_type`` and ``raw_invocation_type``       |                    | n/a                                      | Not part of C++17       |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 3.3.3   | Logical operator traits                               | 5.0                | 7.0                                      | Removed                 |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 3.3.3   | Detection Idiom                                       | 5.0                |                                          | Only partially in C++17 |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 3.4.1   | All of the ``_v`` traits in ``<ratio>``               | 5.0                | 7.0                                      | Removed                 |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 3.5.1   | All of the ``_v`` traits in ``<chrono>``              | 5.0                | 7.0                                      | Removed                 |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 3.6.1   | All of the ``_v`` traits in ``<system_error>``        | 5.0                | 7.0                                      | Removed                 |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 3.7     | ``propagate_const``                                   |                    | n/a                                      | Not part of C++17       |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 4.2     | Enhancements to ``function``                          | Not yet            |                                          |                         |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 4.3     | searchers                                             | 7.0                | 9.0                                      |                         |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 5       | optional                                              | 5.0                | 7.0                                      | Removed                 |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 6       | ``any``                                               | 5.0                | 7.0                                      | Removed                 |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 7       | ``string_view``                                       | 5.0                | 7.0                                      | Removed                 |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 8.2.1   | ``shared_ptr`` enhancements                           | Not yet            | Never added                              |                         |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 8.2.2   | ``weak_ptr`` enhancements                             | Not yet            | Never added                              |                         |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 8.5     | ``memory_resource``                                   | Not yet            |                                          |                         |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 8.6     | ``polymorphic_allocator``                             | Not yet            |                                          |                         |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 8.7     | ``resource_adaptor``                                  |                    | n/a                                      | Not part of C++17       |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 8.8     | Access to program-wide ``memory_resource`` objects    | Not yet            |                                          |                         |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 8.9     | Pool resource classes                                 | Not yet            |                                          |                         |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 8.10    | ``monotonic_buffer_resource``                         | Not yet            |                                          |                         |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 8.11    | Alias templates using polymorphic memory resources    | Not yet            |                                          |                         |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 8.12    | Non-owning pointers                                   |                    | n/a                                      | Not part of C++17       |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 11.2    | ``promise``                                           |                    | n/a                                      | Not part of C++17       |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 11.3    | ``packaged_task``                                     |                    | n/a                                      | Not part of C++17       |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 12.2    | ``search``                                            | 7.0                | 9.0                                      |                         |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 12.3    | ``sample``                                            | 5.0                | 7.0                                      | Removed                 |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 12.4    | ``shuffle``                                           |                    |                                          | Not part of C++17       |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 13.1    | ``gcd`` and ``lcm``                                   | 5.0                | 7.0                                      | Removed                 |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 13.2    | Random number generation                              |                    |                                          | Not part of C++17       |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+| 14      | Reflection Library                                    |                    |                                          | Not part of C++17       |
++---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+
+
+`FileSystem TS <https://wg21.link/N4100>`__
+-------------------------------------------
+The FileSystem TS was accepted (in totality) for C++17.
+The FileSystem TS implementation was shipped in namespace ``std`` in LLVM 7.0, and will be removed in LLVM 11.0 (due to the lack of deprecation warnings before LLVM 9.0).
+
+Parallelism TS `V1 <https://wg21.link/N4507>`__ and `V2 <https://wg21.link/N4706>`__
+------------------------------------------------------------------------------------
+Some (most) of the Parallelism TS was accepted for C++17.
+We have not yet shipped an implementation of the Parallelism TS.
+
+`Coroutines TS <https://wg21.link/N4680>`__
+-------------------------------------------
+The Coroutines TS is not yet part of a shipping standard.
+We are shipping (as of v5.0) an implementation of the Coroutines TS in namespace ``std::experimental``.
+
+`Networking TS <https://wg21.link/N4656>`__
+-------------------------------------------
+The Networking TS is not yet part of a shipping standard.
+We have not yet shipped an implementation of the Networking TS.
+
+`Ranges TS <https://wg21.link/N4685>`__
+---------------------------------------
+The Ranges TS is not yet part of a shipping standard.
+We have not yet shipped an implementation of the Ranges TS.
+
+`Concepts TS <https://wg21.link/N4641>`__
+-----------------------------------------
+The Concepts TS is not yet part of a shipping standard, but it has been adopted into the C++20 working draft.
+We have not yet shipped an implementation of the Concepts TS.
+
+`Concurrency TS <https://wg21.link/P0159>`__
+--------------------------------------------
+The Concurrency TS was adopted in Kona (2015).
+None of the Concurrency TS was accepted for C++17.
+We have not yet shipped an implementation of the Concurrency TS.
+
+.. +---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+.. | Section | Feature                                               | Shipped in ``std`` | To be removed from ``std::experimental`` | Notes                   |
+.. +=========+=======================================================+====================+==========================================+=========================+
+.. | 2.3     | class template ``future``                             |                    |                                          |                         |
+.. +---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+.. | 2.4     | class template ``shared_future``                      |                    |                                          |                         |
+.. +---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+.. | 2.5     | class template ``promise``                            |                    |                                          | Only using ``future``   |
+.. +---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+.. | 2.6     | class template ``packaged_task``                      |                    |                                          | Only using ``future``   |
+.. +---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+.. | 2.7     | function template ``when_all``                        |                    |                                          | Not part of C++17       |
+.. +---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+.. | 2.8     | class template ``when_any_result``                    |                    |                                          | Not part of C++17       |
+.. +---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+.. | 2.9     | function template ``when_any``                        |                    |                                          | Not part of C++17       |
+.. +---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+.. | 2.10    | function template ``make_ready_future``               |                    |                                          | Not part of C++17       |
+.. +---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+.. | 2.11    | function template ``make_exeptional_future``          |                    |                                          | Not part of C++17       |
+.. +---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+.. | 3       | ``latches`` and ``barriers``                          |                    |                                          | Not part of C++17       |
+.. +---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
+.. | 4       | Atomic Smart Pointers                                 |                    |                                          | Adopted for C++20       |
+.. +---------+-------------------------------------------------------+--------------------+------------------------------------------+-------------------------+
diff --git a/docs/DesignDocs/ExtendedCXX03Support.rst b/docs/DesignDocs/ExtendedCXX03Support.rst
new file mode 100644
index 0000000..e9e3fc4
--- /dev/null
+++ b/docs/DesignDocs/ExtendedCXX03Support.rst
@@ -0,0 +1,118 @@
+=======================
+Extended C++03 Support
+=======================
+
+.. contents::
+   :local:
+
+Overview
+========
+
+libc++ is an implementation of the C++ standard library targeting C++11 or later.
+
+In C++03, the library implements the C++11 standard using C++11 language extensions provided
+by Clang.
+
+This document tracks the C++11 extensions libc++ requires, the C++11 extensions it provides,
+and how to write minimal C++11 inside libc++.
+
+Required C++11 Compiler Extensions
+==================================
+
+Clang provides a large subset of C++11 in C++03 as an extension. The features
+libc++ expects Clang  to provide are:
+
+* Variadic templates.
+* RValue references and perfect forwarding.
+* Alias templates
+* defaulted and deleted Functions.
+* reference qualified Functions
+
+There are also features that Clang *does not* provide as an extension in C++03
+mode. These include:
+
+* ``constexpr`` and ``noexcept``
+* ``auto``
+*  Trailing return types.
+* ``>>`` without a space.
+
+
+Provided C++11 Library Extensions
+=================================
+
+.. warning::
+  The C++11 extensions libc++ provides in C++03 are currently undergoing change. Existing extensions
+  may be removed in the future. New users are strongly discouraged depending on these extension
+  in new code.
+
+  This section will be updated once the libc++ developer community has further discussed the
+  future of C++03 with libc++.
+
+
+Using Minimal C++11 in libc++
+=============================
+
+This section is for developers submitting patches to libc++. It describes idioms that should be
+used in libc++ code, even in C++03, and the reasons behind them.
+
+
+Use Alias Templates over Class Templates
+----------------------------------------
+
+Alias templates should be used instead of class templates in metaprogramming. Unlike class templates,
+Alias templates do not produce a new instantiation every time they are used. This significantly
+decreases the amount of memory used by the compiler.
+
+For example, libc++ should not use ``add_const`` internally. Instead it should use an alias template
+like
+
+.. code-block:: cpp
+
+  template <class _Tp>
+  using _AddConst = const _Tp;
+
+Use Default Template Parameters for SFINAE
+------------------------------------------
+
+There are three places in a function declaration that SFINAE may occur: In the template parameter list,
+in the function parameter list, and in the return type. For example:
+
+.. code-block:: cpp
+
+  template <class _Tp, class _ = enable_if_t</*...*/ >
+  void foo(_Tp); // #1
+
+  template <class _Tp>
+  void bar(_Tp, enable_if_t</*...*/>* = nullptr); // # 2
+
+  template <class _Tp>
+  enable_if_t</*...*/> baz(_Tp); // # 3
+
+Using default template parameters for SFINAE (#1) should always be prefered.
+
+Option #2 has two problems. First, users can observe and accidentally pass values to the SFINAE
+function argument. Second, the default arguement creates a live variable, which causes debug
+information to be emitted containing the text of the SFINAE.
+
+Option #3 can also cause more debug information to be emitted than is needed, because the function
+return type will appear in the debug information.
+
+Use ``unique_ptr`` when allocating memory
+------------------------------------------
+
+The standard library often needs to allocate memory and then construct a user type in it.
+If the users constructor throws, the library needs to deallocate that memory. The idiomatic way to
+achieve this is with ``unique_ptr``.
+
+``__builtin_new_allocator`` is an example of this idiom. Example usage would look like:
+
+.. code-block:: cpp
+
+  template <class T>
+  T* __create() {
+    using _UniquePtr = unique_ptr<void*, __default_new_allocator::__default_new_deleter>;
+    _UniquePtr __p = __default_new_allocator::__allocate_bytes(sizeof(T), alignof(T));
+    T* __res = ::new(__p.get()) T();
+    (void)__p.release();
+    return __res;
+  }
diff --git a/docs/DesignDocs/FeatureTestMacros.rst b/docs/DesignDocs/FeatureTestMacros.rst
new file mode 100644
index 0000000..2c6f983
--- /dev/null
+++ b/docs/DesignDocs/FeatureTestMacros.rst
@@ -0,0 +1,43 @@
+===================
+Feature Test Macros
+===================
+
+.. contents::
+   :local:
+
+Overview
+========
+
+Libc++ implements the C++ feature test macros as specified in the C++20 standard,
+and before that in non-normative guiding documents
+(`See cppreference <https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros>`_)
+
+
+Design
+======
+
+Feature test macros are tricky to track, implement, test, and document correctly.
+They must be available from a list of headers, they may have different values in
+different dialects, and they may or may not be implemented by libc++. In order to
+track all of these conditions correctly and easily, we want a Single Source of
+Truth (SSoT) that defines each feature test macro, its values, the headers it
+lives in, and whether or not is is implemented by libc++. From this SSoA we
+have enough information to automatically generate the `<version>` header,
+the tests, and the documentation.
+
+Therefore we maintain a SSoA in `libcxx/utils/generate_feature_test_macro_components.py`
+which doubles as a script to generate the following components:
+
+* The `<version>` header.
+* The version tests under `support.limits.general`.
+* Documentation of libc++'s implementation of each macro.
+
+Usage
+=====
+
+The `generate_feature_test_macro_components.py` script is used to track and
+update feature test macros in libc++.
+
+Whenever a feature test macro is added or changed, the table should be updated
+and the script should be re-ran. The script will clobber the existing test files,
+the documentation and the `<version>` header.
diff --git a/docs/DesignDocs/FileTimeType.rst b/docs/DesignDocs/FileTimeType.rst
new file mode 100644
index 0000000..a54d2bf
--- /dev/null
+++ b/docs/DesignDocs/FileTimeType.rst
@@ -0,0 +1,495 @@
+==============
+File Time Type
+==============
+
+.. contents::
+   :local:
+
+.. _file-time-type-motivation:
+
+Motivation
+==========
+
+The filesystem library provides interfaces for getting and setting the last
+write time of a file or directory. The interfaces use the ``file_time_type``
+type, which is a specialization of ``chrono::time_point`` for the
+"filesystem clock". According to [fs.filesystem.syn]
+
+  trivial-clock is an implementation-defined type that satisfies the
+  Cpp17TrivialClock requirements ([time.clock.req]) and that is capable of
+  representing and measuring file time values. Implementations should ensure
+  that the resolution and range of file_time_type reflect the operating
+  system dependent resolution and range of file time values.
+
+
+On POSIX systems, file times are represented using the ``timespec`` struct,
+which is defined as follows:
+
+.. code-block:: cpp
+
+  struct timespec {
+    time_t tv_sec;
+    long   tv_nsec;
+  };
+
+To represent the range and resolution of ``timespec``, we need to (A) have
+nanosecond resolution, and (B) use more than 64 bits (assuming a 64 bit ``time_t``).
+
+As the standard requires us to use the ``chrono`` interface, we have to define
+our own filesystem clock which specifies the period and representation of
+the time points and duration it provides. It will look like this:
+
+.. code-block:: cpp
+
+  struct _FilesystemClock {
+    using period = nano;
+    using rep = TBD; // What is this?
+
+    using duration = chrono::duration<rep, period>;
+    using time_point = chrono::time_point<_FilesystemClock>;
+
+    // ... //
+  };
+
+  using file_time_type = _FilesystemClock::time_point;
+
+
+To get nanosecond resolution, we simply define ``period`` to be ``std::nano``.
+But what type can we use as the arithmetic representation that is capable
+of representing the range of the ``timespec`` struct?
+
+Problems To Consider
+====================
+
+Before considering solutions, let's consider the problems they should solve,
+and how important solving those problems are:
+
+
+Having a Smaller Range than ``timespec``
+----------------------------------------
+
+One solution to the range problem is to simply reduce the resolution of
+``file_time_type`` to be less than that of nanoseconds. This is what libc++'s
+initial implementation of ``file_time_type`` did; it's also what
+``std::system_clock`` does. As a result, it can represent time points about
+292 thousand years on either side of the epoch, as opposed to only 292 years
+at nanosecond resolution.
+
+``timespec`` can represent time points +/- 292 billion years from the epoch
+(just in case you needed a time point 200 billion years before the big bang,
+and with nanosecond resolution).
+
+To get the same range, we would need to drop our resolution to that of seconds
+to come close to having the same range.
+
+This begs the question, is the range problem "really a problem"? Sane usages
+of file time stamps shouldn't exceed +/- 300 years, so should we care to support it?
+
+I believe the answer is yes. We're not designing the filesystem time API, we're
+providing glorified C++ wrappers for it. If the underlying API supports
+a value, then we should too. Our wrappers should not place artificial restrictions
+on users that are not present in the underlying filesystem.
+
+Having a smaller range that the underlying filesystem forces the
+implementation to report ``value_too_large`` errors when it encounters a time
+point that it can't represent. This can cause the call to ``last_write_time``
+to throw in cases where the user was confident the call should succeed. (See below)
+
+
+.. code-block:: cpp
+
+  #include <filesystem>
+  using namespace std::filesystem;
+
+  // Set the times using the system interface.
+  void set_file_times(const char* path, struct timespec ts) {
+    timespec both_times[2];
+    both_times[0] = ts;
+    both_times[1] = ts;
+    int result = ::utimensat(AT_FDCWD, path, both_times, 0);
+    assert(result != -1);
+  }
+
+  // Called elsewhere to set the file time to something insane, and way
+  // out of the 300 year range we might expect.
+  void some_bad_persons_code() {
+    struct timespec new_times;
+    new_times.tv_sec = numeric_limits<time_t>::max();
+    new_times.tv_nsec = 0;
+    set_file_times("/tmp/foo", new_times); // OK, supported by most FSes
+  }
+
+  int main(int, char**) {
+    path p = "/tmp/foo";
+    file_status st = status(p);
+    if (!exists(st) || !is_regular_file(st))
+      return 1;
+    if ((st.permissions() & perms::others_read) == perms::none)
+      return 1;
+    // It seems reasonable to assume this call should succeed.
+    file_time_type tp = last_write_time(p); // BAD! Throws value_too_large.
+    return 0;
+  }
+
+
+Having a Smaller Resolution than ``timespec``
+---------------------------------------------
+
+As mentioned in the previous section, one way to solve the range problem
+is by reducing the resolution. But matching the range of ``timespec`` using a
+64 bit representation requires limiting the resolution to seconds.
+
+So we might ask: Do users "need" nanosecond precision? Is seconds not good enough?
+I limit my consideration of the point to this: Why was it not good enough for
+the underlying system interfaces? If it wasn't good enough for them, then it
+isn't good enough for us. Our job is to match the filesystems range and
+representation, not design it.
+
+
+Having a Larger Range than ``timespec``
+----------------------------------------
+
+We should also consider the opposite problem of having a ``file_time_type``
+that is able to represent a larger range than ``timespec``. At least in
+this case ``last_write_time`` can be used to get and set all possible values
+supported by the underlying filesystem; meaning ``last_write_time(p)`` will
+never throw a overflow error when retrieving a value.
+
+However, this introduces a new problem, where users are allowed to attempt to
+create a time point beyond what the filesystem can represent. Two particular
+values which cause this are ``file_time_type::min()`` and
+``file_time_type::max()``. As a result, the following code would throw:
+
+.. code-block:: cpp
+
+  void test() {
+    last_write_time("/tmp/foo", file_time_type::max()); // Throws
+    last_write_time("/tmp/foo", file_time_type::min()); // Throws.
+  }
+
+Apart from cases explicitly using ``min`` and ``max``, I don't see users taking
+a valid time point, adding a couple hundred billions of years in error,
+and then trying to update a file's write time to that value very often.
+
+Compared to having a smaller range, this problem seems preferable. At least
+now we can represent any time point the filesystem can, so users won't be forced
+to revert back to system interfaces to avoid limitations in the C++ STL.
+
+I posit that we should only consider this concern *after* we have something
+with at least the same range and resolution of the underlying filesystem. The
+latter two problems are much more important to solve.
+
+Potential Solutions And Their Complications
+===========================================
+
+Source Code Portability Across Implementations
+-----------------------------------------------
+
+As we've discussed, ``file_time_type`` needs a representation that uses more
+than 64 bits. The possible solutions include using ``__int128_t``, emulating a
+128 bit integer using a class, or potentially defining a ``timespec`` like
+arithmetic type. All three will allow us to, at minimum, match the range
+and resolution, and the last one might even allow us to match them exactly.
+
+But when considering these potential solutions we need to consider more than
+just the values they can represent. We need to consider the effects they will
+have on users and their code. For example, each of them breaks the following
+code in some way:
+
+.. code-block:: cpp
+
+  // Bug caused by an unexpected 'rep' type returned by count.
+  void print_time(path p) {
+    // __int128_t doesn't have streaming operators, and neither would our
+    // custom arithmetic types.
+    cout << last_write_time(p).time_since_epoch().count() << endl;
+  }
+
+  // Overflow during creation bug.
+  file_time_type timespec_to_file_time_type(struct timespec ts) {
+    // woops! chrono::seconds and chrono::nanoseconds use a 64 bit representation
+    // this may overflow before it's converted to a file_time_type.
+    auto dur = seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec);
+    return file_time_type(dur);
+  }
+
+  file_time_type correct_timespec_to_file_time_type(struct timespec ts) {
+    // This is the correct version of the above example, where we
+    // avoid using the chrono typedefs as they're not sufficient.
+    // Can we expect users to avoid this bug?
+    using fs_seconds = chrono::duration<file_time_type::rep>;
+    using fs_nanoseconds = chrono::duration<file_time_type::rep, nano>;
+    auto dur = fs_seconds(ts.tv_sec) + fs_nanoseconds(tv.tv_nsec);
+    return file_time_type(dur);
+  }
+
+  // Implicit truncation during conversion bug.
+  intmax_t get_time_in_seconds(path p) {
+    using fs_seconds = duration<file_time_type::rep, ratio<1, 1> >;
+    auto tp = last_write_time(p);
+
+    // This works with truncation for __int128_t, but what does it do for
+    // our custom arithmetic types.
+    return duration_cast<fs_seconds>().count();
+  }
+
+
+Each of the above examples would require a user to adjust their filesystem code
+to the particular eccentricities of the representation, hopefully only in such
+a way that the code is still portable across implementations.
+
+At least some of the above issues are unavoidable, no matter what
+representation we choose. But some representations may be quirkier than others,
+and, as I'll argue later, using an actual arithmetic type (``__int128_t``)
+provides the least aberrant behavior.
+
+
+Chrono and ``timespec`` Emulation.
+----------------------------------
+
+One of the options we've considered is using something akin to ``timespec``
+to represent the ``file_time_type``. It only seems natural seeing as that's
+what the underlying system uses, and because it might allow us to match
+the range and resolution exactly. But would it work with chrono? And could
+it still act at all like a ``timespec`` struct?
+
+For ease of consideration, let's consider what the implementation might
+look like.
+
+.. code-block:: cpp
+
+  struct fs_timespec_rep {
+    fs_timespec_rep(long long v)
+      : tv_sec(v / nano::den), tv_nsec(v % nano::den)
+    { }
+  private:
+    time_t tv_sec;
+    long tv_nsec;
+  };
+  bool operator==(fs_timespec_rep, fs_timespec_rep);
+  fs_int128_rep operator+(fs_timespec_rep, fs_timespec_rep);
+  // ... arithmetic operators ... //
+
+The first thing to notice is that we can't construct ``fs_timespec_rep`` like
+a ``timespec`` by passing ``{secs, nsecs}``. Instead we're limited to
+constructing it from a single 64 bit integer.
+
+We also can't allow the user to inspect the ``tv_sec`` or ``tv_nsec`` values
+directly. A ``chrono::duration`` represents its value as a tick period and a
+number of ticks stored using ``rep``. The representation is unaware of the
+tick period it is being used to represent, but ``timespec`` is setup to assume
+a nanosecond tick period; which is the only case where the names ``tv_sec``
+and ``tv_nsec`` match the values they store.
+
+When we convert a nanosecond duration to seconds, ``fs_timespec_rep`` will
+use ``tv_sec`` to represent the number of giga seconds, and ``tv_nsec`` the
+remaining seconds. Let's consider how this might cause a bug were users allowed
+to manipulate the fields directly.
+
+.. code-block:: cpp
+
+  template <class Period>
+  timespec convert_to_timespec(duration<fs_time_rep, Period> dur) {
+    fs_timespec_rep rep = dur.count();
+    return {rep.tv_sec, rep.tv_nsec}; // Oops! Period may not be nanoseconds.
+  }
+
+  template <class Duration>
+  Duration convert_to_duration(timespec ts) {
+    Duration dur({ts.tv_sec, ts.tv_nsec}); // Oops! Period may not be nanoseconds.
+    return file_time_type(dur);
+    file_time_type tp = last_write_time(p);
+    auto dur =
+  }
+
+  time_t extract_seconds(file_time_type tp) {
+    // Converting to seconds is a silly bug, but I could see it happening.
+    using SecsT = chrono::duration<file_time_type::rep, ratio<1, 1>>;
+    auto secs = duration_cast<Secs>(tp.time_since_epoch());
+    // tv_sec is now representing gigaseconds.
+    return secs.count().tv_sec; // Oops!
+  }
+
+Despite ``fs_timespec_rep`` not being usable in any manner resembling
+``timespec``, it still might buy us our goal of matching its range exactly,
+right?
+
+Sort of. Chrono provides a specialization point which specifies the minimum
+and maximum values for a custom representation. It looks like this:
+
+.. code-block:: cpp
+
+  template <>
+  struct duration_values<fs_timespec_rep> {
+    static fs_timespec_rep zero();
+    static fs_timespec_rep min();
+    static fs_timespec_rep max() { // assume friendship.
+      fs_timespec_rep val;
+      val.tv_sec = numeric_limits<time_t>::max();
+      val.tv_nsec = nano::den - 1;
+      return val;
+    }
+  };
+
+Notice that ``duration_values`` doesn't tell the representation what tick
+period it's actually representing. This would indeed correctly limit the range
+of ``duration<fs_timespec_rep, nano>`` to exactly that of ``timespec``. But
+nanoseconds isn't the only tick period it will be used to represent. For
+example:
+
+.. code-block:: cpp
+
+  void test() {
+    using rep = file_time_type::rep;
+    using fs_nsec = duration<rep, nano>;
+    using fs_sec = duration<rep>;
+    fs_nsec nsecs(fs_seconds::max()); // Truncates
+  }
+
+Though the above example may appear silly, I think it follows from the incorrect
+notion that using a ``timespec`` rep in chrono actually makes it act as if it
+were an actual ``timespec``.
+
+Interactions with 32 bit ``time_t``
+-----------------------------------
+
+Up until now we've only be considering cases where ``time_t`` is 64 bits, but what
+about 32 bit systems/builds where ``time_t`` is 32 bits? (this is the common case
+for 32 bit builds).
+
+When ``time_t`` is 32 bits, we can implement ``file_time_type`` simply using 64-bit
+``long long``. There is no need to get either ``__int128_t`` or ``timespec`` emulation
+involved. And nor should we, as it would suffer from the numerous complications
+described by this paper.
+
+Obviously our implementation for 32-bit builds should act as similarly to the
+64-bit build as possible. Code which compiles in one, should compile in the other.
+This consideration is important when choosing between ``__int128_t`` and
+emulating ``timespec``. The solution which provides the most uniformity with
+the least eccentricity is the preferable one.
+
+Summary
+=======
+
+The ``file_time_type`` time point is used to represent the write times for files.
+Its job is to act as part of a C++ wrapper for less ideal system interfaces. The
+underlying filesystem uses the ``timespec`` struct for the same purpose.
+
+However, the initial implementation of ``file_time_type`` could not represent
+either the range or resolution of ``timespec``, making it unsuitable. Fixing
+this requires an implementation which uses more than 64 bits to store the
+time point.
+
+We primarily considered two solutions: Using ``__int128_t`` and using a
+arithmetic emulation of ``timespec``. Each has its pros and cons, and both
+come with more than one complication.
+
+The Potential Solutions
+-----------------------
+
+``long long`` - The Status Quo
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Pros:
+
+* As a type ``long long`` plays the nicest with others:
+
+  * It works with streaming operators and other library entities which support
+    builtin integer types, but don't support ``__int128_t``.
+  * Its the representation used by chrono's ``nanosecond`` and ``second`` typedefs.
+
+Cons:
+
+* It cannot provide the same resolution as ``timespec`` unless we limit it
+  to a range of +/- 300 years from the epoch.
+* It cannot provide the same range as ``timespec`` unless we limit its resolution
+  to seconds.
+* ``last_write_time`` has to report an error when the time reported by the filesystem
+  is unrepresentable.
+
+__int128_t
+~~~~~~~~~~~
+
+Pros:
+
+* It is an integer type.
+* It makes the implementation simple and efficient.
+* Acts exactly like other arithmetic types.
+* Can be implicitly converted to a builtin integer type by the user.
+
+  * This is important for doing things like:
+
+    .. code-block:: cpp
+
+      void c_interface_using_time_t(const char* p, time_t);
+
+      void foo(path p) {
+        file_time_type tp = last_write_time(p);
+        time_t secs = duration_cast<seconds>(tp.time_since_epoch()).count();
+        c_interface_using_time_t(p.c_str(), secs);
+      }
+
+Cons:
+
+* It isn't always available (but on 64 bit machines, it normally is).
+* It causes ``file_time_type`` to have a larger range than ``timespec``.
+* It doesn't always act the same as other builtin integer types. For example
+  with ``cout`` or ``to_string``.
+* Allows implicit truncation to 64 bit integers.
+* It can be implicitly converted to a builtin integer type by the user,
+  truncating its value.
+
+Arithmetic ``timespec`` Emulation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Pros:
+
+* It has the exact same range and resolution of ``timespec`` when representing
+  a nanosecond tick period.
+* It's always available, unlike ``__int128_t``.
+
+Cons:
+
+* It has a larger range when representing any period longer than a nanosecond.
+* Doesn't actually allow users to use it like a ``timespec``.
+* The required representation of using ``tv_sec`` to store the giga tick count
+  and ``tv_nsec`` to store the remainder adds nothing over a 128 bit integer,
+  but complicates a lot.
+* It isn't a builtin integer type, and can't be used anything like one.
+* Chrono can be made to work with it, but not nicely.
+* Emulating arithmetic classes come with their own host of problems regarding
+  overload resolution (Each operator needs three SFINAE constrained versions of
+  it in order to act like builtin integer types).
+* It offers little over simply using ``__int128_t``.
+* It acts the most differently than implementations using an actual integer type,
+  which has a high chance of breaking source compatibility.
+
+
+Selected Solution - Using ``__int128_t``
+=========================================
+
+The solution I selected for libc++ is using ``__int128_t`` when available,
+and otherwise falling back to using ``long long`` with nanosecond precision.
+
+When ``__int128_t`` is available, or when ``time_t`` is 32-bits, the implementation
+provides same resolution and a greater range than ``timespec``. Otherwise
+it still provides the same resolution, but is limited to a range of +/- 300
+years. This final case should be rather rare, as ``__int128_t``
+is normally available in 64-bit builds, and ``time_t`` is normally 32-bits
+during 32-bit builds.
+
+Although falling back to ``long long`` and nanosecond precision is less than
+ideal, it also happens to be the implementation provided by both libstdc++
+and MSVC. (So that makes it better, right?)
+
+Although the ``timespec`` emulation solution is feasible and would largely
+do what we want, it comes with too many complications, potential problems
+and discrepancies when compared to "normal" chrono time points and durations.
+
+An emulation of a builtin arithmetic type using a class is never going to act
+exactly the same, and the difference will be felt by users. It's not reasonable
+to expect them to tolerate and work around these differences. And once
+we commit to an ABI it will be too late to change. Committing to this seems
+risky.
+
+Therefore, ``__int128_t`` seems like the better solution.
diff --git a/docs/DesignDocs/NoexceptPolicy.rst b/docs/DesignDocs/NoexceptPolicy.rst
new file mode 100644
index 0000000..8dc5e14
--- /dev/null
+++ b/docs/DesignDocs/NoexceptPolicy.rst
@@ -0,0 +1,13 @@
+====================
+``noexcept`` Policy
+====================
+
+Extended applications of ``noexcept``
+------------------------------------------
+
+As of version 13 libc++ may mark functions that do not throw (i.e.,
+"Throws: Nothing") as ``noexcept``. This has two primary consequences:
+first, functions might not report precondition violations by throwing.
+Second, user-provided functions, such as custom predicates or custom
+traits, which throw might not be propagated up to the caller (unless
+specified otherwise by the Standard).
diff --git a/docs/DesignDocs/ThreadingSupportAPI.rst b/docs/DesignDocs/ThreadingSupportAPI.rst
new file mode 100644
index 0000000..330ce74
--- /dev/null
+++ b/docs/DesignDocs/ThreadingSupportAPI.rst
@@ -0,0 +1,83 @@
+=====================
+Threading Support API
+=====================
+
+.. contents::
+   :local:
+
+Overview
+========
+
+Libc++ supports using multiple different threading models and configurations
+to implement the threading parts of libc++, including ``<thread>`` and ``<mutex>``.
+These different models provide entirely different interfaces from each
+other. To address this libc++ wraps the underlying threading API in a new and
+consistent API, which it uses internally to implement threading primitives.
+
+The ``<__threading_support>`` header is where libc++ defines its internal
+threading interface. It contains forward declarations of the internal threading
+interface as well as definitions for the interface.
+
+External Threading API and the ``<__external_threading>`` header
+================================================================
+
+In order to support vendors with custom threading API's libc++ allows the
+entire internal threading interface to be provided by an external,
+vendor provided, header.
+
+When ``_LIBCPP_HAS_THREAD_API_EXTERNAL`` is defined the ``<__threading_support>``
+header simply forwards to the ``<__external_threading>`` header (which must exist).
+It is expected that the ``<__external_threading>`` header provide the exact
+interface normally provided by ``<__threading_support>``.
+
+External Threading Library
+==========================
+
+libc++ can be compiled with its internal threading API delegating to an external
+library. Such a configuration is useful for library vendors who wish to
+distribute a thread-agnostic libc++ library, where the users of the library are
+expected to provide the implementation of the libc++ internal threading API.
+
+On a production setting, this would be achieved through a custom
+``<__external_threading>`` header, which declares the libc++ internal threading
+API but leaves out the implementation.
+
+The ``-DLIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY`` option allows building libc++ in
+such a configuration while allowing it to be tested on a platform that supports
+any of the threading systems (e.g. pthread) supported in ``__threading_support``
+header. Therefore, the main purpose of this option is to allow testing of this
+particular configuration of the library without being tied to a vendor-specific
+threading system. This option is only meant to be used by libc++ library
+developers.
+
+Threading Configuration Macros
+==============================
+
+**_LIBCPP_HAS_NO_THREADS**
+  This macro is defined when libc++ is built without threading support. It
+  should not be manually defined by the user.
+
+**_LIBCPP_HAS_THREAD_API_EXTERNAL**
+  This macro is defined when libc++ should use the ``<__external_threading>``
+  header to provide the internal threading API. This macro overrides
+  ``_LIBCPP_HAS_THREAD_API_PTHREAD``.
+
+**_LIBCPP_HAS_THREAD_API_PTHREAD**
+  This macro is defined when libc++ should use POSIX threads to implement the
+  internal threading API.
+
+**_LIBCPP_HAS_THREAD_API_WIN32**
+  This macro is defined when libc++ should use Win32 threads to implement the
+  internal threading API.
+
+**_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL**
+  This macro is defined when libc++ expects the definitions of the internal
+  threading API to be provided by an external library. When defined
+  ``<__threading_support>`` will only provide the forward declarations and
+  typedefs for the internal threading API.
+
+**_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL**
+  This macro is used to build an external threading library using the
+  ``<__threading_support>``. Specifically it exposes the threading API
+  definitions in ``<__threading_support>`` as non-inline definitions meant to
+  be compiled into a library.
diff --git a/docs/DesignDocs/UniquePtrTrivialAbi.rst b/docs/DesignDocs/UniquePtrTrivialAbi.rst
new file mode 100644
index 0000000..a0f260a
--- /dev/null
+++ b/docs/DesignDocs/UniquePtrTrivialAbi.rst
@@ -0,0 +1,149 @@
+=============================================
+Enable std::unique_ptr [[clang::trivial_abi]]
+=============================================
+
+Background
+==========
+
+Consider the follow snippets
+
+
+.. code-block:: cpp
+
+    void raw_func(Foo* raw_arg) { ... }
+    void smart_func(std::unique_ptr<Foo> smart_arg) { ... }
+
+    Foo* raw_ptr_retval() { ... }
+    std::unique_ptr<Foo*> smart_ptr_retval() { ... }
+
+
+
+The argument ``raw_arg`` could be passed in a register but ``smart_arg`` could not, due to current
+implementation.
+
+Specifically, in the ``smart_arg`` case, the caller secretly constructs a temporary ``std::unique_ptr``
+in its stack-frame, and then passes a pointer to it to the callee in a hidden parameter.
+Similarly, the return value from ``smart_ptr_retval`` is secretly allocated in the caller and
+passed as a secret reference to the callee.
+
+
+Goal
+===================
+
+``std::unique_ptr`` is passed directly in a register.
+
+Design
+======
+
+* Annotate the two definitions of ``std::unique_ptr``  with ``clang::trivial_abi`` attribute.
+* Put the attribuate behind a flag because this change has potential compilation and runtime breakages.
+
+
+This comes with some side effects:
+
+* ``std::unique_ptr`` parameters will now be destroyed by callees, rather than callers.
+  It is worth noting that destruction by callee is not unique to the use of trivial_abi attribute.
+  In most Microsoft's ABIs, arguments are always destroyed by the callee.
+
+  Consequently, this may change the destruction order for function parameters to an order that is non-conforming to the standard.
+  For example:
+
+
+  .. code-block:: cpp
+
+    struct A { ~A(); };
+    struct B { ~B(); };
+    struct C { C(A, unique_ptr<B>, A) {} };
+    C c{{}, make_unique<B>, {}};
+
+
+  In a conforming implementation, the destruction order for C::C's parameters is required to be ``~A(), ~B(), ~A()`` but with this mode enabled, we'll instead see ``~B(), ~A(), ~A()``.
+
+* Reduced code-size.
+
+
+Performance impact
+------------------
+
+Google has measured performance improvements of up to 1.6% on some large server macrobenchmarks, and a small reduction in binary sizes.
+
+This also affects null pointer optimization
+
+Clang's optimizer can now figure out when a `std::unique_ptr` is known to contain *non*-null.
+(Actually, this has been a *missed* optimization all along.)
+
+
+.. code-block:: cpp
+
+    struct Foo {
+      ~Foo();
+    };
+    std::unique_ptr<Foo> make_foo();
+    void do_nothing(const Foo&)
+
+    void bar() {
+      auto x = make_foo();
+      do_nothing(*x);
+    }
+
+
+With this change, ``~Foo()`` will be called even if ``make_foo`` returns ``unique_ptr<Foo>(nullptr)``.
+The compiler can now assume that ``x.get()`` cannot be null by the end of ``bar()``, because
+the deference of ``x`` would be UB if it were ``nullptr``. (This dereference would not have caused
+a segfault, because no load is generated for dereferencing a pointer to a reference. This can be detected with ``-fsanitize=null``).
+
+
+Potential breakages
+-------------------
+
+The following breakages were discovered by enabling this change and fixing the resulting issues in a large code base.
+
+- Compilation failures
+
+ - Function definitions now require complete type ``T`` for parameters with type ``std::unique_ptr<T>``. The following code will no longer compile.
+
+   .. code-block:: cpp
+
+       class Foo;
+       void func(std::unique_ptr<Foo> arg) { /* never use `arg` directly */ }
+
+ - Fix: Remove forward-declaration of ``Foo`` and include its proper header.
+
+- Runtime Failures
+
+ - Lifetime of ``std::unique_ptr<>`` arguments end earlier (at the end of the callee's body, rather than at the end of the full expression containing the call).
+
+   .. code-block:: cpp
+
+     util::Status run_worker(std::unique_ptr<Foo>);
+     void func() {
+        std::unique_ptr<Foo> smart_foo = ...;
+        Foo* owned_foo = smart_foo.get();
+        // Currently, the following would "work" because the argument to run_worker() is deleted at the end of func()
+        // With the new calling convention, it will be deleted at the end of run_worker(),
+        // making this an access to freed memory.
+        owned_foo->Bar(run_worker(std::move(smart_foo)));
+                  ^
+                 // <<<Crash expected here
+     }
+
+ - Lifetime of local *returned* ``std::unique_ptr<>`` ends earlier.
+
+   Spot the bug:
+
+    .. code-block:: cpp
+
+     std::unique_ptr<Foo> create_and_subscribe(Bar* subscriber) {
+       auto foo = std::make_unique<Foo>();
+       subscriber->sub([&foo] { foo->do_thing();} );
+       return foo;
+     }
+
+   One could point out this is an obvious stack-use-after return bug.
+   With the current calling convention, running this code with ASAN enabled, however, would not yield any "issue".
+   So is this a bug in ASAN? (Spoiler: No)
+
+   This currently would "work" only because the storage for ``foo`` is in the caller's stackframe.
+   In other words, ``&foo`` in callee and ``&foo`` in the caller are the same address.
+
+ASAN can be used to detect both of these.
diff --git a/docs/DesignDocs/VisibilityMacros.rst b/docs/DesignDocs/VisibilityMacros.rst
new file mode 100644
index 0000000..e5aa500
--- /dev/null
+++ b/docs/DesignDocs/VisibilityMacros.rst
@@ -0,0 +1,218 @@
+========================
+Symbol Visibility Macros
+========================
+
+.. contents::
+   :local:
+
+.. _visibility-macros:
+
+Overview
+========
+
+Libc++ uses various "visibility" macros in order to provide a stable ABI in
+both the library and the headers. These macros work by changing the
+visibility and inlining characteristics of the symbols they are applied to.
+
+Visibility Macros
+=================
+
+**_LIBCPP_HIDDEN**
+  Mark a symbol as hidden so it will not be exported from shared libraries.
+
+**_LIBCPP_FUNC_VIS**
+  Mark a symbol as being exported by the libc++ library. This attribute must
+  be applied to the declaration of all functions exported by the libc++ dylib.
+
+**_LIBCPP_EXPORTED_FROM_ABI**
+  Mark a symbol as being exported by the libc++ library. This attribute may
+  only be applied to objects defined in the libc++ runtime library. On Windows,
+  this macro applies `dllimport`/`dllexport` to the symbol, and on other
+  platforms it gives the symbol default visibility.
+
+**_LIBCPP_OVERRIDABLE_FUNC_VIS**
+  Mark a symbol as being exported by the libc++ library, but allow it to be
+  overridden locally. On non-Windows, this is equivalent to `_LIBCPP_FUNC_VIS`.
+  This macro is applied to all `operator new` and `operator delete` overloads.
+
+  **Windows Behavior**: Any symbol marked `dllimport` cannot be overridden
+  locally, since `dllimport` indicates the symbol should be bound to a separate
+  DLL. All `operator new` and `operator delete` overloads are required to be
+  locally overridable, and therefore must not be marked `dllimport`. On Windows,
+  this macro therefore expands to `__declspec(dllexport)` when building the
+  library and has an empty definition otherwise.
+
+**_LIBCPP_HIDE_FROM_ABI**
+  Mark a function as not being part of the ABI of any final linked image that
+  uses it.
+
+**_LIBCPP_INLINE_VISIBILITY**
+  Historical predecessor of ``_LIBCPP_HIDE_FROM_ABI`` -- please use
+  ``_LIBCPP_HIDE_FROM_ABI`` instead.
+
+**_LIBCPP_HIDE_FROM_ABI_AFTER_V1**
+  Mark a function as being hidden from the ABI (per `_LIBCPP_HIDE_FROM_ABI`)
+  when libc++ is built with an ABI version after ABI v1. This macro is used to
+  maintain ABI compatibility for symbols that have been historically exported
+  by libc++ in v1 of the ABI, but that we don't want to export in the future.
+
+  This macro works as follows. When we build libc++, we either hide the symbol
+  from the ABI (if the symbol is not part of the ABI in the version we're
+  building), or we leave it included. From user code (i.e. when we're not
+  building libc++), the macro always marks symbols as internal so that programs
+  built using new libc++ headers stop relying on symbols that are removed from
+  the ABI in a future version. Each time we release a new stable version of the
+  ABI, we should create a new _LIBCPP_HIDE_FROM_ABI_AFTER_XXX macro, and we can
+  use it to start removing symbols from the ABI after that stable version.
+
+**_LIBCPP_HIDE_FROM_ABI_PER_TU**
+  This macro controls whether symbols hidden from the ABI with `_LIBCPP_HIDE_FROM_ABI`
+  are local to each translation unit in addition to being local to each final
+  linked image. This macro is defined to either 0 or 1. When it is defined to
+  1, translation units compiled with different versions of libc++ can be linked
+  together, since all non ABI-facing functions are local to each translation unit.
+  This allows static archives built with different versions of libc++ to be linked
+  together. This also means that functions marked with `_LIBCPP_HIDE_FROM_ABI`
+  are not guaranteed to have the same address across translation unit boundaries.
+
+  When the macro is defined to 0, there is no guarantee that translation units
+  compiled with different versions of libc++ can interoperate. However, this
+  leads to code size improvements, since non ABI-facing functions can be
+  deduplicated across translation unit boundaries.
+
+  This macro can be defined by users to control the behavior they want from
+  libc++. The default value of this macro (0 or 1) is controlled by whether
+  `_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT` is defined, which is intended to
+  be used by vendors only (see below).
+
+**_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT**
+  This macro controls the default value for `_LIBCPP_HIDE_FROM_ABI_PER_TU`.
+  When the macro is defined, per TU ABI insulation is enabled by default, and
+  `_LIBCPP_HIDE_FROM_ABI_PER_TU` is defined to 1 unless overridden by users.
+  Otherwise, per TU ABI insulation is disabled by default, and
+  `_LIBCPP_HIDE_FROM_ABI_PER_TU` is defined to 0 unless overridden by users.
+
+  This macro is intended for vendors to control whether they want to ship
+  libc++ with per TU ABI insulation enabled by default. Users can always
+  control the behavior they want by defining `_LIBCPP_HIDE_FROM_ABI_PER_TU`
+  appropriately.
+
+  By default, this macro is not defined, which means that per TU ABI insulation
+  is not provided unless explicitly overridden by users.
+
+**_LIBCPP_TYPE_VIS**
+  Mark a type's typeinfo, vtable and members as having default visibility.
+  This attribute cannot be used on class templates.
+
+**_LIBCPP_TEMPLATE_VIS**
+  Mark a type's typeinfo and vtable as having default visibility.
+  This macro has no effect on the visibility of the type's member functions.
+
+  **GCC Behavior**: GCC does not support Clang's `type_visibility(...)`
+  attribute. With GCC the `visibility(...)` attribute is used and member
+  functions are affected.
+
+  **Windows Behavior**: DLLs do not support dllimport/export on class templates.
+  The macro has an empty definition on this platform.
+
+
+**_LIBCPP_ENUM_VIS**
+  Mark the typeinfo of an enum as having default visibility. This attribute
+  should be applied to all enum declarations.
+
+  **Windows Behavior**: DLLs do not support importing or exporting enumeration
+  typeinfo. The macro has an empty definition on this platform.
+
+  **GCC Behavior**: GCC un-hides the typeinfo for enumerations by default, even
+  if `-fvisibility=hidden` is specified. Additionally applying a visibility
+  attribute to an enum class results in a warning. The macro has an empty
+  definition with GCC.
+
+**_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS**
+  Mark the member functions, typeinfo, and vtable of the type named in
+  a `_LIBCPP_EXTERN_TEMPLATE` declaration as being exported by the libc++ library.
+  This attribute must be specified on all extern class template declarations.
+
+  This macro is used to override the `_LIBCPP_TEMPLATE_VIS` attribute
+  specified on the primary template and to export the member functions produced
+  by the explicit instantiation in the dylib.
+
+  **Windows Behavior**: `extern template` and `dllexport` are fundamentally
+  incompatible *on a class template* on Windows; the former suppresses
+  instantiation, while the latter forces it. Specifying both on the same
+  declaration makes the class template be instantiated, which is not desirable
+  inside headers. This macro therefore expands to `dllimport` outside of libc++
+  but nothing inside of it (rather than expanding to `dllexport`); instead, the
+  explicit instantiations themselves are marked as exported. Note that this
+  applies *only* to extern *class* templates. Extern *function* templates obey
+  regular import/export semantics, and applying `dllexport` directly to the
+  extern template declaration (i.e. using `_LIBCPP_FUNC_VIS`) is the correct
+  thing to do for them.
+
+**_LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS**
+  Mark the member functions, typeinfo, and vtable of an explicit instantiation
+  of a class template as being exported by the libc++ library. This attribute
+  must be specified on all class template explicit instantiations.
+
+  It is only necessary to mark the explicit instantiation itself (as opposed to
+  the extern template declaration) as exported on Windows, as discussed above.
+  On all other platforms, this macro has an empty definition.
+
+**_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS**
+  Mark a symbol as hidden so it will not be exported from shared libraries. This
+  is intended specifically for method templates of either classes marked with
+  `_LIBCPP_TYPE_VIS` or classes with an extern template instantiation
+  declaration marked with `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS`.
+
+  When building libc++ with hidden visibility, we want explicit template
+  instantiations to export members, which is consistent with existing Windows
+  behavior. We also want classes annotated with `_LIBCPP_TYPE_VIS` to export
+  their members, which is again consistent with existing Windows behavior.
+  Both these changes are necessary for clients to be able to link against a
+  libc++ DSO built with hidden visibility without encountering missing symbols.
+
+  An unfortunate side effect, however, is that method templates of classes
+  either marked `_LIBCPP_TYPE_VIS` or with extern template instantiation
+  declarations marked with `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` also get default
+  visibility when instantiated. These methods are often implicitly instantiated
+  inside other libraries which use the libc++ headers, and will therefore end up
+  being exported from those libraries, since those implicit instantiations will
+  receive default visibility. This is not acceptable for libraries that wish to
+  control their visibility, and led to PR30642.
+
+  Consequently, all such problematic method templates are explicitly marked
+  either hidden (via this macro) or inline, so that they don't leak into client
+  libraries. The problematic methods were found by running
+  `bad-visibility-finder <https://github.com/smeenai/bad-visibility-finder>`_
+  against the libc++ headers after making `_LIBCPP_TYPE_VIS` and
+  `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` expand to default visibility.
+
+**_LIBCPP_EXCEPTION_ABI**
+  Mark the member functions, typeinfo, and vtable of the type as being exported
+  by the libc++ library. This macro must be applied to all *exception types*.
+  Exception types should be defined directly in namespace `std` and not the
+  versioning namespace. This allows throwing and catching some exception types
+  between libc++ and libstdc++.
+
+**_LIBCPP_INTERNAL_LINKAGE**
+  Mark the affected entity as having internal linkage (i.e. the `static`
+  keyword in C). This is only a best effort: when the `internal_linkage`
+  attribute is not available, we fall back to forcing the function to be
+  inlined, which approximates internal linkage since an externally visible
+  symbol is never generated for that function. This is an internal macro
+  used as an implementation detail by other visibility macros. Never mark
+  a function or a class with this macro directly.
+
+**_LIBCPP_ALWAYS_INLINE**
+  Forces inlining of the function it is applied to. For visibility purposes,
+  this macro is used to make sure that an externally visible symbol is never
+  generated in an object file when the `internal_linkage` attribute is not
+  available. This is an internal macro used by other visibility macros, and
+  it should not be used directly.
+
+Links
+=====
+
+* `[cfe-dev] Visibility in libc++ - 1 <http://lists.llvm.org/pipermail/cfe-dev/2013-July/030610.html>`_
+* `[cfe-dev] Visibility in libc++ - 2 <http://lists.llvm.org/pipermail/cfe-dev/2013-August/031195.html>`_
+* `[libcxx] Visibility fixes for Windows <http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20130805/085461.html>`_
diff --git a/docs/FeatureTestMacroTable.rst b/docs/FeatureTestMacroTable.rst
new file mode 100644
index 0000000..c2690e7
--- /dev/null
+++ b/docs/FeatureTestMacroTable.rst
@@ -0,0 +1,307 @@
+.. _FeatureTestMacroTable:
+
+==========================
+Feature Test Macro Support
+==========================
+
+.. contents::
+   :local:
+
+Overview
+========
+
+This file documents the feature test macros currently supported by libc++.
+
+.. _feature-status:
+
+Status
+======
+
+.. table:: Current Status
+     :name: feature-status-table
+     :widths: auto
+
+    ================================================= =================
+    Macro Name                                        Value
+    ================================================= =================
+    **C++ 14**
+    -------------------------------------------------------------------
+    ``__cpp_lib_chrono_udls``                         ``201304L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_complex_udls``                        ``201309L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_exchange_function``                   ``201304L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_generic_associative_lookup``          ``201304L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_integer_sequence``                    ``201304L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_integral_constant_callable``          ``201304L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_final``                            ``201402L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_null_pointer``                     ``201309L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_make_reverse_iterator``               ``201402L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_make_unique``                         ``201304L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_null_iterators``                      ``201304L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_quoted_string_io``                    ``201304L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_result_of_sfinae``                    ``201210L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_robust_nonmodifying_seq_ops``         ``201304L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_shared_timed_mutex``                  ``201402L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_string_udls``                         ``201304L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_transformation_trait_aliases``        ``201304L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_transparent_operators``               ``201210L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_tuple_element_t``                     ``201402L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_tuples_by_type``                      ``201304L``
+    ------------------------------------------------- -----------------
+    **C++ 17**
+    -------------------------------------------------------------------
+    ``__cpp_lib_addressof_constexpr``                 ``201603L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_allocator_traits_is_always_equal``    ``201411L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_any``                                 ``201606L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_apply``                               ``201603L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_array_constexpr``                     ``201603L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_as_const``                            ``201510L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_atomic_is_always_lock_free``          ``201603L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_bool_constant``                       ``201505L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_boyer_moore_searcher``                *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_byte``                                ``201603L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_chrono``                              ``201611L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_clamp``                               ``201603L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_enable_shared_from_this``             ``201603L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_execution``                           *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_filesystem``                          ``201703L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_gcd_lcm``                             ``201606L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_hardware_interference_size``          *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_has_unique_object_representations``   ``201606L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_hypot``                               ``201603L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_incomplete_container_elements``       ``201505L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_invoke``                              ``201411L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_aggregate``                        ``201703L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_invocable``                        ``201703L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_swappable``                        ``201603L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_launder``                             ``201606L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_logical_traits``                      ``201510L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_make_from_tuple``                     ``201606L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_map_try_emplace``                     ``201411L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_math_special_functions``              *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_memory_resource``                     *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_node_extract``                        ``201606L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_nonmember_container_access``          ``201411L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_not_fn``                              ``201603L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_optional``                            ``201606L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_parallel_algorithm``                  *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_raw_memory_algorithms``               ``201606L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_sample``                              ``201603L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_scoped_lock``                         ``201703L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_shared_mutex``                        ``201505L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_shared_ptr_arrays``                   ``201611L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_shared_ptr_weak_type``                ``201606L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_string_view``                         ``201606L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_to_chars``                            *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_transparent_operators``               ``201510L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_type_trait_variable_templates``       ``201510L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_uncaught_exceptions``                 ``201411L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_unordered_map_try_emplace``           ``201411L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_variant``                             ``202102L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_void_t``                              ``201411L``
+    ------------------------------------------------- -----------------
+    **C++ 20**
+    -------------------------------------------------------------------
+    ``__cpp_lib_array_constexpr``                     ``201811L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_assume_aligned``                      *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_atomic_flag_test``                    ``201907L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_atomic_float``                        *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_atomic_lock_free_type_aliases``       ``201907L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_atomic_ref``                          *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_atomic_shared_ptr``                   *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_atomic_value_initialization``         ``201911L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_atomic_wait``                         ``201907L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_barrier``                             ``201907L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_bind_front``                          ``201907L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_bit_cast``                            *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_bitops``                              *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_bounded_array_traits``                ``201902L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_char8_t``                             ``201811L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_concepts``                            ``202002L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_algorithms``                ``201806L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_complex``                   *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_dynamic_alloc``             ``201907L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_functional``                ``201907L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_iterator``                  ``201811L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_memory``                    ``201811L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_numeric``                   ``201911L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_string``                    ``201811L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_string_view``               ``201811L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_tuple``                     ``201811L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_utility``                   ``201811L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_vector``                    *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_coroutine``                           *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_destroying_delete``                   ``201806L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_endian``                              ``201907L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_erase_if``                            ``202002L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_execution``                           *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_format``                              *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_generic_unordered_lookup``            ``201811L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_int_pow2``                            ``202002L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_integer_comparison_functions``        ``202002L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_interpolate``                         ``201902L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_constant_evaluated``               ``201811L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_layout_compatible``                *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_nothrow_convertible``              ``201806L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_is_pointer_interconvertible``         *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_jthread``                             *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_latch``                               ``201907L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_list_remove_return_type``             ``201806L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_math_constants``                      ``201907L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_polymorphic_allocator``               *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_ranges``                              *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_remove_cvref``                        ``201711L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_semaphore``                           ``201907L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_shift``                               ``201806L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_smart_ptr_for_overwrite``             *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_source_location``                     *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_span``                                ``202002L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_ssize``                               ``201902L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_starts_ends_with``                    ``201711L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_string_view``                         ``201803L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_syncbuf``                             *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_three_way_comparison``                *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_to_address``                          ``201711L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_to_array``                            ``201907L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_unwrap_ref``                          ``201811L``
+    ------------------------------------------------- -----------------
+    **C++ 2b**
+    -------------------------------------------------------------------
+    ``__cpp_lib_is_scoped_enum``                      ``202011L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_stacktrace``                          *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_stdatomic_h``                         *unimplemented*
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_string_contains``                     ``202011L``
+    ------------------------------------------------- -----------------
+    ``__cpp_lib_to_underlying``                       ``202102L``
+    ================================================= =================
+
diff --git a/docs/Helpers/Styles.rst b/docs/Helpers/Styles.rst
new file mode 100644
index 0000000..9bba3bf
--- /dev/null
+++ b/docs/Helpers/Styles.rst
@@ -0,0 +1,31 @@
+.. raw:: html

+

+      <style type="text/css">

+        .nothingtodo {

+            background-color: #99FF99;

+            font-style: italic;

+         }

+        .inprogress {

+            background-color: #FFFF99;

+            font-style: italic;

+         }

+        .partial {

+            background-color: #2CCCFF;

+            font-style: italic;

+         }

+        .complete { background-color: #99FF99; }

+      </style>

+

+.. role:: nothingtodo

+.. role:: inprogress

+.. role:: partial

+.. role:: complete

+

+

+.. |Nothing To Do| replace:: :nothingtodo:`Nothing To Do`

+.. |In Progress| replace:: :inprogress:`In Progress`

+.. |Partial| replace:: :partial:`Partial`

+.. |Complete| replace:: :complete:`Complete`

+

+.. |sect| unicode:: U+00A7

+.. |hellip| unicode:: U+2026

diff --git a/docs/Makefile.sphinx b/docs/Makefile.sphinx
new file mode 100644
index 0000000..a34f0cc
--- /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    = -n -W -v
+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..ff7e71f
--- /dev/null
+++ b/docs/README.txt
@@ -0,0 +1,17 @@
+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.
+
+The documentation in this directory is published at https://libcxx.llvm.org. It is kept up-to-date
+by a build bot: https://lab.llvm.org/buildbot/#/builders/publish-sphinx-docs. If you notice that the
+documentation is not updating anymore, please contact one of the maintainers.
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
new file mode 100644
index 0000000..85b7016
--- /dev/null
+++ b/docs/ReleaseNotes.rst
@@ -0,0 +1,103 @@
+=========================================
+Libc++ 13.0.0 (In-Progress) Release Notes
+=========================================
+
+.. contents::
+   :local:
+   :depth: 2
+
+Written by the `Libc++ Team <https://libcxx.llvm.org>`_
+
+.. warning::
+
+   These are in-progress notes for the upcoming libc++ 13 release.
+   Release notes for previous releases can be found on
+   `the Download Page <https://releases.llvm.org/download.html>`_.
+
+Introduction
+============
+
+This document contains the release notes for the libc++ C++ Standard Library,
+part of the LLVM Compiler Infrastructure, release 13.0.0. Here we describe the
+status of libc++ in some detail, including major improvements from the previous
+release and new feature work. For the general LLVM release notes, see `the LLVM
+documentation <https://llvm.org/docs/ReleaseNotes.html>`_. All LLVM releases may
+be downloaded from the `LLVM releases web site <https://llvm.org/releases/>`_.
+
+For more information about libc++, please see the `Libc++ Web Site
+<https://libcxx.llvm.org>`_ or the `LLVM Web Site <https://llvm.org>`_.
+
+Note that if you are reading this file from a Git checkout or the
+main Libc++ web page, this document applies to the *next* release, not
+the current one. To see the release notes for a specific release, please
+see the `releases page <https://llvm.org/releases/>`_.
+
+What's New in Libc++ 13.0.0?
+============================
+
+- Support for older compilers has been removed. Several additional platforms
+  are now officially supported. :ref:`platform_and_compiler_support` contains
+  the complete overview of platforms and compilers supported by libc++.
+- The large headers ``<algorithm>``, ``<iterator>``, and ``<utility>`` have
+  been split in more granular headers. This reduces the size of included code
+  when using libc++. This may lead to missing includes after upgrading to
+  libc++13.
+
+New Features
+------------
+
+- ``std::filesystem`` is now feature complete for the Windows platform using
+  MinGW. MSVC isn't supported since it lacks 128-bit integer support.
+- The implementation of the C++20 concepts library has been completed.
+- Several C++20 ``constexpr`` papers have been completed:
+
+  - `P0879R0 <https://wg21.link/P0879R0>`_ ``constexpr`` for ``std::swap()``
+    and swap related functions
+  - `P1032R1 <https://wg21.link/P1032R1>`_ Misc ``constexpr`` bits
+  - `P0883 <https://wg21.link/P0883>`_ Fixing Atomic Initialization
+
+- More C++20 features have been implemented. :doc:`Status/Cxx20` has the full
+  overview of libc++'s C++20 implementation status.
+- More C++2b features have been implemented. :doc:`Status/Cxx2b` has the
+  full overview of libc++'s C++2b implementation status.
+- The CMake option ``LIBCXX_ENABLE_INCOMPLETE_FEATURES`` has been added. This
+  option allows libc++ vendors to disable headers that aren't production
+  quality yet. Currently, turning the option off disables the headers
+  ``<format>`` and ``<ranges>``.
+- The documentation conversion from html to restructured text has been
+  completed.
+
+API Changes
+-----------
+
+- There has been several changes in the tuple constructors provided by libc++.
+  Those changes were made as part of an effort to regularize libc++'s tuple
+  implementation, which contained several subtle bugs due to these extensions.
+  If you notice a build breakage when initializing a tuple, make sure you
+  properly initialize all the tuple elements - this is probably the culprit.
+
+  In particular, the extension allowing tuples to be constructed from fewer
+  elements than the number of elements in the tuple (in which case the remaining
+  elements would be default-constructed) has been removed. See https://godbolt.org/z/sqozjd.
+
+  Also, the extension allowing a tuple to be constructed from an array has been
+  removed. See https://godbolt.org/z/5esqbW.
+
+- The ``std::pointer_safety`` utility and related functions are not available
+  in C++03 anymore. Furthermore, in other standard modes, it has changed from
+  a struct to a scoped enumeration, which is an ABI break. Finally, the
+  ``std::get_pointer_safety`` function was previously in the dylib, but it
+  is now defined as inline in the headers.
+
+  While this is technically both an API and an ABI break, we do not expect
+  ``std::pointer_safety`` to have been used at all in real code, since we
+  never implemented the underlying support for garbage collection.
+
+- The `LIBCXXABI_ENABLE_PIC` CMake option was removed. If you are building your
+  own libc++abi from source and were using `LIBCXXABI_ENABLE_PIC`, please use
+  `CMAKE_POSITION_INDEPENDENT_CODE=ON` instead.
+
+- When the header <variant> is included, it will no longer include <array> transitively.
+
+- The ``std::result_of`` and ``std::is_literal_type`` type traits have been removed in
+  C++20 mode.
diff --git a/docs/Status/Cxx14.rst b/docs/Status/Cxx14.rst
new file mode 100644
index 0000000..fc3aeee
--- /dev/null
+++ b/docs/Status/Cxx14.rst
@@ -0,0 +1,52 @@
+.. _cxx14-status:

+

+================================

+libc++ C++14 Status

+================================

+

+.. include:: ../Helpers/Styles.rst

+

+.. contents::

+   :local:

+

+

+Overview

+================================

+

+In April 2013, the C++ standard committee approved the draft for the next version of the C++ standard, initially known as "C++1y".

+

+The draft standard includes papers and issues that were voted on at the previous three meetings (Kona, Portland, and Bristol).

+

+In August 2014, this draft was approved by ISO as C++14.

+

+This page shows the status of libc++; the status of clang's support of the language features is `here <https://clang.llvm.org/cxx_status.html#cxx14>`__.

+

+The groups that have contributed papers:

+

+-  CWG - Core Language Working group

+-  LWG - Library working group

+-  SG1 - Study group #1 (Concurrency working group)

+

+

+.. _paper-status-cxx14:

+

+Paper Status

+====================================

+

+.. csv-table::

+   :file: Cxx14Papers.csv

+   :header-rows: 1

+   :widths: auto

+

+

+.. _issues-status-cxx14:

+

+Library Working Group Issues Status

+====================================

+

+.. csv-table::

+   :file: Cxx14Issues.csv

+   :header-rows: 1

+   :widths: auto

+

+Last Updated: 25-Mar-2014

diff --git a/docs/Status/Cxx14Issues.csv b/docs/Status/Cxx14Issues.csv
new file mode 100644
index 0000000..02da3e7
--- /dev/null
+++ b/docs/Status/Cxx14Issues.csv
@@ -0,0 +1,157 @@
+"Issue #","Issue Name","Meeting","Status"
+"`1214 <https://wg21.link/lwg1214>`__","Insufficient/inconsistent key immutability requirements for associative containers","Kona","|Complete|"
+"`2009 <https://wg21.link/lwg2009>`__","Reporting out-of-bound values on numeric string conversions","Kona","|Complete|"
+"`2010 <https://wg21.link/lwg2010>`__","``is_*``\  traits for binding operations can't be meaningfully specialized","Kona","|Complete|"
+"`2015 <https://wg21.link/lwg2015>`__","Incorrect pre-conditions for some type traits","Kona","|Complete|"
+"`2021 <https://wg21.link/lwg2021>`__","Further incorrect usages of result_of","Kona","|Complete|"
+"`2028 <https://wg21.link/lwg2028>`__","messages_base::catalog overspecified","Kona","|Complete|"
+"`2033 <https://wg21.link/lwg2033>`__","Preconditions of reserve, shrink_to_fit, and resize functions","Kona","|Complete|"
+"`2039 <https://wg21.link/lwg2039>`__","Issues with std::reverse and std::copy_if","Kona","|Complete|"
+"`2044 <https://wg21.link/lwg2044>`__","No definition of ""Stable"" for copy algorithms","Kona","|Complete|"
+"`2045 <https://wg21.link/lwg2045>`__","forward_list::merge and forward_list::splice_after with unequal allocators","Kona","|Complete|"
+"`2047 <https://wg21.link/lwg2047>`__","Incorrect ""mixed"" move-assignment semantics of unique_ptr","Kona","|Complete|"
+"`2050 <https://wg21.link/lwg2050>`__","Unordered associative containers do not use allocator_traits to define member types","Kona","|Complete|"
+"`2053 <https://wg21.link/lwg2053>`__","Errors in regex bitmask types","Kona","|Complete|"
+"`2061 <https://wg21.link/lwg2061>`__","make_move_iterator and arrays","Kona","|Complete|"
+"`2064 <https://wg21.link/lwg2064>`__","More noexcept issues in basic_string","Kona","|Complete|"
+"`2065 <https://wg21.link/lwg2065>`__","Minimal allocator interface","Kona","|Complete|"
+"`2067 <https://wg21.link/lwg2067>`__","packaged_task should have deleted copy c'tor with const parameter","Kona","|Complete|"
+"`2069 <https://wg21.link/lwg2069>`__","Inconsistent exception spec for basic_string move constructor","Kona","|Complete|"
+"`2096 <https://wg21.link/lwg2096>`__","Incorrect constraints of future::get in regard to MoveAssignable","Kona","|Complete|"
+"`2102 <https://wg21.link/lwg2102>`__","Why is std::launch an implementation-defined type?","Kona","|Complete|"
+"","","",""
+"`2071 <https://wg21.link/lwg2071>`__","std::valarray move-assignment","Portland","|Complete|"
+"`2074 <https://wg21.link/lwg2074>`__","Off by one error in std::reverse_copy","Portland","|Complete|"
+"`2081 <https://wg21.link/lwg2081>`__","Allocator requirements should include CopyConstructible","Portland","|Complete|"
+"`2083 <https://wg21.link/lwg2083>`__","const-qualification on weak_ptr::owner_before","Portland","|Complete|"
+"`2086 <https://wg21.link/lwg2086>`__","Overly generic type support for math functions","Portland","|Complete|"
+"`2099 <https://wg21.link/lwg2099>`__","Unnecessary constraints of va_start() usage","Portland","|Complete|"
+"`2103 <https://wg21.link/lwg2103>`__","std::allocator_traits<std::allocator<T>>::propagate_on_container_move_assignment","Portland","|Complete|"
+"`2105 <https://wg21.link/lwg2105>`__","Inconsistent requirements on ``const_iterator``'s value_type","Portland","|Complete|"
+"`2110 <https://wg21.link/lwg2110>`__","remove can't swap but note says it might","Portland","|Complete|"
+"`2123 <https://wg21.link/lwg2123>`__","merge() allocator requirements for lists versus forward lists","Portland","|Complete|"
+"`2005 <https://wg21.link/lwg2005>`__","unordered_map::insert(T&&) protection should apply to map too","Portland","|Complete|"
+"`2011 <https://wg21.link/lwg2011>`__","Unexpected output required of strings","Portland","|Complete|"
+"`2048 <https://wg21.link/lwg2048>`__","Unnecessary mem_fn overloads","Portland","|Complete|"
+"`2049 <https://wg21.link/lwg2049>`__","``is_destructible``\  is underspecified","Portland","|Complete|"
+"`2056 <https://wg21.link/lwg2056>`__","future_errc enums start with value 0 (invalid value for broken_promise)","Portland","|Complete|"
+"`2058 <https://wg21.link/lwg2058>`__","valarray and begin/end","Portland","|Complete|"
+"","","",""
+"`2091 <https://wg21.link/lwg2091>`__","Misplaced effect in m.try_lock_for()","Bristol","|Complete|"
+"`2092 <https://wg21.link/lwg2092>`__","Vague Wording for condition_variable_any","Bristol","|Complete|"
+"`2093 <https://wg21.link/lwg2093>`__","Throws clause of condition_variable::wait with predicate","Bristol","|Complete|"
+"`2094 <https://wg21.link/lwg2094>`__","duration conversion overflow shouldn't participate in overload resolution","Bristol","|Complete|"
+"`2122 <https://wg21.link/lwg2122>`__","merge() stability for lists versus forward lists","Bristol","|Complete|"
+"`2128 <https://wg21.link/lwg2128>`__","Absence of global functions cbegin/cend","Bristol","|Complete|"
+"`2145 <https://wg21.link/lwg2145>`__","error_category default constructor","Bristol","|Complete|"
+"`2147 <https://wg21.link/lwg2147>`__","Unclear hint type in Allocator's allocate function","Bristol","|Complete|"
+"`2148 <https://wg21.link/lwg2148>`__","Hashing enums should be supported directly by std::hash","Bristol","|Complete|"
+"`2149 <https://wg21.link/lwg2149>`__","Concerns about 20.8/5","Bristol","|Complete|"
+"`2162 <https://wg21.link/lwg2162>`__","allocator_traits::max_size missing noexcept","Bristol","|Complete|"
+"`2163 <https://wg21.link/lwg2163>`__","nth_element requires inconsistent post-conditions","Bristol","|Complete|"
+"`2169 <https://wg21.link/lwg2169>`__","Missing reset() requirements in unique_ptr specialization","Bristol","|Complete|"
+"`2172 <https://wg21.link/lwg2172>`__","Does ``atomic_compare_exchange_*``\  accept v == nullptr arguments?","Bristol","|Complete|"
+"`2080 <https://wg21.link/lwg2080>`__","Specify when once_flag becomes invalid","Bristol","|Complete|"
+"`2098 <https://wg21.link/lwg2098>`__","promise throws clauses","Bristol","|Complete|"
+"`2109 <https://wg21.link/lwg2109>`__","Incorrect requirements for hash specializations","Bristol","|Complete|"
+"`2130 <https://wg21.link/lwg2130>`__","missing ordering constraints for fences","Bristol","|Complete|"
+"`2138 <https://wg21.link/lwg2138>`__","atomic_flag::clear ordering constraints","Bristol","|Complete|"
+"`2140 <https://wg21.link/lwg2140>`__","notify_all_at_thread_exit synchronization","Bristol","|Complete|"
+"`2144 <https://wg21.link/lwg2144>`__","Missing noexcept specification in type_index","Bristol","|Complete|"
+"`2174 <https://wg21.link/lwg2174>`__","wstring_convert::converted() should be noexcept","Bristol","|Complete|"
+"`2175 <https://wg21.link/lwg2175>`__","string_convert and wbuffer_convert validity","Bristol","|Complete|"
+"`2176 <https://wg21.link/lwg2176>`__","Special members for wstring_convert and wbuffer_convert","Bristol","|Complete|"
+"`2177 <https://wg21.link/lwg2177>`__","Requirements on Copy/MoveInsertable","Bristol","|Complete|"
+"`2185 <https://wg21.link/lwg2185>`__","Missing throws clause for future/shared_future::wait_for/wait_until","Bristol","|Complete|"
+"`2187 <https://wg21.link/lwg2187>`__","vector<bool> is missing emplace and emplace_back member functions","Bristol","|Complete|"
+"`2190 <https://wg21.link/lwg2190>`__","ordering of condition variable operations, reflects Posix discussion","Bristol","|Complete|"
+"`2196 <https://wg21.link/lwg2196>`__","Specification of ``is_*[copy/move]_[constructible/assignable]``\  unclear for non-referencable types","Bristol","|Complete|"
+"`2197 <https://wg21.link/lwg2197>`__","Specification of ``is_[un]signed``\  unclear for non-arithmetic types","Bristol","|Complete|"
+"`2200 <https://wg21.link/lwg2200>`__","Data race avoidance for all containers, not only for sequences","Bristol","|Complete|"
+"`2203 <https://wg21.link/lwg2203>`__","scoped_allocator_adaptor uses wrong argument types for piecewise construction","Bristol","|Complete|"
+"`2207 <https://wg21.link/lwg2207>`__","basic_string::at should not have a Requires clause","Bristol","|Complete|"
+"`2209 <https://wg21.link/lwg2209>`__","assign() overspecified for sequence containers","Bristol","|Complete|"
+"`2210 <https://wg21.link/lwg2210>`__","Missing allocator-extended constructor for allocator-aware containers","Bristol","|Complete|"
+"`2211 <https://wg21.link/lwg2211>`__","Replace ambiguous use of ""Allocator"" in container requirements","Bristol","|Complete|"
+"`2222 <https://wg21.link/lwg2222>`__","Inconsistency in description of forward_list::splice_after single-element overload","Bristol","|Complete|"
+"`2225 <https://wg21.link/lwg2225>`__","Unrealistic header inclusion checks required","Bristol","|Complete|"
+"`2229 <https://wg21.link/lwg2229>`__","Standard code conversion facets underspecified","Bristol","|Complete|"
+"`2231 <https://wg21.link/lwg2231>`__","DR 704 removes complexity guarantee for clear()","Bristol","|Complete|"
+"`2235 <https://wg21.link/lwg2235>`__","Undefined behavior without proper requirements on basic_string constructors","Bristol","|Complete|"
+"","","",""
+"`2141 <https://wg21.link/lwg2141>`__","common_type trait produces reference types","Chicago","|Complete|"
+"`2246 <https://wg21.link/lwg2246>`__","unique_ptr assignment effects w.r.t. deleter","Chicago","|Complete|"
+"`2247 <https://wg21.link/lwg2247>`__","Type traits and std::nullptr_t","Chicago","|Complete|"
+"`2085 <https://wg21.link/lwg2085>`__","Wrong description of effect 1 of basic_istream::ignore","Chicago","|Complete|"
+"`2087 <https://wg21.link/lwg2087>`__","iostream_category() and noexcept","Chicago","|Complete|"
+"`2143 <https://wg21.link/lwg2143>`__","ios_base::xalloc should be thread-safe","Chicago","|Complete|"
+"`2150 <https://wg21.link/lwg2150>`__","Unclear specification of find_end","Chicago","|Complete|"
+"`2180 <https://wg21.link/lwg2180>`__","Exceptions from std::seed_seq operations","Chicago","|Complete|"
+"`2194 <https://wg21.link/lwg2194>`__","Impossible container requirements for adaptor types","Chicago","|Complete|"
+"`2013 <https://wg21.link/lwg2013>`__","Do library implementers have the freedom to add constexpr?","Chicago","|Complete|"
+"`2018 <https://wg21.link/lwg2018>`__","regex_traits::isctype Returns clause is wrong","Chicago","|Complete|"
+"`2078 <https://wg21.link/lwg2078>`__","Throw specification of async() incomplete","Chicago","|Complete|"
+"`2097 <https://wg21.link/lwg2097>`__","packaged_task constructors should be constrained","Chicago","|Complete|"
+"`2100 <https://wg21.link/lwg2100>`__","Timed waiting functions cannot timeout if launch::async policy used","Chicago","|Complete|"
+"`2120 <https://wg21.link/lwg2120>`__","What should async do if neither 'async' nor 'deferred' is set in policy?","Chicago","|Complete|"
+"`2159 <https://wg21.link/lwg2159>`__","atomic_flag initialization","Chicago","|Complete|"
+"`2275 <https://wg21.link/lwg2275>`__","Why is forward_as_tuple not constexpr?","Chicago","|Complete|"
+"`2284 <https://wg21.link/lwg2284>`__","Inconsistency in allocator_traits::max_size","Chicago","|Complete|"
+"`2298 <https://wg21.link/lwg2298>`__","``is_nothrow_constructible``\  is always false because of create<>","Chicago","|Complete|"
+"`2300 <https://wg21.link/lwg2300>`__","Redundant sections for map and multimap members should be removed","Chicago","|Complete|"
+"NB comment: GB9","Remove gets from C++14","Chicago","|Complete|"
+"","","",""
+"`2135 <https://wg21.link/lwg2135>`__","Unclear requirement for exceptions thrown in condition_variable::wait()","Issaquah","|Complete|"
+"`2291 <https://wg21.link/lwg2291>`__","std::hash is vulnerable to collision DoS attack","Issaquah","|Complete|"
+"`2142 <https://wg21.link/lwg2142>`__","packaged_task::operator() synchronization too broad?","Issaquah","|Complete|"
+"`2240 <https://wg21.link/lwg2240>`__","Probable misuse of term ""function scope"" in [thread.condition]","Issaquah","|Complete|"
+"`2252 <https://wg21.link/lwg2252>`__","Strong guarantee on vector::push_back() still broken with C++11?","Issaquah","|Complete|"
+"`2257 <https://wg21.link/lwg2257>`__","Simplify container requirements with the new algorithms","Issaquah","|Complete|"
+"`2268 <https://wg21.link/lwg2268>`__","Setting a default argument in the declaration of a member function assign of std::basic_string","Issaquah","|Complete|"
+"`2271 <https://wg21.link/lwg2271>`__","regex_traits::lookup_classname specification unclear","Issaquah","|Complete|"
+"`2272 <https://wg21.link/lwg2272>`__","quoted should use char_traits::eq for character comparison","Issaquah","|Complete|"
+"`2278 <https://wg21.link/lwg2278>`__","User-defined literals for Standard Library types","Issaquah","|Complete|"
+"`2280 <https://wg21.link/lwg2280>`__","begin / end for arrays should be constexpr and noexcept","Issaquah","|Complete|"
+"`2285 <https://wg21.link/lwg2285>`__","make_reverse_iterator","Issaquah","|Complete|"
+"`2299 <https://wg21.link/lwg2299>`__","Effects of inaccessible ``key_compare::is_transparent``\  type are not clear","Issaquah","|Complete|"
+"`1450 <https://wg21.link/lwg1450>`__","Contradiction in regex_constants","Issaquah","|Complete|"
+"`2003 <https://wg21.link/lwg2003>`__","String exception inconsistency in erase.","Issaquah","|Complete|"
+"`2112 <https://wg21.link/lwg2112>`__","User-defined classes that cannot be derived from","Issaquah","|Complete|"
+"`2132 <https://wg21.link/lwg2132>`__","std::function ambiguity","Issaquah","|Complete|"
+"`2182 <https://wg21.link/lwg2182>`__","``Container::[const_]reference`` types are misleadingly specified","Issaquah","|Complete|"
+"`2188 <https://wg21.link/lwg2188>`__","Reverse iterator does not fully support targets that overload operator&","Issaquah","|Complete|"
+"`2193 <https://wg21.link/lwg2193>`__","Default constructors for standard library containers are explicit","Issaquah","|Complete|"
+"`2205 <https://wg21.link/lwg2205>`__","Problematic postconditions of regex_match and regex_search","Issaquah","|Complete|"
+"`2213 <https://wg21.link/lwg2213>`__","Return value of std::regex_replace","Issaquah","|Complete|"
+"`2258 <https://wg21.link/lwg2258>`__","a.erase(q1, q2) unable to directly return q2","Issaquah","|Complete|"
+"`2263 <https://wg21.link/lwg2263>`__","Comparing iterators and allocator pointers with different const-character","Issaquah","|Complete|"
+"`2293 <https://wg21.link/lwg2293>`__","Wrong facet used by num_put::do_put","Issaquah","|Complete|"
+"`2301 <https://wg21.link/lwg2301>`__","Why is std::tie not constexpr?","Issaquah","|Complete|"
+"`2304 <https://wg21.link/lwg2304>`__","Complexity of count in unordered associative containers","Issaquah","|Complete|"
+"`2306 <https://wg21.link/lwg2306>`__","match_results::reference should be value_type&, not const value_type&","Issaquah","|Complete|"
+"`2308 <https://wg21.link/lwg2308>`__","Clarify container destructor requirements w.r.t. std::array","Issaquah","|Complete|"
+"`2313 <https://wg21.link/lwg2313>`__","tuple_size should always derive from integral_constant<size_t, N>","Issaquah","|Complete|"
+"`2314 <https://wg21.link/lwg2314>`__","apply() should return decltype(auto) and use decay_t before tuple_size","Issaquah","|Complete|"
+"`2315 <https://wg21.link/lwg2315>`__","weak_ptr should be movable","Issaquah","|Complete|"
+"`2316 <https://wg21.link/lwg2316>`__","weak_ptr::lock() should be atomic","Issaquah","|Complete|"
+"`2317 <https://wg21.link/lwg2317>`__","The type property queries should be UnaryTypeTraits returning size_t","Issaquah","|Complete|"
+"`2320 <https://wg21.link/lwg2320>`__","select_on_container_copy_construction() takes allocators, not containers","Issaquah","|Complete|"
+"`2322 <https://wg21.link/lwg2322>`__","Associative(initializer_list, stuff) constructors are underspecified","Issaquah","|Complete|"
+"`2323 <https://wg21.link/lwg2323>`__","vector::resize(n, t)'s specification should be simplified","Issaquah","|Complete|"
+"`2324 <https://wg21.link/lwg2324>`__","Insert iterator constructors should use addressof()","Issaquah","|Complete|"
+"`2329 <https://wg21.link/lwg2329>`__","regex_match()/regex_search() with match_results should forbid temporary strings","Issaquah","|Complete|"
+"`2330 <https://wg21.link/lwg2330>`__","regex(""meow"", regex::icase) is technically forbidden but should be permitted","Issaquah","|Complete|"
+"`2332 <https://wg21.link/lwg2332>`__","regex_iterator/regex_token_iterator should forbid temporary regexes","Issaquah","|Complete|"
+"`2339 <https://wg21.link/lwg2339>`__","Wording issue in nth_element","Issaquah","|Complete|"
+"`2341 <https://wg21.link/lwg2341>`__","Inconsistency between basic_ostream::seekp(pos) and basic_ostream::seekp(off, dir)","Issaquah","|Complete|"
+"`2344 <https://wg21.link/lwg2344>`__","quoted()'s interaction with padding is unclear","Issaquah","|Complete|"
+"`2346 <https://wg21.link/lwg2346>`__","integral_constant's member functions should be marked noexcept","Issaquah","|Complete|"
+"`2350 <https://wg21.link/lwg2350>`__","min, max, and minmax should be constexpr","Issaquah","|Complete|"
+"`2356 <https://wg21.link/lwg2356>`__","Stability of erasure in unordered associative containers","Issaquah","|Complete|"
+"`2357 <https://wg21.link/lwg2357>`__","Remaining ""Assignable"" requirement","Issaquah","|Complete|"
+"`2359 <https://wg21.link/lwg2359>`__","How does regex_constants::nosubs affect basic_regex::mark_count()?","Issaquah","|Complete|"
+"`2360 <https://wg21.link/lwg2360>`__","``reverse_iterator::operator*()``\  is unimplementable","Issaquah","|Complete|"
+"`2104 <https://wg21.link/lwg2104>`__","unique_lock move-assignment should not be noexcept","Issaquah","|Complete|"
+"`2186 <https://wg21.link/lwg2186>`__","Incomplete action on async/launch::deferred","Issaquah","|Complete|"
+"`2075 <https://wg21.link/lwg2075>`__","Progress guarantees, lock-free property, and scheduling assumptions","Issaquah","|Complete|"
+"`2288 <https://wg21.link/lwg2288>`__","Inconsistent requirements for shared mutexes","Issaquah","|Complete|"
diff --git a/docs/Status/Cxx14Papers.csv b/docs/Status/Cxx14Papers.csv
new file mode 100644
index 0000000..0e5ba7f
--- /dev/null
+++ b/docs/Status/Cxx14Papers.csv
@@ -0,0 +1,32 @@
+"Paper #","Group","Paper Name","Meeting","Status","First released version"
+"`3346 <https://wg21.link/n3346>`__","LWG","Terminology for Container Element Requirements - Rev 1","Kona","|Complete|","3.4"
+"","","","","",""
+"`3421 <https://wg21.link/n3421>`__","LWG","Making Operator Functors greater<>","Portland","|Complete|","3.4"
+"`3462 <https://wg21.link/n3462>`__","LWG","std::result_of and SFINAE","Portland","|Complete|","3.4"
+"`3469 <https://wg21.link/n3469>`__","LWG","Constexpr Library Additions: chrono, v3","Portland","|Complete|","3.4"
+"`3470 <https://wg21.link/n3470>`__","LWG","Constexpr Library Additions: containers, v2","Portland","|Complete|","3.4"
+"`3471 <https://wg21.link/n3471>`__","LWG","Constexpr Library Additions: utilities, v3","Portland","|Complete|","3.4"
+"`3302 <https://wg21.link/n3302>`__","LWG","Constexpr Library Additions: complex, v2","Portland","|Complete|","3.4"
+"","","","","",""
+"`3545 <https://wg21.link/n3545>`__","LWG","An Incremental Improvement to integral_constant","Bristol","|Complete|","3.4"
+"`3644 <https://wg21.link/n3644>`__","LWG","Null Forward Iterators","Bristol","|Complete|","3.4"
+"`3668 <https://wg21.link/n3668>`__","LWG","std::exchange()","Bristol","|Complete|","3.4"
+"`3658 <https://wg21.link/n3658>`__","LWG","Compile-time integer sequences","Bristol","|Complete|","3.4"
+"`3670 <https://wg21.link/n3670>`__","LWG","Addressing Tuples by Type","Bristol","|Complete|","3.4"
+"`3671 <https://wg21.link/n3671>`__","LWG","Making non-modifying sequence operations more robust","Bristol","|Complete|","3.4"
+"`3656 <https://wg21.link/n3656>`__","LWG","make_unique","Bristol","|Complete|","3.4"
+"`3654 <https://wg21.link/n3654>`__","LWG","Quoted Strings","Bristol","|Complete|","3.4"
+"`3642 <https://wg21.link/n3642>`__","LWG","User-defined Literals","Bristol","|Complete|","3.4"
+"`3655 <https://wg21.link/n3655>`__","LWG","TransformationTraits Redux (excluding part 4)","Bristol","|Complete|","3.4"
+"`3657 <https://wg21.link/n3657>`__","LWG","Adding heterogeneous comparison lookup to associative containers","Bristol","|Complete|","3.4"
+"`3672 <https://wg21.link/n3672>`__","LWG","A proposal to add a utility class to represent optional objects","Bristol","*Removed from Draft Standard*","n/a"
+"`3669 <https://wg21.link/n3669>`__","LWG","Fixing constexpr member functions without const","Bristol","|Complete|","3.4"
+"`3662 <https://wg21.link/n3662>`__","LWG","C++ Dynamic Arrays (dynarray)","Bristol","*Removed from Draft Standard*","n/a"
+"`3659 <https://wg21.link/n3659>`__","SG1","Shared Locking in C++","Bristol","|Complete|","3.4"
+"","","","","",""
+"`3779 <https://wg21.link/n3779>`__","LWG","User-defined Literals for std::complex","Chicago","|Complete|","3.4"
+"`3789 <https://wg21.link/n3789>`__","LWG","Constexpr Library Additions: functional","Chicago","|Complete|","3.4"
+"","","","","",""
+"`3924 <https://wg21.link/n3924>`__","LWG","Discouraging rand() in C++14","Issaquah","|Complete|","3.5"
+"`3887 <https://wg21.link/n3887>`__","LWG","Consistent Metafunction Aliases","Issaquah","|Complete|","3.5"
+"`3891 <https://wg21.link/n3891>`__","SG1","A proposal to rename shared_mutex to shared_timed_mutex","Issaquah","|Complete|","3.5"
diff --git a/docs/Status/Cxx17.rst b/docs/Status/Cxx17.rst
new file mode 100644
index 0000000..9076b9c
--- /dev/null
+++ b/docs/Status/Cxx17.rst
@@ -0,0 +1,57 @@
+.. _cxx17-status:

+

+================================

+libc++ C++17 Status

+================================

+

+.. include:: ../Helpers/Styles.rst

+

+.. contents::

+   :local:

+

+

+Overview

+================================

+

+In November 2014, the C++ standard committee created a draft for the next version of the C++ standard, initially known as "C++1z".

+In February 2017, the C++ standard committee approved this draft, and sent it to ISO for approval as C++17.

+

+This page shows the status of libc++; the status of clang's support of the language features is `here <https://clang.llvm.org/cxx_status.html#cxx17>`__.

+

+.. attention:: Features in unreleased drafts of the standard are subject to change.

+

+The groups that have contributed papers:

+

+-  CWG - Core Language Working group

+-  LWG - Library working group

+-  SG1 - Study group #1 (Concurrency working group)

+

+.. note:: "Nothing to do" means that no library changes were needed to implement this change.

+

+.. _paper-status-cxx17:

+

+Paper Status

+====================================

+

+.. csv-table::

+   :file: Cxx17Papers.csv

+   :header-rows: 1

+   :widths: auto

+

+.. note::

+

+   .. [#note-P0433] P0433: So far, only the ``<string>``, sequence containers, container adaptors and ``<regex>`` portions of P0433 have been implemented.

+   .. [#note-P0607] P0607: The parts of P0607 that are not done are the ``<regex>`` bits.

+

+

+.. _issues-status-cxx17:

+

+Library Working Group Issues Status

+====================================

+

+.. csv-table::

+   :file: Cxx17Issues.csv

+   :header-rows: 1

+   :widths: auto

+

+Last Updated: 17-Nov-2020

diff --git a/docs/Status/Cxx17Issues.csv b/docs/Status/Cxx17Issues.csv
new file mode 100644
index 0000000..090e12f
--- /dev/null
+++ b/docs/Status/Cxx17Issues.csv
@@ -0,0 +1,318 @@
+"Issue #","Issue Name","Meeting","Status","First released version"
+"`2016 <https://wg21.link/LWG2016>`__","Allocators must be no-throw swappable","Urbana","|Complete|",""
+"`2118 <https://wg21.link/LWG2376>`__","``unique_ptr``\  for array does not support cv qualification conversion of actual argument","Urbana","|Complete|",""
+"`2170 <https://wg21.link/LWG2170>`__","Aggregates cannot be ``DefaultConstructible``\ ","Urbana","|Complete|",""
+"`2308 <https://wg21.link/LWG2308>`__","Clarify container destructor requirements w.r.t. ``std::array``\ ","Urbana","|Complete|",""
+"`2340 <https://wg21.link/LWG2340>`__","Replacement allocation functions declared as inline","Urbana","|Complete|",""
+"`2354 <https://wg21.link/LWG2354>`__","Unnecessary copying when inserting into maps with braced-init syntax","Urbana","|Complete|",""
+"`2377 <https://wg21.link/LWG2377>`__","``std::align``\  requirements overly strict","Urbana","|Complete|",""
+"`2396 <https://wg21.link/LWG2396>`__","``underlying_type``\  doesn't say what to do for an incomplete enumeration type","Urbana","|Complete|",""
+"`2399 <https://wg21.link/LWG2399>`__","``shared_ptr``\ 's constructor from ``unique_ptr``\  should be constrained","Urbana","|Complete|",""
+"`2400 <https://wg21.link/LWG2400>`__","``shared_ptr``\ 's ``get_deleter()``\  should use ``addressof()``\ ","Urbana","|Complete|",""
+"`2401 <https://wg21.link/LWG2401>`__","``std::function``\  needs more noexcept","Urbana","|Complete|",""
+"`2404 <https://wg21.link/LWG2404>`__","``mismatch()``\ 's complexity needs to be updated","Urbana","|Complete|",""
+"`2408 <https://wg21.link/LWG2408>`__","SFINAE-friendly ``common_type``\  / ``iterator_traits``\  is missing in C++14","Urbana","|Complete|",""
+"","","","",""
+"`2106 <https://wg21.link/LWG2106>`__","``move_iterator``\  wrapping iterators returning prvalues","Urbana","|Complete|",""
+"`2129 <https://wg21.link/LWG2129>`__","User specializations of ``std::initializer_list``\ ","Urbana","|Complete|",""
+"`2212 <https://wg21.link/LWG2212>`__","``tuple_size``\  for ``const pair``\  request <tuple> header","Urbana","|Complete|",""
+"`2217 <https://wg21.link/LWG2217>`__","``operator==(sub_match, string)``\  slices on embedded '\0's","Urbana","|Complete|",""
+"`2230 <https://wg21.link/LWG2230>`__","""see below"" for ``initializer_list``\  constructors of unordered containers","Urbana","|Complete|",""
+"`2233 <https://wg21.link/LWG2233>`__","``bad_function_call::what()``\  unhelpful","Urbana","|Complete|",""
+"`2266 <https://wg21.link/LWG2266>`__","``vector``\  and ``deque``\  have incorrect insert requirements","Urbana","|Complete|",""
+"`2325 <https://wg21.link/LWG2325>`__","``minmax_element()``\ 's behavior differing from ``max_element()``\ 's should be noted","Urbana","|Complete|",""
+"`2361 <https://wg21.link/LWG2361>`__","Apply 2299 resolution throughout library","Urbana","|Complete|",""
+"`2365 <https://wg21.link/LWG2365>`__","Missing noexcept in ``shared_ptr::shared_ptr(nullptr_t)``\ ","Urbana","|Complete|",""
+"`2376 <https://wg21.link/LWG2376>`__","``bad_weak_ptr::what()``\  overspecified","Urbana","|Complete|",""
+"`2387 <https://wg21.link/LWG2387>`__","More nested types that must be accessible and unambiguous","Urbana","|Complete|",""
+"","","","",""
+"`2059 <https://wg21.link/LWG2059>`__","C++0x ambiguity problem with map::erase","Lenexa","|Complete|",""
+"`2063 <https://wg21.link/LWG2063>`__","Contradictory requirements for string move assignment","Lenexa","|Complete|",""
+"`2076 <https://wg21.link/LWG2076>`__","Bad CopyConstructible requirement in set constructors","Lenexa","|Complete|",""
+"`2160 <https://wg21.link/LWG2160>`__","Unintended destruction ordering-specification of resize","Lenexa","|Complete|",""
+"`2168 <https://wg21.link/LWG2168>`__","Inconsistent specification of uniform_real_distribution constructor","Lenexa","|Complete|",""
+"`2239 <https://wg21.link/LWG2239>`__","min/max/minmax requirements","Lenexa","|Complete|",""
+"`2364 <https://wg21.link/LWG2364>`__","deque and vector pop_back don't specify iterator invalidation requirements","Lenexa","|Complete|",""
+"`2369 <https://wg21.link/LWG2369>`__","constexpr max(initializer_list) vs max_element","Lenexa","|Complete|",""
+"`2378 <https://wg21.link/LWG2378>`__","Behaviour of standard exception types","Lenexa","|Complete|",""
+"`2403 <https://wg21.link/LWG2403>`__","stof() should call strtof() and wcstof()","Lenexa","|Complete|",""
+"`2406 <https://wg21.link/LWG2406>`__","negative_binomial_distribution should reject p == 1","Lenexa","|Complete|",""
+"`2407 <https://wg21.link/LWG2407>`__","packaged_task(allocator_arg_t, const Allocator&, F&&) should neither be constrained nor explicit","Lenexa","|Complete|",""
+"`2411 <https://wg21.link/LWG2411>`__","shared_ptr is only contextually convertible to bool","Lenexa","|Complete|",""
+"`2415 <https://wg21.link/LWG2415>`__","Inconsistency between unique_ptr and shared_ptr","Lenexa","|Complete|",""
+"`2420 <https://wg21.link/LWG2420>`__","function<void(ArgTypes...)> does not discard the return value of the target object","Lenexa","|Complete|",""
+"`2425 <https://wg21.link/LWG2425>`__","``operator delete(void*, size_t)``\  doesn't invalidate pointers sufficiently","Lenexa","|Complete|",""
+"`2427 <https://wg21.link/LWG2427>`__","Container adaptors as sequence containers, redux","Lenexa","|Complete|",""
+"`2428 <https://wg21.link/LWG2428>`__","""External declaration"" used without being defined","Lenexa","|Complete|",""
+"`2433 <https://wg21.link/LWG2433>`__","``uninitialized_copy()``\ /etc. should tolerate overloaded operator&","Lenexa","|Complete|",""
+"`2434 <https://wg21.link/LWG2434>`__","``shared_ptr::use_count()``\  is efficient","Lenexa","|Complete|",""
+"`2437 <https://wg21.link/LWG2437>`__","``iterator_traits::reference``\  can and can't be void","Lenexa","|Complete|",""
+"`2438 <https://wg21.link/LWG2438>`__","``std::iterator``\  inheritance shouldn't be mandated","Lenexa","|Complete|",""
+"`2439 <https://wg21.link/LWG2439>`__","``unique_copy()``\  sometimes can't fall back to reading its output","Lenexa","|Complete|",""
+"`2440 <https://wg21.link/LWG2440>`__","``seed_seq::size()``\  should be noexcept","Lenexa","|Complete|",""
+"`2442 <https://wg21.link/LWG2442>`__","``call_once()``\  shouldn't DECAY_COPY()","Lenexa","|Complete|",""
+"`2448 <https://wg21.link/LWG2448>`__","Non-normative Container destructor specification","Lenexa","|Complete|",""
+"`2454 <https://wg21.link/LWG2454>`__","Add ``raw_storage_iterator::base()``\  member","Lenexa","|Complete|",""
+"`2455 <https://wg21.link/LWG2455>`__","Allocator default construction should be allowed to throw","Lenexa","|Complete|",""
+"`2458 <https://wg21.link/LWG2458>`__","N3778 and new library deallocation signatures","Lenexa","|Complete|",""
+"`2459 <https://wg21.link/LWG2459>`__","``std::polar``\  should require a non-negative rho","Lenexa","|Complete|",""
+"`2464 <https://wg21.link/LWG2464>`__","``try_emplace``\  and ``insert_or_assign``\  misspecified","Lenexa","|Complete|",""
+"`2467 <https://wg21.link/LWG2467>`__","``is_always_equal``\  has slightly inconsistent default","Lenexa","|Complete|",""
+"`2470 <https://wg21.link/LWG2470>`__","Allocator's destroy function should be allowed to fail to instantiate","Lenexa","|Complete|",""
+"`2482 <https://wg21.link/LWG2482>`__","[c.strings] Table 73 mentions nonexistent functions","Lenexa","|Complete|",""
+"`2488 <https://wg21.link/LWG2488>`__","Placeholders should be allowed and encouraged to be constexpr","Lenexa","|Complete|",""
+"","","","",""
+"`1169 <https://wg21.link/LWG1169>`__","``num_get``\  not fully compatible with ``strto*``\ ","Kona","|Complete|",""
+"`2072 <https://wg21.link/LWG2072>`__","Unclear wording about capacity of temporary buffers","Kona","|Complete|",""
+"`2101 <https://wg21.link/LWG2101>`__","Some transformation types can produce impossible types","Kona","|Complete|",""
+"`2111 <https://wg21.link/LWG2111>`__","Which ``unexpected``\ &#47;``terminate``\  handler is called from the exception handling runtime?","Kona","|Complete|",""
+"`2119 <https://wg21.link/LWG2119>`__","Missing ``hash``\  specializations for extended integer types","Kona","|Complete|",""
+"`2127 <https://wg21.link/LWG2127>`__","Move-construction with ``raw_storage_iterator``\ ","Kona","|Complete|",""
+"`2133 <https://wg21.link/LWG2133>`__","Attitude to overloaded comma for iterators","Kona","|Complete|",""
+"`2156 <https://wg21.link/LWG2156>`__","Unordered containers' ``reserve(n)``\  reserves for ``n-1``\  elements","Kona","|Complete|",""
+"`2218 <https://wg21.link/LWG2218>`__","Unclear how containers use ``allocator_traits::construct()``\ ","Kona","|Complete|",""
+"`2219 <https://wg21.link/LWG2219>`__","``*INVOKE*``\ -ing a pointer to member with a ``reference_wrapper``\  as the object expression","Kona","|Complete|",""
+"`2224 <https://wg21.link/LWG2224>`__","Ambiguous status of access to non-live objects","Kona","|Complete|",""
+"`2234 <https://wg21.link/LWG2234>`__","``assert()``\  should allow usage in constant expressions","Kona","|Complete|",""
+"`2244 <https://wg21.link/LWG2244>`__","Issue on ``basic_istream::seekg``\ ","Kona","|Complete|",""
+"`2250 <https://wg21.link/LWG2250>`__","Follow-up On Library Issue 2207","Kona","|Complete|",""
+"`2259 <https://wg21.link/LWG2259>`__","Issues in 17.6.5.5 rules for member functions","Kona","|Complete|",""
+"`2273 <https://wg21.link/LWG2273>`__","``regex_match``\  ambiguity","Kona","|Complete|",""
+"`2336 <https://wg21.link/LWG2336>`__","``is_trivially_constructible``\ /``is_trivially_assignable``\  traits are always false","Kona","|Complete|",""
+"`2353 <https://wg21.link/LWG2353>`__","``std::next``\  is over-constrained","Kona","|Complete|",""
+"`2367 <https://wg21.link/LWG2367>`__","``pair``\  and ``tuple``\  are not correctly implemented for ``is_constructible``\  with no args","Kona","|Complete|",""
+"`2380 <https://wg21.link/LWG2380>`__","May ``<cstdlib>``\  provide ``long ::abs(long)``\  and ``long long ::abs(long long)``\ ?","Kona","|Complete|",""
+"`2384 <https://wg21.link/LWG2384>`__","Allocator's ``deallocate``\  function needs better specification","Kona","|Complete|",""
+"`2385 <https://wg21.link/LWG2385>`__","``function::assign``\  allocator argument doesn't make sense","Kona","|Complete|",""
+"`2435 <https://wg21.link/LWG2435>`__","``reference_wrapper::operator()``\ 's Remark should be deleted","Kona","|Complete|",""
+"`2447 <https://wg21.link/LWG2447>`__","Allocators and ``volatile``\ -qualified value types","Kona","|Complete|",""
+"`2462 <https://wg21.link/LWG2462>`__","``std::ios_base::failure``\  is overspecified","Kona","|Complete|",""
+"`2466 <https://wg21.link/LWG2466>`__","``allocator_traits::max_size()``\  default behavior is incorrect","Kona","|Complete|",""
+"`2469 <https://wg21.link/LWG2469>`__","Wrong specification of Requires clause of ``operator[]``\  for ``map``\  and ``unordered_map``\ ","Kona","|Complete|",""
+"`2473 <https://wg21.link/LWG2473>`__","``basic_filebuf``\ 's relation to C ``FILE``\  semantics","Kona","|Complete|",""
+"`2476 <https://wg21.link/LWG2476>`__","``scoped_allocator_adaptor``\  is not assignable","Kona","|Complete|",""
+"`2477 <https://wg21.link/LWG2477>`__","Inconsistency of wordings in ``std::vector::erase()``\  and ``std::deque::erase()``\ ","Kona","|Complete|",""
+"`2483 <https://wg21.link/LWG2483>`__","``throw_with_nested()``\  should use ``is_final``\ ","Kona","|Complete|",""
+"`2484 <https://wg21.link/LWG2484>`__","``rethrow_if_nested()``\  is doubly unimplementable","Kona","|Complete|",""
+"`2485 <https://wg21.link/LWG2485>`__","``get()``\  should be overloaded for ``const tuple&&``\ ","Kona","|Complete|",""
+"`2486 <https://wg21.link/LWG2486>`__","``mem_fn()``\  should be required to use perfect forwarding","Kona","|Complete|",""
+"`2487 <https://wg21.link/LWG2487>`__","``bind()``\  should be ``const``\ -overloaded, not *cv*-overloaded","Kona","|Complete|",""
+"`2489 <https://wg21.link/LWG2489>`__","``mem_fn()``\  should be ``noexcept``\ ","Kona","|Complete|",""
+"`2492 <https://wg21.link/LWG2492>`__","Clarify requirements for ``comp``\ ","Kona","|Complete|",""
+"`2495 <https://wg21.link/LWG2495>`__","There is no such thing as an Exception Safety element","Kona","|Complete|",""
+"","","","",""
+"`2192 <https://wg21.link/LWG2192>`__","Validity and return type of ``std::abs(0u)``\  is unclear","Jacksonville","|Complete|",""
+"`2276 <https://wg21.link/LWG2276>`__","Missing requirement on ``std::promise::set_exception``\ ","Jacksonville","|Complete|",""
+"`2296 <https://wg21.link/LWG2296>`__","``std::addressof``\  should be ``constexpr``\ ","Jacksonville","|Complete|",""
+"`2450 <https://wg21.link/LWG2450>`__","``(greater|less|greater_equal|less_equal)<void>``\  do not yield a total order for pointers","Jacksonville","|Complete|",""
+"`2520 <https://wg21.link/LWG2520>`__","N4089 broke initializing ``unique_ptr<T[]>``\  from a ``nullptr``\ ","Jacksonville","|Complete|",""
+"`2522 <https://wg21.link/LWG2522>`__","[fund.ts.v2] Contradiction in ``set_default_resource``\  specification","Jacksonville","|Complete|",""
+"`2523 <https://wg21.link/LWG2523>`__","``std::promise``\  synopsis shows two ``set_value_at_thread_exit()``\ 's for no apparent reason","Jacksonville","|Complete|",""
+"`2537 <https://wg21.link/LWG2537>`__","Constructors for ``priority_queue``\  taking allocators should call ``make_heap``\ ","Jacksonville","|Complete|",""
+"`2539 <https://wg21.link/LWG2539>`__","[fund.ts.v2] ``invocation_trait``\  definition definition doesn't work for surrogate call functions","Jacksonville","",""
+"`2545 <https://wg21.link/LWG2545>`__","Simplify wording for ``bind``\  without explicitly specified return type","Jacksonville","|Complete|",""
+"`2557 <https://wg21.link/LWG2557>`__","Logical operator traits are broken in the zero-argument case","Jacksonville","|Complete|",""
+"`2558 <https://wg21.link/LWG2558>`__","[fund.ts.v2] Logical operator traits are broken in the zero-argument case","Jacksonville","|Complete|",""
+"`2559 <https://wg21.link/LWG2559>`__","Error in LWG 2234's resolution","Jacksonville","|Complete|",""
+"`2560 <https://wg21.link/LWG2560>`__","``is_constructible``\  underspecified when applied to a function type","Jacksonville","Broken in 3.6; See r261653.",""
+"`2565 <https://wg21.link/LWG2565>`__","``std::function``\ 's move constructor should guarantee nothrow for ``reference_wrapper``\ s and function pointers","Jacksonville","|Complete|",""
+"`2566 <https://wg21.link/LWG2566>`__","Requirements on the first template parameter of container adaptors","Jacksonville","|Complete|",""
+"`2571 <https://wg21.link/LWG2571>`__","|sect|\ [map.modifiers]/2 imposes nonsensical requirement on ``insert(InputIterator, InputIterator)``\ ","Jacksonville","|Complete|",""
+"`2572 <https://wg21.link/LWG2572>`__","The remarks for ``shared_ptr::operator*``\  should apply to *cv*-qualified ``void``\  as well","Jacksonville","|Complete|",""
+"`2574 <https://wg21.link/LWG2574>`__","[fund.ts.v2] ``std::experimental::function::operator=(F&&)``\  should be constrained","Jacksonville","|Complete|",""
+"`2575 <https://wg21.link/LWG2575>`__","[fund.ts.v2] ``experimental::function::assign``\  should be removed","Jacksonville","",""
+"`2576 <https://wg21.link/LWG2576>`__","``istream_iterator``\  and ``ostream_iterator``\  should use ``std::addressof``\ ","Jacksonville","|Complete|",""
+"`2577 <https://wg21.link/LWG2577>`__","``{shared,unique}_lock``\  should use ``std::addressof``\ ","Jacksonville","|Complete|",""
+"`2579 <https://wg21.link/LWG2579>`__","Inconsistency wrt Allocators in ``basic_string``\  assignment vs. ``basic_string::assign``\ ","Jacksonville","|Complete|",""
+"`2581 <https://wg21.link/LWG2581>`__","Specialization of ``<type_traits>``\  variable templates should be prohibited","Jacksonville","|Complete|",""
+"`2582 <https://wg21.link/LWG2582>`__","|sect|\ [res.on.functions]/2's prohibition against incomplete types shouldn't apply to type traits","Jacksonville","|Complete|",""
+"`2583 <https://wg21.link/LWG2583>`__","There is no way to supply an allocator for ``basic_string(str, pos)``\ ","Jacksonville","|Complete|",""
+"`2585 <https://wg21.link/LWG2585>`__","``forward_list::resize(size_type, const value_type&)``\  effects incorrect","Jacksonville","|Complete|",""
+"`2586 <https://wg21.link/LWG2586>`__","Wrong value category used in ``scoped_allocator_adaptor::construct()``\ ","Jacksonville","|Complete|",""
+"`2590 <https://wg21.link/LWG2590>`__","Aggregate initialization for ``std::array``\ ","Jacksonville","|Complete|",""
+"","","","",""
+"`2181 <https://wg21.link/LWG2181>`__","Exceptions from seed sequence operations","Oulu","|Complete|",""
+"`2309 <https://wg21.link/LWG2309>`__","mutex::lock() should not throw device_or_resource_busy","Oulu","|Complete|",""
+"`2310 <https://wg21.link/LWG2310>`__","Public exposition only member in std::array","Oulu","|Complete|",""
+"`2312 <https://wg21.link/LWG2312>`__","tuple's constructor constraints need to be phrased more precisely","Oulu","|Complete|",""
+"`2328 <https://wg21.link/LWG2328>`__","Rvalue stream extraction should use perfect forwarding","Oulu","|Complete|",""
+"`2393 <https://wg21.link/LWG2393>`__","std::function's Callable definition is broken","Oulu","|Complete|",""
+"`2422 <https://wg21.link/LWG2422>`__","``std::numeric_limits<T>::is_modulo``\  description: ""most machines"" errata","Oulu","|Complete|",""
+"`2426 <https://wg21.link/LWG2426>`__","Issue about compare_exchange","Oulu","",""
+"`2436 <https://wg21.link/LWG2436>`__","Comparators for associative containers should always be CopyConstructible","Oulu","|Complete|",""
+"`2441 <https://wg21.link/LWG2441>`__","Exact-width atomic typedefs should be provided","Oulu","|Complete|",""
+"`2451 <https://wg21.link/LWG2451>`__","[fund.ts.v2] optional should 'forward' T's implicit conversions","Oulu","|Nothing To Do|",""
+"`2509 <https://wg21.link/LWG2509>`__","[fund.ts.v2] any_cast doesn't work with rvalue reference targets and cannot move with a value target","Oulu","|Complete|",""
+"`2516 <https://wg21.link/LWG2516>`__","[fund.ts.v2] Public ""exposition only"" members in observer_ptr","Oulu","",""
+"`2542 <https://wg21.link/LWG2542>`__","Missing const requirements for associative containers","Oulu","",""
+"`2549 <https://wg21.link/LWG2549>`__","Tuple EXPLICIT constructor templates that take tuple parameters end up taking references to temporaries and will create dangling references","Oulu","|Complete|",""
+"`2550 <https://wg21.link/LWG2550>`__","Wording of unordered container's clear() method complexity","Oulu","|Complete|",""
+"`2551 <https://wg21.link/LWG2551>`__","[fund.ts.v2] ""Exception safety"" cleanup in library fundamentals required","Oulu","|Complete|",""
+"`2555 <https://wg21.link/LWG2555>`__","[fund.ts.v2] No handling for over-aligned types in optional","Oulu","|Complete|",""
+"`2573 <https://wg21.link/LWG2573>`__","[fund.ts.v2] std::hash<std::experimental::shared_ptr> does not work for arrays","Oulu","",""
+"`2596 <https://wg21.link/LWG2596>`__","vector::data() should use addressof","Oulu","|Complete|",""
+"`2667 <https://wg21.link/LWG2667>`__","path::root_directory() description is confusing","Oulu","|Complete|",""
+"`2669 <https://wg21.link/LWG2669>`__","recursive_directory_iterator effects refers to non-existent functions","Oulu","|Complete|",""
+"`2670 <https://wg21.link/LWG2670>`__","system_complete refers to undefined variable 'base'","Oulu","|Complete|",""
+"`2671 <https://wg21.link/LWG2671>`__","Errors in Copy","Oulu","|Complete|",""
+"`2673 <https://wg21.link/LWG2673>`__","status() effects cannot be implemented as specified","Oulu","|Complete|",""
+"`2674 <https://wg21.link/LWG2674>`__","Bidirectional iterator requirement on path::iterator is very expensive","Oulu","|Complete|",""
+"`2683 <https://wg21.link/LWG2683>`__","filesystem::copy() says ""no effects""","Oulu","|Complete|",""
+"`2684 <https://wg21.link/LWG2684>`__","priority_queue lacking comparator typedef","Oulu","|Complete|",""
+"`2685 <https://wg21.link/LWG2685>`__","shared_ptr deleters must not throw on move construction","Oulu","|Complete|",""
+"`2687 <https://wg21.link/LWG2687>`__","{inclusive,exclusive}_scan misspecified","Oulu","",""
+"`2688 <https://wg21.link/LWG2688>`__","clamp misses preconditions and has extraneous condition on result","Oulu","|Complete|",""
+"`2689 <https://wg21.link/LWG2689>`__","Parallel versions of std::copy and std::move shouldn't be in order","Oulu","",""
+"`2698 <https://wg21.link/LWG2698>`__","Effect of assign() on iterators/pointers/references","Oulu","|Complete|",""
+"`2704 <https://wg21.link/LWG2704>`__","recursive_directory_iterator's members should require '``*this`` is dereferenceable'","Oulu","|Complete|",""
+"`2706 <https://wg21.link/LWG2706>`__","Error reporting for recursive_directory_iterator::pop() is under-specified","Oulu","|Complete|",""
+"`2707 <https://wg21.link/LWG2707>`__","path construction and assignment should have ""string_type&&"" overloads","Oulu","|Complete|",""
+"`2709 <https://wg21.link/LWG2709>`__","offsetof is unnecessarily imprecise","Oulu","",""
+"`2710 <https://wg21.link/LWG2710>`__","""Effects: Equivalent to ..."" doesn't count ""Synchronization:"" as determined semantics","Oulu","|Complete|",""
+"`2711 <https://wg21.link/LWG2711>`__","path is convertible from approximately everything under the sun","Oulu","|Complete|",""
+"`2716 <https://wg21.link/LWG2716>`__","Specification of shuffle and sample disallows lvalue URNGs","Oulu","|Complete|",""
+"`2718 <https://wg21.link/LWG2718>`__","Parallelism bug in [algorithms.parallel.exec] p2","Oulu","",""
+"`2719 <https://wg21.link/LWG2719>`__","permissions function should not be noexcept due to narrow contract","Oulu","|Complete|",""
+"`2720 <https://wg21.link/LWG2720>`__","permissions function incorrectly specified for symlinks","Oulu","|Complete|",""
+"`2721 <https://wg21.link/LWG2721>`__","remove_all has incorrect post conditions","Oulu","|Complete|",""
+"`2723 <https://wg21.link/LWG2723>`__","Do directory_iterator and recursive_directory_iterator become the end iterator upon error?","Oulu","|Complete|",""
+"`2724 <https://wg21.link/LWG2724>`__","The protected virtual member functions of memory_resource should be private","Oulu","",""
+"`2725 <https://wg21.link/LWG2725>`__","filesystem::exists(const path&, error_code&) error reporting","Oulu","|Complete|",""
+"`2726 <https://wg21.link/LWG2726>`__","``[recursive_]directory_iterator::increment(error_code&)`` is underspecified","Oulu","|Complete|",""
+"`2727 <https://wg21.link/LWG2727>`__","Parallel algorithms with constexpr specifier","Oulu","",""
+"`2728 <https://wg21.link/LWG2728>`__","status(p).permissions() and symlink_status(p).permissions() are not specified","Oulu","|Complete|",""
+"","","","",""
+"`2062 <https://wg21.link/LWG2062>`__","Effect contradictions w/o no-throw guarantee of std::function swaps","Issaquah","|Complete|",""
+"`2166 <https://wg21.link/LWG2166>`__","Heap property underspecified?","Issaquah","",""
+"`2221 <https://wg21.link/LWG2221>`__","No formatted output operator for nullptr","Issaquah","|Complete|",""
+"`2223 <https://wg21.link/LWG2223>`__","shrink_to_fit effect on iterator validity","Issaquah","|Complete|",""
+"`2261 <https://wg21.link/LWG2261>`__","Are containers required to use their 'pointer' type internally?","Issaquah","",""
+"`2394 <https://wg21.link/LWG2394>`__","locale::name specification unclear - what is implementation-defined?","Issaquah","|Complete|",""
+"`2460 <https://wg21.link/LWG2460>`__","LWG issue 2408 and value categories","Issaquah","|Complete|",""
+"`2468 <https://wg21.link/LWG2468>`__","Self-move-assignment of library types","Issaquah","",""
+"`2475 <https://wg21.link/LWG2475>`__","Allow overwriting of std::basic_string terminator with charT() to allow cleaner interoperation with legacy APIs","Issaquah","|Complete|",""
+"`2503 <https://wg21.link/LWG2503>`__","multiline option should be added to syntax_option_type","Issaquah","|Complete|",""
+"`2510 <https://wg21.link/LWG2510>`__","Tag types should not be DefaultConstructible","Issaquah","|Complete|",""
+"`2514 <https://wg21.link/LWG2514>`__","Type traits must not be final","Issaquah","|Complete|",""
+"`2518 <https://wg21.link/LWG2518>`__","[fund.ts.v2] Non-member swap for propagate_const should call member swap","Issaquah","|Complete|",""
+"`2519 <https://wg21.link/LWG2519>`__","Iterator operator-= has gratuitous undefined behaviour","Issaquah","|Complete|",""
+"`2521 <https://wg21.link/LWG2521>`__","[fund.ts.v2] weak_ptr's converting move constructor should be modified as well for array support","Issaquah","",""
+"`2525 <https://wg21.link/LWG2525>`__","[fund.ts.v2] get_memory_resource should be const and noexcept","Issaquah","",""
+"`2527 <https://wg21.link/LWG2527>`__","[fund.ts.v2] ALLOCATOR_OF for function::operator= has incorrect default","Issaquah","",""
+"`2531 <https://wg21.link/LWG2531>`__","future::get should explicitly state that the shared state is released","Issaquah","",""
+"`2534 <https://wg21.link/LWG2534>`__","Constrain rvalue stream operators","Issaquah","|Complete|",""
+"`2536 <https://wg21.link/LWG2536>`__","What should <complex.h> do?","Issaquah","|Complete|",""
+"`2540 <https://wg21.link/LWG2540>`__","unordered_multimap::insert hint iterator","Issaquah","|Complete|",""
+"`2543 <https://wg21.link/LWG2543>`__","LWG 2148 (hash support for enum types) seems under-specified","Issaquah","|Complete|",""
+"`2544 <https://wg21.link/LWG2544>`__","``istreambuf_iterator(basic_streambuf<charT, traits>* s)``\  effects unclear when s is 0","Issaquah","|Complete|",""
+"`2556 <https://wg21.link/LWG2556>`__","Wide contract for future::share()","Issaquah","|Complete|",""
+"`2562 <https://wg21.link/LWG2562>`__","Consistent total ordering of pointers by comparison functors","Issaquah","",""
+"`2567 <https://wg21.link/LWG2567>`__","Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","|Complete|",""
+"`2568 <https://wg21.link/LWG2568>`__","[fund.ts.v2] Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","",""
+"`2569 <https://wg21.link/LWG2569>`__","conjunction and disjunction requirements are too strict","Issaquah","|Complete|",""
+"`2570 <https://wg21.link/LWG2570>`__","[fund.ts.v2] conjunction and disjunction requirements are too strict","Issaquah","",""
+"`2578 <https://wg21.link/LWG2578>`__","Iterator requirements should reference iterator traits","Issaquah","|Complete|",""
+"`2584 <https://wg21.link/LWG2584>`__","<regex> ECMAScript IdentityEscape is ambiguous","Issaquah","",""
+"`2587 <https://wg21.link/LWG2587>`__","""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","Resolved by 2567",""
+"`2588 <https://wg21.link/LWG2588>`__","[fund.ts.v2] ""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","",""
+"`2589 <https://wg21.link/LWG2589>`__","match_results can't satisfy the requirements of a container","Issaquah","|Complete|",""
+"`2591 <https://wg21.link/LWG2591>`__","std::function's member template target() should not lead to undefined behaviour","Issaquah","|Complete|",""
+"`2598 <https://wg21.link/LWG2598>`__","addressof works on temporaries","Issaquah","|Complete|",""
+"`2664 <https://wg21.link/LWG2664>`__","operator/ (and other append) semantics not useful if argument has root","Issaquah","|Complete|",""
+"`2665 <https://wg21.link/LWG2665>`__","remove_filename() post condition is incorrect","Issaquah","|Complete|",""
+"`2672 <https://wg21.link/LWG2672>`__","Should ``is_empty``\  use error_code in its specification?","Issaquah","|Complete|",""
+"`2678 <https://wg21.link/LWG2678>`__","std::filesystem enum classes overspecified","Issaquah","|Complete|",""
+"`2679 <https://wg21.link/LWG2679>`__","Inconsistent Use of Effects and Equivalent To","Issaquah","|Complete|",""
+"`2680 <https://wg21.link/LWG2680>`__","Add ""Equivalent to"" to filesystem","Issaquah","|Complete|",""
+"`2681 <https://wg21.link/LWG2681>`__","filesystem::copy() cannot copy symlinks","Issaquah","|Complete|",""
+"`2682 <https://wg21.link/LWG2682>`__","filesystem::copy() won't create a symlink to a directory","Issaquah","|Complete|",""
+"`2686 <https://wg21.link/LWG2686>`__","Why is std::hash specialized for error_code, but not error_condition?","Issaquah","|Complete|",""
+"`2694 <https://wg21.link/LWG2694>`__","Application of LWG 436 accidentally deleted definition of ""facet""","Issaquah","|Complete|",""
+"`2696 <https://wg21.link/LWG2696>`__","Interaction between make_shared and enable_shared_from_this is underspecified","Issaquah","|Nothing To Do|",""
+"`2699 <https://wg21.link/LWG2699>`__","Missing restriction in [numeric.requirements]","Issaquah","|Complete|",""
+"`2712 <https://wg21.link/LWG2712>`__","copy_file(from, to, ...) has a number of unspecified error conditions","Issaquah","|Complete|",""
+"`2722 <https://wg21.link/LWG2722>`__","equivalent incorrectly specifies throws clause","Issaquah","|Complete|",""
+"`2729 <https://wg21.link/LWG2729>`__","Missing SFINAE on std::pair::operator=","Issaquah","|Complete|",""
+"`2732 <https://wg21.link/LWG2732>`__","Questionable specification of path::operator/= and path::append","Issaquah","|Complete|",""
+"`2733 <https://wg21.link/LWG2733>`__","[fund.ts.v2] gcd / lcm and bool","Issaquah","|Complete|",""
+"`2735 <https://wg21.link/LWG2735>`__","std::abs(short), std::abs(signed char) and others should return int instead of double in order to be compatible with C++98 and C","Issaquah","|Complete|",""
+"`2736 <https://wg21.link/LWG2736>`__","nullopt_t insufficiently constrained","Issaquah","|Complete|",""
+"`2738 <https://wg21.link/LWG2738>`__","``is_constructible``\  with void types","Issaquah","|Complete|",""
+"`2739 <https://wg21.link/LWG2739>`__","Issue with time_point non-member subtraction with an unsigned duration","Issaquah","|Complete|",""
+"`2740 <https://wg21.link/LWG2740>`__","constexpr optional<T>::operator->","Issaquah","|Complete|",""
+"`2742 <https://wg21.link/LWG2742>`__","Inconsistent string interface taking string_view","Issaquah","|Complete|",""
+"`2744 <https://wg21.link/LWG2744>`__","any's in_place constructors","Issaquah","|Complete|",""
+"`2745 <https://wg21.link/LWG2745>`__","[fund.ts.v2] Implementability of LWG 2451","Issaquah","|Complete|",""
+"`2747 <https://wg21.link/LWG2747>`__","Possibly redundant std::move in [alg.foreach]","Issaquah","|Complete|",""
+"`2748 <https://wg21.link/LWG2748>`__","swappable traits for optionals","Issaquah","|Complete|",""
+"`2749 <https://wg21.link/LWG2749>`__","swappable traits for variants","Issaquah","|Complete|",""
+"`2750 <https://wg21.link/LWG2750>`__","[fund.ts.v2] LWG 2451 conversion constructor constraint","Issaquah","|Nothing To Do|",""
+"`2752 <https://wg21.link/LWG2752>`__","""Throws:"" clauses of async and packaged_task are unimplementable","Issaquah","",""
+"`2755 <https://wg21.link/LWG2755>`__","[string.view.io] uses non-existent basic_string_view::to_string function","Issaquah","|Complete|",""
+"`2756 <https://wg21.link/LWG2756>`__","C++ WP optional<T> should 'forward' T's implicit conversions","Issaquah","|Complete|",""
+"`2758 <https://wg21.link/LWG2758>`__","std::string{}.assign(""ABCDE"", 0, 1) is ambiguous","Issaquah","|Complete|",""
+"`2759 <https://wg21.link/LWG2759>`__","gcd / lcm and bool for the WP","Issaquah","|Complete|",""
+"`2760 <https://wg21.link/LWG2760>`__","non-const basic_string::data should not invalidate iterators","Issaquah","|Complete|",""
+"`2765 <https://wg21.link/LWG2765>`__","Did LWG 1123 go too far?","Issaquah","|Complete|",""
+"`2767 <https://wg21.link/LWG2767>`__","not_fn call_wrapper can form invalid types","Issaquah","|Complete|",""
+"`2769 <https://wg21.link/LWG2769>`__","Redundant const in the return type of any_cast(const any&)","Issaquah","|Complete|",""
+"`2771 <https://wg21.link/LWG2771>`__","Broken Effects of some basic_string::compare functions in terms of basic_string_view","Issaquah","|Complete|",""
+"`2773 <https://wg21.link/LWG2773>`__","Making std::ignore constexpr","Issaquah","|Complete|",""
+"`2777 <https://wg21.link/LWG2777>`__","basic_string_view::copy should use char_traits::copy","Issaquah","|Complete|",""
+"`2778 <https://wg21.link/LWG2778>`__","basic_string_view is missing constexpr","Issaquah","|Complete|",""
+"","","","",""
+"`2260 <https://wg21.link/LWG2260>`__","Missing requirement for Allocator::pointer","Kona","|Complete|",""
+"`2676 <https://wg21.link/LWG2676>`__","Provide filesystem::path overloads for File-based streams","Kona","|Complete|",""
+"`2768 <https://wg21.link/LWG2768>`__","any_cast and move semantics","Kona","|Complete|",""
+"`2769 <https://wg21.link/LWG2769>`__","Redundant const in the return type of any_cast(const any&)","Kona","|Complete|",""
+"`2781 <https://wg21.link/LWG2781>`__","Contradictory requirements for std::function and std::reference_wrapper","Kona","|Complete|",""
+"`2782 <https://wg21.link/LWG2782>`__","scoped_allocator_adaptor constructors must be constrained","Kona","|Complete|",""
+"`2784 <https://wg21.link/LWG2784>`__","Resolution to LWG 2484 is missing ""otherwise, no effects"" and is hard to parse","Kona","|Complete|",""
+"`2785 <https://wg21.link/LWG2785>`__","quoted should work with basic_string_view","Kona","|Complete|",""
+"`2786 <https://wg21.link/LWG2786>`__","Annex C should mention shared_ptr changes for array support","Kona","|Complete|",""
+"`2787 <https://wg21.link/LWG2787>`__","|sect|\ [file_status.cons] doesn't match class definition","Kona","|Complete|",""
+"`2788 <https://wg21.link/LWG2788>`__","basic_string range mutators unintentionally require a default constructible allocator","Kona","|Complete|",""
+"`2789 <https://wg21.link/LWG2789>`__","Equivalence of contained objects","Kona","|Complete|",""
+"`2790 <https://wg21.link/LWG2790>`__","Missing specification of istreambuf_iterator::operator->","Kona","|Complete|",""
+"`2794 <https://wg21.link/LWG2794>`__","Missing requirements for allocator pointers","Kona","|Nothing To Do|",""
+"`2795 <https://wg21.link/LWG2795>`__","|sect|\ [global.functions] provides incorrect example of ADL use","Kona","|Complete|",""
+"`2796 <https://wg21.link/LWG2796>`__","tuple should be a literal type","Kona","|Complete|",""
+"`2801 <https://wg21.link/LWG2801>`__","Default-constructibility of unique_ptr","Kona","|Complete|",""
+"`2802 <https://wg21.link/LWG2802>`__","shared_ptr constructor requirements for a deleter","Kona","|Complete|",""
+"`2804 <https://wg21.link/LWG2804>`__","Unconditional constexpr default constructor for istream_iterator","Kona","|Complete|",""
+"`2806 <https://wg21.link/LWG2806>`__","Base class of bad_optional_access","Kona","|Complete|",""
+"`2807 <https://wg21.link/LWG2807>`__","std::invoke should use ``std::is_nothrow_callable``\ ","Kona","|Complete|",""
+"`2812 <https://wg21.link/LWG2812>`__","Range access is available with <string_view>","Kona","|Complete|",""
+"`2824 <https://wg21.link/LWG2824>`__","list::sort should say that the order of elements is unspecified if an exception is thrown","Kona","|Complete|",""
+"`2826 <https://wg21.link/LWG2826>`__","string_view iterators use old wording","Kona","|Complete|",""
+"`2834 <https://wg21.link/LWG2834>`__","Resolution LWG 2223 is missing wording about end iterators","Kona","|Complete|",""
+"`2835 <https://wg21.link/LWG2835>`__","LWG 2536 seems to misspecify <tgmath.h>","Kona","|Complete|",""
+"`2837 <https://wg21.link/LWG2837>`__","gcd and lcm should support a wider range of input values","Kona","|Complete|",""
+"`2838 <https://wg21.link/LWG2838>`__","is_literal_type specification needs a little cleanup","Kona","|Complete|",""
+"`2842 <https://wg21.link/LWG2842>`__","in_place_t check for optional::optional(U&&) should decay U","Kona","|Complete|",""
+"`2850 <https://wg21.link/LWG2850>`__","std::function move constructor does unnecessary work","Kona","|Complete|",""
+"`2853 <https://wg21.link/LWG2853>`__","Possible inconsistency in specification of erase in [vector.modifiers]","Kona","|Complete|",""
+"`2855 <https://wg21.link/LWG2855>`__","std::throw_with_nested(""string_literal"")","Kona","|Complete|",""
+"`2857 <https://wg21.link/LWG2857>`__","{variant,optional,any}::emplace should return the constructed value","Kona","|Complete|",""
+"`2861 <https://wg21.link/LWG2861>`__","basic_string should require that charT match traits::char_type","Kona","|Complete|",""
+"`2866 <https://wg21.link/LWG2866>`__","Incorrect derived classes constraints","Kona","|Nothing To Do|",""
+"`2868 <https://wg21.link/LWG2868>`__","Missing specification of bad_any_cast::what()","Kona","|Complete|",""
+"`2872 <https://wg21.link/LWG2872>`__","Add definition for direct-non-list-initialization","Kona","|Complete|",""
+"`2873 <https://wg21.link/LWG2873>`__","Add noexcept to several shared_ptr related functions","Kona","|Complete|",""
+"`2874 <https://wg21.link/LWG2874>`__","Constructor ``shared_ptr::shared_ptr(Y*)``\  should be constrained","Kona","|Complete|","13.0"
+"`2875 <https://wg21.link/LWG2875>`__","shared_ptr::shared_ptr(Y\*, D, [|hellip|\ ]) constructors should be constrained","Kona","|Complete|",""
+"`2876 <https://wg21.link/LWG2876>`__","``shared_ptr::shared_ptr(const weak_ptr<Y>&)``\  constructor should be constrained","Kona","",""
+"`2878 <https://wg21.link/LWG2878>`__","Missing DefaultConstructible requirement for istream_iterator default constructor","Kona","|Complete|",""
+"`2890 <https://wg21.link/LWG2890>`__","The definition of 'object state' applies only to class types","Kona","|Complete|",""
+"`2900 <https://wg21.link/LWG2900>`__","The copy and move constructors of optional are not constexpr","Kona","|Complete|",""
+"`2903 <https://wg21.link/LWG2903>`__","The form of initialization for the emplace-constructors is not specified","Kona","|Complete|",""
+"`2904 <https://wg21.link/LWG2904>`__","Make variant move-assignment more exception safe","Kona","|Complete|",""
+"`2905 <https://wg21.link/LWG2905>`__","is_constructible_v<unique_ptr<P, D>, P, D const &> should be false when D is not copy constructible","Kona","|Complete|",""
+"`2908 <https://wg21.link/LWG2908>`__","The less-than operator for shared pointers could do more","Kona","|Complete|",""
+"`2911 <https://wg21.link/LWG2911>`__","An is_aggregate type trait is needed","Kona","|Complete|",""
+"`2921 <https://wg21.link/LWG2921>`__","packaged_task and type-erased allocators","Kona","|Complete|",""
+"`2934 <https://wg21.link/LWG2934>`__","optional<const T> doesn't compare with T","Kona","|Complete|",""
+"","","","",""
+"`2901 <https://wg21.link/LWG2901>`__","Variants cannot properly support allocators","Toronto","|Complete|",""
+"`2955 <https://wg21.link/LWG2955>`__","``to_chars / from_chars``\  depend on ``std::string``\ ","Toronto","Resolved by `P0682R1 <https://wg21.link/P0682R1>`__",""
+"`2956 <https://wg21.link/LWG2956>`__","``filesystem::canonical()``\  still defined in terms of ``absolute(p, base)``\ ","Toronto","|Complete|",""
diff --git a/docs/Status/Cxx17Papers.csv b/docs/Status/Cxx17Papers.csv
new file mode 100644
index 0000000..a015529
--- /dev/null
+++ b/docs/Status/Cxx17Papers.csv
@@ -0,0 +1,113 @@
+"Paper #","Group","Paper Name","Meeting","Status","First released version"
+"`N3911 <https://wg21.link/n3911>`__","LWG","TransformationTrait Alias ``void_t``\ .","Urbana","|Complete|","3.6"
+"`N4089 <https://wg21.link/n4089>`__","LWG","Safe conversions in ``unique_ptr<T[]>``\ .","Urbana","|In Progress|","3.9"
+"`N4169 <https://wg21.link/n4169>`__","LWG","A proposal to add invoke function template","Urbana","|Complete|","3.7"
+"`N4190 <https://wg21.link/n4190>`__","LWG","Removing auto_ptr, random_shuffle(), And Old <functional> Stuff.","Urbana","|In Progress|",""
+"`N4258 <https://wg21.link/n4258>`__","LWG","Cleaning-up noexcept in the Library.","Urbana","|In Progress|","3.7"
+"`N4259 <https://wg21.link/n4259>`__","CWG","Wording for std::uncaught_exceptions","Urbana","|Complete|","3.7"
+"`N4277 <https://wg21.link/n4277>`__","LWG","TriviallyCopyable ``reference_wrapper``\ .","Urbana","|Complete|","3.2"
+"`N4279 <https://wg21.link/n4279>`__","LWG","Improved insertion interface for unique-key maps.","Urbana","|Complete|","3.7"
+"`N4280 <https://wg21.link/n4280>`__","LWG","Non-member size() and more","Urbana","|Complete|","3.6"
+"`N4284 <https://wg21.link/n4284>`__","LWG","Contiguous Iterators.","Urbana","|Complete|","3.6"
+"`N4285 <https://wg21.link/n4285>`__","CWG","Cleanup for exception-specification and throw-expression.","Urbana","|Complete|","4.0"
+"","","","","",""
+"`N4387 <https://wg21.link/n4387>`__","LWG","improving pair and tuple","Lenexa","|Complete|","4.0"
+"`N4389 <https://wg21.link/n4389>`__","LWG","bool_constant","Lenexa","|Complete|","3.7"
+"`N4508 <https://wg21.link/n4508>`__","LWG","shared_mutex for C++17","Lenexa","|Complete|","3.7"
+"`N4366 <https://wg21.link/n4366>`__","LWG","LWG 2228 missing SFINAE rule","Lenexa","|Complete|","3.1"
+"`N4510 <https://wg21.link/n4510>`__","LWG","Minimal incomplete type support for standard containers, revision 4","Lenexa","|Complete|","3.6"
+"","","","","",""
+"`P0004R1 <https://wg21.link/p0004r1>`__","LWG","Remove Deprecated iostreams aliases.","Kona","|Complete|","3.8"
+"`P0006R0 <https://wg21.link/p0006r0>`__","LWG","Adopt Type Traits Variable Templates for C++17.","Kona","|Complete|","3.8"
+"`P0092R1 <https://wg21.link/p0092r1>`__","LWG","Polishing <chrono>","Kona","|Complete|","3.8"
+"`P0007R1 <https://wg21.link/p0007r1>`__","LWG","Constant View: A proposal for a ``std::as_const``\  helper function template.","Kona","|Complete|","3.8"
+"`P0156R0 <https://wg21.link/p0156r0>`__","LWG","Variadic lock_guard(rev 3).","Kona","*Reverted in Kona*","3.9"
+"`P0074R0 <https://wg21.link/p0074r0>`__","LWG","Making ``std::owner_less``\  more flexible","Kona","|Complete|","3.8"
+"`P0013R1 <https://wg21.link/p0013r1>`__","LWG","Logical type traits rev 2","Kona","|Complete|","3.8"
+"","","","","",""
+"`P0024R2 <https://wg21.link/P0024R2>`__","LWG","The Parallelism TS Should be Standardized","Jacksonville","",""
+"`P0226R1 <https://wg21.link/P0226R1>`__","LWG","Mathematical Special Functions for C++17","Jacksonville","",""
+"`P0220R1 <https://wg21.link/P0220R1>`__","LWG","Adopt Library Fundamentals V1 TS Components for C++17","Jacksonville","|In Progress|",""
+"`P0218R1 <https://wg21.link/P0218R1>`__","LWG","Adopt the File System TS for C++17","Jacksonville","|Complete|","7.0"
+"`P0033R1 <https://wg21.link/P0033R1>`__","LWG","Re-enabling shared_from_this","Jacksonville","|Complete|","3.9"
+"`P0005R4 <https://wg21.link/P0005R4>`__","LWG","Adopt not_fn from Library Fundamentals 2 for C++17","Jacksonville","|Complete|","3.9"
+"`P0152R1 <https://wg21.link/P0152R1>`__","LWG","constexpr ``atomic::is_always_lock_free``\ ","Jacksonville","|Complete|","3.9"
+"`P0185R1 <https://wg21.link/P0185R1>`__","LWG","Adding [nothrow-]swappable traits","Jacksonville","|Complete|","3.9"
+"`P0253R1 <https://wg21.link/P0253R1>`__","LWG","Fixing a design mistake in the searchers interface","Jacksonville","|Complete|","3.9"
+"`P0025R0 <https://wg21.link/P0025R0>`__","LWG","An algorithm to ""clamp"" a value between a pair of boundary values","Jacksonville","|Complete|","3.9"
+"`P0154R1 <https://wg21.link/P0154R1>`__","LWG","constexpr std::hardware_{constructive,destructive}_interference_size","Jacksonville","",""
+"`P0030R1 <https://wg21.link/P0030R1>`__","LWG","Proposal to Introduce a 3-Argument Overload to std::hypot","Jacksonville","|Complete|","3.9"
+"`P0031R0 <https://wg21.link/P0031R0>`__","LWG","A Proposal to Add Constexpr Modifiers to reverse_iterator, move_iterator, array and Range Access","Jacksonville","|Complete|","4.0"
+"`P0272R1 <https://wg21.link/P0272R1>`__","LWG","Give ``std::string``\  a non-const ``.data()``\  member function","Jacksonville","|Complete|","3.9"
+"`P0077R2 <https://wg21.link/P0077R2>`__","LWG","``is_callable``\ , the missing INVOKE related trait","Jacksonville","|Complete|","3.9"
+"","","","","",""
+"`p0032r3 <https://wg21.link/p0032r3>`__","LWG","Homogeneous interface for variant, any and optional","Oulu","|Complete|","4.0"
+"`p0040r3 <https://wg21.link/p0040r3>`__","LWG","Extending memory management tools","Oulu","|Complete|","4.0"
+"`p0063r3 <https://wg21.link/p0063r3>`__","LWG","C++17 should refer to C11 instead of C99","Oulu","|Complete|","7.0"
+"`p0067r3 <https://wg21.link/p0067r3>`__","LWG","Elementary string conversions","Oulu","Now `P0067R5 <https://wg21.link/P0067R5>`__","n/a"
+"`p0083r3 <https://wg21.link/p0083r3>`__","LWG","Splicing Maps and Sets","Oulu","|Complete|","8.0"
+"`p0084r2 <https://wg21.link/p0084r2>`__","LWG","Emplace Return Type","Oulu","|Complete|","4.0"
+"`p0088r3 <https://wg21.link/p0088r3>`__","LWG","Variant: a type-safe union for C++17","Oulu","|Complete|","4.0"
+"`p0137r1 <https://wg21.link/p0137r1>`__","CWG","Core Issue 1776: Replacement of class objects containing reference members","Oulu","|Complete|","6.0"
+"`p0163r0 <https://wg21.link/p0163r0>`__","LWG","shared_ptr::weak_type","Oulu","|Complete|","3.9"
+"`p0174r2 <https://wg21.link/p0174r2>`__","LWG","Deprecating Vestigial Library Parts in C++17","Oulu","|Partial|",""
+"`p0175r1 <https://wg21.link/p0175r1>`__","LWG","Synopses for the C library","Oulu","",""
+"`p0180r2 <https://wg21.link/p0180r2>`__","LWG","Reserve a New Library Namespace for Future Standardization","Oulu","|Nothing To Do|","n/a"
+"`p0181r1 <https://wg21.link/p0181r1>`__","LWG","Ordered by Default","Oulu","*Removed in Kona*","n/a"
+"`p0209r2 <https://wg21.link/p0209r2>`__","LWG","make_from_tuple: apply for construction","Oulu","|Complete|","3.9"
+"`p0219r1 <https://wg21.link/p0219r1>`__","LWG","Relative Paths for Filesystem","Oulu","|Complete|","7.0"
+"`p0254r2 <https://wg21.link/p0254r2>`__","LWG","Integrating std::string_view and std::string","Oulu","|Complete|","4.0"
+"`p0258r2 <https://wg21.link/p0258r2>`__","LWG","has_unique_object_representations","Oulu","|Complete|","6.0"
+"`p0295r0 <https://wg21.link/p0295r0>`__","LWG","Adopt Selected Library Fundamentals V2 Components for C++17","Oulu","|Complete|","4.0"
+"`p0302r1 <https://wg21.link/p0302r1>`__","LWG","Removing Allocator Support in std::function","Oulu","|Complete|","4.0"
+"`p0307r2 <https://wg21.link/p0307r2>`__","LWG","Making Optional Greater Equal Again","Oulu","|Complete|","4.0"
+"`p0336r1 <https://wg21.link/p0336r1>`__","LWG","Better Names for Parallel Execution Policies in C++17","Oulu","",""
+"`p0337r0 <https://wg21.link/p0337r0>`__","LWG","Delete ``operator=``\  for polymorphic_allocator","Oulu","|Complete|","3.9"
+"`p0346r1 <https://wg21.link/p0346r1>`__","LWG","A <random> Nomenclature Tweak","Oulu","|Complete|","3.9"
+"`p0358r1 <https://wg21.link/p0358r1>`__","LWG","Fixes for not_fn","Oulu","|Complete|","3.9"
+"`p0371r1 <https://wg21.link/p0371r1>`__","LWG","Temporarily discourage memory_order_consume","Oulu","|Nothing To Do|","n/a"
+"`p0392r0 <https://wg21.link/p0392r0>`__","LWG","Adapting string_view by filesystem paths","Oulu","|Complete|","4.0"
+"`p0393r3 <https://wg21.link/p0393r3>`__","LWG","Making Variant Greater Equal","Oulu","|Complete|","4.0"
+"`P0394r4 <https://wg21.link/P0394r4>`__","LWG","Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling","Oulu","",""
+"","","","","",""
+"`P0003R5 <https://wg21.link/P0003R5>`__","LWG","Removing Deprecated Exception Specifications from C++17","Issaquah","|Complete|","5.0"
+"`P0067R5 <https://wg21.link/P0067R5>`__","LWG","Elementary string conversions, revision 5","Issaquah","|Partial|",""
+"`P0403R1 <https://wg21.link/P0403R1>`__","LWG","Literal suffixes for ``basic_string_view``\ ","Issaquah","|Complete|","4.0"
+"`P0414R2 <https://wg21.link/P0414R2>`__","LWG","Merging shared_ptr changes from Library Fundamentals to C++17","Issaquah","|Complete|","11.0"
+"`P0418R2 <https://wg21.link/P0418R2>`__","LWG","Fail or succeed: there is no atomic lattice","Issaquah","",""
+"`P0426R1 <https://wg21.link/P0426R1>`__","LWG","Constexpr for ``std::char_traits``\ ","Issaquah","|Complete|","4.0"
+"`P0435R1 <https://wg21.link/P0435R1>`__","LWG","Resolving LWG Issues re ``common_type``\ ","Issaquah","|Complete|","4.0"
+"`P0502R0 <https://wg21.link/P0502R0>`__","LWG","Throwing out of a parallel algorithm terminates - but how?","Issaquah","",""
+"`P0503R0 <https://wg21.link/P0503R0>`__","LWG","Correcting library usage of ""literal type""","Issaquah","|Complete|","4.0"
+"`P0504R0 <https://wg21.link/P0504R0>`__","LWG","Revisiting in-place tag types for any/optional/variant","Issaquah","|Complete|","4.0"
+"`P0505R0 <https://wg21.link/P0505R0>`__","LWG","Wording for GB 50 - constexpr for chrono","Issaquah","|Complete|","4.0"
+"`P0508R0 <https://wg21.link/P0508R0>`__","LWG","Wording for GB 58 - structured bindings for node_handles","Issaquah","",""
+"`P0509R1 <https://wg21.link/P0509R1>`__","LWG","Updating ""Restrictions on exception handling""","Issaquah","|Nothing To Do|","n/a"
+"`P0510R0 <https://wg21.link/P0510R0>`__","LWG","Disallowing references, incomplete types, arrays, and empty variants","Issaquah","|Complete|","4.0"
+"`P0513R0 <https://wg21.link/P0513R0>`__","LWG","Poisoning the Hash","Issaquah","|Complete|","5.0"
+"`P0516R0 <https://wg21.link/P0516R0>`__","LWG","Clarify That shared_future's Copy Operations have Wide Contracts","Issaquah","|Complete|","4.0"
+"`P0517R0 <https://wg21.link/P0517R0>`__","LWG","Make future_error Constructible","Issaquah","|Complete|","4.0"
+"`P0521R0 <https://wg21.link/P0521R0>`__","LWG","Proposed Resolution for CA 14 (shared_ptr use_count/unique)","Issaquah","|Nothing To Do|","n/a"
+"","","","","",""
+"`P0156R2 <https://wg21.link/P0156R2>`__","LWG","Variadic Lock guard(rev 5)","Kona","|Complete|","5.0"
+"`P0270R3 <https://wg21.link/P0270R3>`__","CWG","Removing C dependencies from signal handler wording","Kona","",""
+"`P0298R3 <https://wg21.link/P0298R3>`__","CWG","A byte type definition","Kona","|Complete|","5.0"
+"`P0317R1 <https://wg21.link/P0317R1>`__","LWG","Directory Entry Caching for Filesystem","Kona","|Complete|","7.0"
+"`P0430R2 <https://wg21.link/P0430R2>`__","LWG","File system library on non-POSIX-like operating systems","Kona","|Complete|","7.0"
+"`P0433R2 <https://wg21.link/P0433R2>`__","LWG","Toward a resolution of US7 and US14: Integrating template deduction for class templates into the standard library","Kona","|In Progress| [#note-P0433]_","7.0"
+"`P0452R1 <https://wg21.link/P0452R1>`__","LWG","Unifying <numeric> Parallel Algorithms","Kona","",""
+"`P0467R2 <https://wg21.link/P0467R2>`__","LWG","Iterator Concerns for Parallel Algorithms","Kona","",""
+"`P0492R2 <https://wg21.link/P0492R2>`__","LWG","Proposed Resolution of C++17 National Body Comments for Filesystems","Kona","|Complete|","7.0"
+"`P0518R1 <https://wg21.link/P0518R1>`__","LWG","Allowing copies as arguments to function objects given to parallel algorithms in response to CH11","Kona","",""
+"`P0523R1 <https://wg21.link/P0523R1>`__","LWG","Wording for CH 10: Complexity of parallel algorithms","Kona","",""
+"`P0548R1 <https://wg21.link/P0548R1>`__","LWG","common_type and duration","Kona","|Complete|","5.0"
+"`P0558R1 <https://wg21.link/P0558R1>`__","LWG","Resolving atomic<T> named base class inconsistencies","Kona","",""
+"`P0574R1 <https://wg21.link/P0574R1>`__","LWG","Algorithm Complexity Constraints and Parallel Overloads","Kona","",""
+"`P0599R1 <https://wg21.link/P0599R1>`__","LWG","noexcept for hash functions","Kona","|Complete|","5.0"
+"`P0604R0 <https://wg21.link/P0604R0>`__","LWG","Resolving GB 55, US 84, US 85, US 86","Kona","|Complete|",""
+"`P0607R0 <https://wg21.link/P0607R0>`__","LWG","Inline Variables for the Standard Library","Kona","|In Progress| [#note-P0607]_","6.0"
+"`P0618R0 <https://wg21.link/P0618R0>`__","LWG","Deprecating <codecvt>","Kona","",""
+"`P0623R0 <https://wg21.link/P0623R0>`__","LWG","Final C++17 Parallel Algorithms Fixes","Kona","",""
+"","","","","",""
+"`P0682R1 <https://wg21.link/P0682R1>`__","LWG","Repairing elementary string conversions","Toronto","",""
+"`P0739R0 <https://wg21.link/P0739R0>`__","LWG","Some improvements to class template argument deduction integration into the standard library","Toronto","|Complete|","5.0"
diff --git a/docs/Status/Cxx20.rst b/docs/Status/Cxx20.rst
new file mode 100644
index 0000000..69e607c
--- /dev/null
+++ b/docs/Status/Cxx20.rst
@@ -0,0 +1,59 @@
+.. _cxx20-status:

+

+================================

+libc++ C++20 Status

+================================

+

+.. include:: ../Helpers/Styles.rst

+

+.. contents::

+   :local:

+

+

+Overview

+================================

+

+In July 2017, the C++ standard committee created a draft for the next version of the C++ standard, initially known as "C++2a".

+In September 2020, the C++ standard committee approved this draft, and sent it to ISO for approval as C++20.

+

+This page shows the status of libc++; the status of clang's support of the language features is `here <https://clang.llvm.org/cxx_status.html#cxx20>`__.

+

+.. attention:: Features in unreleased drafts of the standard are subject to change.

+

+The groups that have contributed papers:

+

+-  CWG - Core Language Working group

+-  LWG - Library working group

+-  SG1 - Study group #1 (Concurrency working group)

+

+.. note:: "Nothing to do" means that no library changes were needed to implement this change.

+

+.. _paper-status-cxx20:

+

+Paper Status

+====================================

+

+.. csv-table::

+   :file: Cxx20Papers.csv

+   :header-rows: 1

+   :widths: auto

+

+.. note::

+

+   .. [#note-P0600] P0600: The missing bits in P0600 are in |sect|\ [mem.res.class], |sect|\ [mem.poly.allocator.class], and |sect|\ [container.node.overview].

+   .. [#note-P0966] P0966: It was previously erroneously marked as complete in version 8.0. See `bug 45368 <https://llvm.org/PR45368>`__.

+   .. [#note-P0619] P0619: Only sections D.8, D.9, D.10 and D.13 are implemented. Sections D.4, D.7, D.11, D.12, and D.14 remain undone.

+   .. [#note-P0883] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet.

+

+

+.. _issues-status-cxx20:

+

+Library Working Group Issues Status

+====================================

+

+.. csv-table::

+   :file: Cxx20Issues.csv

+   :header-rows: 1

+   :widths: auto

+

+Last Updated: 24-May-2021

diff --git a/docs/Status/Cxx20Issues.csv b/docs/Status/Cxx20Issues.csv
new file mode 100644
index 0000000..2437cc2
--- /dev/null
+++ b/docs/Status/Cxx20Issues.csv
@@ -0,0 +1,300 @@
+"Issue #","Issue Name","Meeting","Status","First released version"
+"`2070 <https://wg21.link/LWG2070>`__","``allocate_shared``\  should use ``allocator_traits<A>::construct``\ ","Toronto","Resolved by `P0674R1 <https://wg21.link/P0674R1>`__",""
+"`2444 <https://wg21.link/LWG2444>`__","Inconsistent complexity for ``std::sort_heap``\ ","Toronto","",""
+"`2593 <https://wg21.link/LWG2593>`__","Moved-from state of Allocators","Toronto","",""
+"`2597 <https://wg21.link/LWG2597>`__","``std::log``\  misspecified for complex numbers","Toronto","",""
+"`2783 <https://wg21.link/LWG2783>`__","``stack::emplace()``\  and ``queue::emplace()``\  should return ``decltype(auto)``\ ","Toronto","|Complete|",""
+"`2932 <https://wg21.link/LWG2932>`__","Constraints on parallel algorithm implementations are underspecified","Toronto","",""
+"`2937 <https://wg21.link/LWG2937>`__","Is ``equivalent(""existing_thing"", ""not_existing_thing"")``\  an error","Toronto","|Complete|",""
+"`2940 <https://wg21.link/LWG2940>`__","``result_of``\  specification also needs a little cleanup","Toronto","",""
+"`2942 <https://wg21.link/LWG2942>`__","LWG 2873's resolution missed ``weak_ptr::owner_before``\ ","Toronto","|Complete|",""
+"`2954 <https://wg21.link/LWG2954>`__","Specialization of the convenience variable templates should be prohibited","Toronto","|Complete|",""
+"`2961 <https://wg21.link/LWG2961>`__","Bad postcondition for ``set_default_resource``\ ","Toronto","",""
+"`2966 <https://wg21.link/LWG2966>`__","Incomplete resolution of US 74","Toronto","|Nothing To Do|",""
+"`2974 <https://wg21.link/LWG2974>`__","Diagnose out of bounds ``tuple_element/variant_alternative``\ ","Toronto","|Complete|",""
+"","","","",""
+"`2779 <https://wg21.link/LWG2779>`__","[networking.ts] Relax requirements on buffer sequence iterators","Albuquerque","",""
+"`2870 <https://wg21.link/LWG2870>`__","Default value of parameter theta of polar should be dependent","Albuquerque","|Complete|",""
+"`2935 <https://wg21.link/LWG2935>`__","What should create_directories do when p already exists but is not a directory?","Albuquerque","|Nothing To Do|",""
+"`2941 <https://wg21.link/LWG2941>`__","[thread.req.timing] wording should apply to both member and namespace-level functions","Albuquerque","|Nothing To Do|",""
+"`2944 <https://wg21.link/LWG2944>`__","LWG 2905 accidentally removed requirement that construction of the deleter doesn't throw an exception","Albuquerque","|Nothing To Do|",""
+"`2945 <https://wg21.link/LWG2945>`__","Order of template parameters in optional comparisons","Albuquerque","|Complete|",""
+"`2948 <https://wg21.link/LWG2948>`__","unique_ptr does not define operator<< for stream output","Albuquerque","|Complete|",""
+"`2950 <https://wg21.link/LWG2950>`__","std::byte operations are misspecified","Albuquerque","|Complete|",""
+"`2952 <https://wg21.link/LWG2952>`__","iterator_traits should work for pointers to cv T","Albuquerque","|Complete|",""
+"`2953 <https://wg21.link/LWG2953>`__","LWG 2853 should apply to deque::erase too","Albuquerque","|Complete|",""
+"`2958 <https://wg21.link/LWG2958>`__","Moves improperly defined as deleted","Albuquerque","*We already do this*",""
+"`2964 <https://wg21.link/LWG2964>`__","Apparently redundant requirement for dynamic_pointer_cast","Albuquerque","",""
+"`2965 <https://wg21.link/LWG2965>`__","Non-existing path::native_string() in filesystem_error::what() specification","Albuquerque","|Nothing To Do|",""
+"`2972 <https://wg21.link/LWG2972>`__","What is ``is_trivially_destructible_v<int>``\ ?","Albuquerque","|Complete|",""
+"`2976 <https://wg21.link/LWG2976>`__","Dangling uses_allocator specialization for packaged_task","Albuquerque","|Complete|",""
+"`2977 <https://wg21.link/LWG2977>`__","unordered_meow::merge() has incorrect Throws: clause","Albuquerque","|Nothing To Do|",""
+"`2978 <https://wg21.link/LWG2978>`__","Hash support for pmr::string and friends","Albuquerque","",""
+"`2979 <https://wg21.link/LWG2979>`__","aligned_union should require complete object types","Albuquerque","|Complete|",""
+"`2980 <https://wg21.link/LWG2980>`__","Cannot compare_exchange empty pointers","Albuquerque","",""
+"`2981 <https://wg21.link/LWG2981>`__","Remove redundant deduction guides from standard library","Albuquerque","",""
+"`2982 <https://wg21.link/LWG2982>`__","Making size_type consistent in associative container deduction guides","Albuquerque","",""
+"`2988 <https://wg21.link/LWG2988>`__","Clause 32 cleanup missed one typename","Albuquerque","",""
+"`2993 <https://wg21.link/LWG2993>`__","reference_wrapper<T> conversion from T&&","Albuquerque","|Complete|","13.0"
+"`2998 <https://wg21.link/LWG2998>`__","Requirements on function objects passed to {``forward_``,}list-specific algorithms","Albuquerque","|Nothing To Do|",""
+"`3001 <https://wg21.link/LWG3001>`__","weak_ptr::element_type needs remove_extent_t","Albuquerque","",""
+"`3024 <https://wg21.link/LWG3024>`__","variant's copies must be deleted instead of disabled via SFINAE","Albuquerque","|Complete|",""
+"","","","",""
+"`2164 <https://wg21.link/LWG2164>`__","What are the semantics of ``vector.emplace(vector.begin(), vector.back())``\ ?","Jacksonville","|Complete|",""
+"`2243 <https://wg21.link/LWG2243>`__","``istream::putback``\  problem","Jacksonville","|Complete|",""
+"`2816 <https://wg21.link/LWG2816>`__","``resize_file``\  has impossible postcondition","Jacksonville","|Nothing To Do|",""
+"`2843 <https://wg21.link/LWG2843>`__","Unclear behavior of ``std::pmr::memory_resource::do_allocate()``\ ","Jacksonville","|Complete|",""
+"`2849 <https://wg21.link/LWG2849>`__","Why does ``!is_regular_file(from)``\  cause ``copy_file``\  to report a ""file already exists"" error?","Jacksonville","|Nothing To Do|",""
+"`2851 <https://wg21.link/LWG2851>`__","``std::filesystem``\  enum classes are now underspecified","Jacksonville","|Nothing To Do|",""
+"`2946 <https://wg21.link/LWG2946>`__","LWG 2758's resolution missed further corrections","Jacksonville","|Complete|",""
+"`2969 <https://wg21.link/LWG2969>`__","``polymorphic_allocator::construct()``\  shouldn't pass ``resource()``\ ","Jacksonville","|Complete|",""
+"`2975 <https://wg21.link/LWG2975>`__","Missing case for ``pair``\  construction in scoped and polymorphic allocators","Jacksonville","",""
+"`2989 <https://wg21.link/LWG2989>`__","``path``\ 's stream insertion operator lets you insert everything under the sun","Jacksonville","|Complete|",""
+"`3000 <https://wg21.link/LWG3000>`__","``monotonic_memory_resource::do_is_equal``\  uses ``dynamic_cast``\  unnecessarily","Jacksonville","",""
+"`3002 <https://wg21.link/LWG3002>`__","[networking.ts] ``basic_socket_acceptor::is_open()``\  isn't ``noexcept``\ ","Jacksonville","",""
+"`3004 <https://wg21.link/LWG3004>`__","|sect|\ [string.capacity] and |sect|\ [vector.capacity] should specify time complexity for ``capacity()``\ ","Jacksonville","|Nothing To Do|",""
+"`3005 <https://wg21.link/LWG3005>`__","Destruction order of arrays by ``make_shared/allocate_shared``\  only recommended?","Jacksonville","",""
+"`3007 <https://wg21.link/LWG3007>`__","``allocate_shared``\  should rebind allocator to *cv*-unqualified ``value_type``\  for construction","Jacksonville","",""
+"`3009 <https://wg21.link/LWG3009>`__","Including ``<string_view>``\  doesn't provide ``std::size/empty/data``\ ","Jacksonville","|Complete|",""
+"`3010 <https://wg21.link/LWG3010>`__","[networking.ts] ``uses_executor``\  says ""if a type ``T::executor_type``\  exists""","Jacksonville","",""
+"`3013 <https://wg21.link/LWG3013>`__","``(recursive_)directory_iterator``\  construction and traversal should not be ``noexcept``\ ","Jacksonville","|Complete|",""
+"`3014 <https://wg21.link/LWG3014>`__","More ``noexcept``\  issues with filesystem operations","Jacksonville","|Complete|",""
+"`3015 <https://wg21.link/LWG3015>`__","``copy_options::*unspecified*``\  underspecified","Jacksonville","|Nothing To Do|",""
+"`3017 <https://wg21.link/LWG3017>`__","``list splice``\  functions should use ``addressof``\ ","Jacksonville","|Complete|",""
+"`3020 <https://wg21.link/LWG3020>`__","[networking.ts] Remove spurious nested ``value_type``\  buffer sequence requirement","Jacksonville","",""
+"`3026 <https://wg21.link/LWG3026>`__","``filesystem::weakly_canonical``\  still defined in terms of ``canonical(p, base)``\ ","Jacksonville","|Complete|",""
+"`3030 <https://wg21.link/LWG3030>`__","Who shall meet the requirements of ``try_lock``\ ?","Jacksonville","|Nothing To Do|",""
+"`3034 <https://wg21.link/LWG3034>`__","P0767R1 breaks previously-standard-layout types","Jacksonville","|Complete|",""
+"`3035 <https://wg21.link/LWG3035>`__","``std::allocator``\ 's constructors should be ``constexpr``\ ","Jacksonville","|Complete|",""
+"`3039 <https://wg21.link/LWG3039>`__","Unnecessary ``decay``\  in ``thread``\  and ``packaged_task``\ ","Jacksonville","|Complete|",""
+"`3041 <https://wg21.link/LWG3041>`__","Unnecessary ``decay``\  in ``reference_wrapper``\ ","Jacksonville","|Complete|",""
+"`3042 <https://wg21.link/LWG3042>`__","``is_literal_type_v``\  should be inline","Jacksonville","|Complete|",""
+"`3043 <https://wg21.link/LWG3043>`__","Bogus postcondition for ``filesystem_error``\  constructor","Jacksonville","|Complete|",""
+"`3045 <https://wg21.link/LWG3045>`__","``atomic<*floating-point*>``\  doesn't have ``value_type``\  or ``difference_type``\ ","Jacksonville","",""
+"`3048 <https://wg21.link/LWG3048>`__","``transform_reduce(exec, first1, last1, first2, init)``\  discards execution policy","Jacksonville","",""
+"`3051 <https://wg21.link/LWG3051>`__","Floating point classifications were inadvertently changed in P0175","Jacksonville","|Nothing To Do|",""
+"`3075 <https://wg21.link/LWG3075>`__","``basic_string``\  needs deduction guides from ``basic_string_view``\ ","Jacksonville","|Complete|",""
+"","","","",""
+"`2139 <https://wg21.link/LWG2139>`__","What is a user-defined type?","Rapperswil","",""
+"`2970 <https://wg21.link/LWG2970>`__","Return type of std::visit misspecified","Rapperswil","",""
+"`3058 <https://wg21.link/LWG3058>`__","Parallel adjacent_difference shouldn't require creating temporaries","Rapperswil","",""
+"`3062 <https://wg21.link/LWG3062>`__","Unnecessary decay_t in is_execution_policy_v should be remove_cvref_t","Rapperswil","",""
+"`3067 <https://wg21.link/LWG3067>`__","recursive_directory_iterator::pop must invalidate","Rapperswil","|Nothing To Do|",""
+"`3071 <https://wg21.link/LWG3071>`__","[networking.ts] read_until still refers to ""input sequence""","Rapperswil","|Nothing To Do|",""
+"`3074 <https://wg21.link/LWG3074>`__","Non-member functions for valarray should only deduce from the valarray","Rapperswil","",""
+"`3076 <https://wg21.link/LWG3076>`__","basic_string CTAD ambiguity","Rapperswil","|Complete|",""
+"`3079 <https://wg21.link/LWG3079>`__","LWG 2935 forgot to fix the existing_p overloads of create_directory","Rapperswil","|Nothing To Do|",""
+"`3080 <https://wg21.link/LWG3080>`__","Floating point from_chars pattern specification breaks round-tripping","Rapperswil","",""
+"`3083 <https://wg21.link/LWG3083>`__","What should ios::iword(-1) do?","Rapperswil","|Nothing To Do|",""
+"`3094 <https://wg21.link/LWG3094>`__","[time.duration.io]p4 makes surprising claims about encoding","Rapperswil","",""
+"`3100 <https://wg21.link/LWG3100>`__","Unnecessary and confusing ""empty span"" wording","Rapperswil","|Nothing To Do|",""
+"`3102 <https://wg21.link/LWG3102>`__","Clarify span iterator and ``const_iterator`` behavior","Rapperswil","|Complete|",""
+"`3104 <https://wg21.link/LWG3104>`__","Fixing duration division","Rapperswil","|Complete|",""
+"","","","",""
+"`2183 <https://wg21.link/LWG2183>`__","Muddled allocator requirements for ``match_results``\  constructors","San Diego","|Complete|",""
+"`2184 <https://wg21.link/LWG2184>`__","Muddled allocator requirements for ``match_results``\  assignments","San Diego","|Complete|",""
+"`2412 <https://wg21.link/LWG2412>`__","``promise::set_value()``\  and ``promise::get_future()``\  should not race","San Diego","",""
+"`2499 <https://wg21.link/LWG2499>`__","``operator>>(basic_istream&, CharT*)``\  makes it hard to avoid buffer overflows","San Diego","Resolved by P0487R1",""
+"`2682 <https://wg21.link/LWG2682>`__","``filesystem::copy()``\  won't create a symlink to a directory","San Diego","|Nothing To Do|",""
+"`2697 <https://wg21.link/LWG2697>`__","[concurr.ts] Behavior of ``future/shared_future``\  unwrapping constructor when given an invalid ``future``\ ","San Diego","",""
+"`2797 <https://wg21.link/LWG2797>`__","Trait precondition violations","San Diego","Resolved by 1285R0",""
+"`2936 <https://wg21.link/LWG2936>`__","Path comparison is defined in terms of the generic format","San Diego","|Complete|",""
+"`2943 <https://wg21.link/LWG2943>`__","Problematic specification of the wide version of ``basic_filebuf::open``\ ","San Diego","|Nothing To Do|",""
+"`2960 <https://wg21.link/LWG2960>`__","[fund.ts.v3] ``nonesuch``\  is insufficiently useless","San Diego","|Complete|",""
+"`2995 <https://wg21.link/LWG2995>`__","``basic_stringbuf``\  default constructor forbids it from using SSO capacity","San Diego","",""
+"`2996 <https://wg21.link/LWG2996>`__","Missing rvalue overloads for ``shared_ptr``\  operations","San Diego","",""
+"`3008 <https://wg21.link/LWG3008>`__","``make_shared``\  (sub)object destruction semantics are not specified","San Diego","",""
+"`3022 <https://wg21.link/LWG3022>`__","``is_convertible<derived*, base*>``\  may lead to ODR","San Diego","Resolved by 1285R0",""
+"`3025 <https://wg21.link/LWG3025>`__","Map-like container deduction guides should use ``pair<Key, T>``\ , not ``pair<const Key, T>``\ ","San Diego","|Complete|",""
+"`3031 <https://wg21.link/LWG3031>`__","Algorithms and predicates with non-const reference arguments","San Diego","",""
+"`3037 <https://wg21.link/LWG3037>`__","``polymorphic_allocator``\  and incomplete types","San Diego","",""
+"`3038 <https://wg21.link/LWG3038>`__","``polymorphic_allocator::allocate``\  should not allow integer overflow to create vulnerabilities","San Diego","",""
+"`3054 <https://wg21.link/LWG3054>`__","``uninitialized_copy``\  appears to not be able to meet its exception-safety guarantee","San Diego","",""
+"`3065 <https://wg21.link/LWG3065>`__","LWG 2989 missed that all ``path``\ 's other operators should be hidden friends as well","San Diego","|Complete|",""
+"`3096 <https://wg21.link/LWG3096>`__","``path::lexically_relative``\  is confused by trailing slashes","San Diego","|Complete|",""
+"`3116 <https://wg21.link/LWG3116>`__","``*OUTERMOST_ALLOC_TRAITS*``\  needs ``remove_reference_t``\ ","San Diego","",""
+"`3122 <https://wg21.link/LWG3122>`__","``__cpp_lib_chrono_udls``\  was accidentally dropped","San Diego","|Complete|",""
+"`3127 <https://wg21.link/LWG3127>`__","``basic_osyncstream::rdbuf``\  needs a ````const_cast````\ ","San Diego","",""
+"`3128 <https://wg21.link/LWG3128>`__","``strstream::rdbuf``\  needs a ````const_cast````\ ","San Diego","|Nothing To Do|",""
+"`3129 <https://wg21.link/LWG3129>`__","``regex_token_iterator``\  constructor uses wrong pointer arithmetic","San Diego","",""
+"`3130 <https://wg21.link/LWG3130>`__","|sect|\ [input.output] needs many ``addressof``\ ","San Diego","",""
+"`3131 <https://wg21.link/LWG3131>`__","``addressof``\  all the things","San Diego","",""
+"`3132 <https://wg21.link/LWG3132>`__","Library needs to ban macros named ``expects``\  or ``ensures``\ ","San Diego","|Nothing To Do|",""
+"`3134 <https://wg21.link/LWG3134>`__","[fund.ts.v3] LFTSv3 contains extraneous [meta] variable templates that should have been deleted by P09961","San Diego","Resolved by P1210R0",""
+"`3137 <https://wg21.link/LWG3137>`__","Header for ``__cpp_lib_to_chars``\ ","San Diego","|Complete|",""
+"`3145 <https://wg21.link/LWG3145>`__","``file_clock``\  breaks ABI for C++17 implementations","San Diego","|Complete|",""
+"`3147 <https://wg21.link/LWG3147>`__","Definitions of ""likely"" and ""unlikely"" are likely to cause problems","San Diego","",""
+"`3148 <https://wg21.link/LWG3148>`__","``<concepts>``\  should be freestanding","San Diego","",""
+"`3153 <https://wg21.link/LWG3153>`__","``Common``\  and ``common_type``\  have too little in common","San Diego","",""
+"`3154 <https://wg21.link/LWG3154>`__","``Common``\  and ``CommonReference``\  have a common defect","San Diego","",""
+"","","","",""
+"`3012 <https://wg21.link/LWG3012>`__","``atomic<T>``\  is unimplementable for non-``is_trivially_copy_constructible T``\ ","Kona","",""
+"`3040 <https://wg21.link/LWG3040>`__","``basic_string_view::starts_with``\  *Effects* are incorrect","Kona","|Complete|",""
+"`3077 <https://wg21.link/LWG3077>`__","``(push|emplace)_back``\  should invalidate the ``end``\  iterator","Kona","|Nothing To Do|",""
+"`3087 <https://wg21.link/LWG3087>`__","One final ``&x``\  in |sect|\ [list.ops]","Kona","|Nothing To Do|",""
+"`3101 <https://wg21.link/LWG3101>`__","``span``\ 's ``Container``\  constructors need another constraint","Kona","|Complete|",""
+"`3112 <https://wg21.link/LWG3112>`__","``system_error``\  and ``filesystem_error``\  constructors taking a ``string``\  may not be able to meet their postconditions","Kona","",""
+"`3119 <https://wg21.link/LWG3119>`__","Program-definedness of closure types","Kona","|Nothing To Do|",""
+"`3133 <https://wg21.link/LWG3133>`__","Modernizing numeric type requirements","Kona","",""
+"`3144 <https://wg21.link/LWG3144>`__","``span``\  does not have a ````const_pointer````\  typedef","Kona","|Complete|",""
+"`3173 <https://wg21.link/LWG3173>`__","Enable CTAD for *``ref-view``*\ ","Kona","",""
+"`3179 <https://wg21.link/LWG3179>`__","``subrange``\  should always model ``Range``\ ","Kona","",""
+"`3180 <https://wg21.link/LWG3180>`__","Inconsistently named return type for ``ranges::minmax_element``\ ","Kona","",""
+"`3182 <https://wg21.link/LWG3182>`__","Specification of ``Same``\  could be clearer","Kona","",""
+"","","","",""
+"`2899 <https://wg21.link/LWG2899>`__","``is_(nothrow_)move_constructible``\  and ``tuple``\ , ``optional``\  and ``unique_ptr``\ ","Cologne","",""
+"`3055 <https://wg21.link/LWG3055>`__","``path::operator+=(*single-character*)``\  misspecified","Cologne","|Complete|","7.0"
+"`3158 <https://wg21.link/LWG3158>`__","``tuple(allocator_arg_t, const Alloc&)``\  should be conditionally explicit","Cologne","",""
+"`3169 <https://wg21.link/LWG3169>`__","``ranges``\  permutation generators discard useful information","Cologne","",""
+"`3183 <https://wg21.link/LWG3183>`__","Normative permission to specialize Ranges variable templates","Cologne","",""
+"`3184 <https://wg21.link/LWG3184>`__","Inconsistencies in ``bind_front``\  wording","Cologne","|Complete|","13.0"
+"`3185 <https://wg21.link/LWG3185>`__","Uses-allocator construction functions missing ``constexpr``\  and ``noexcept``\ ","Cologne","",""
+"`3186 <https://wg21.link/LWG3186>`__","``ranges``\  removal, partition, and ``partial_sort_copy``\  algorithms discard useful information","Cologne","",""
+"`3187 <https://wg21.link/LWG3187>`__","`P0591R4 <https://wg21.link/p0591r4>`__ reverted DR 2586 fixes to ``scoped_allocator_adaptor::construct()``\ ","Cologne","",""
+"`3191 <https://wg21.link/LWG3191>`__","``std::ranges::shuffle``\  synopsis does not match algorithm definition","Cologne","",""
+"`3196 <https://wg21.link/LWG3196>`__","``std::optional<T>``\  is ill-formed is ``T``\  is an array","Cologne","|Complete|",""
+"`3198 <https://wg21.link/LWG3198>`__","Bad constraint on ``std::span::span()``\ ","Cologne","|Complete|",""
+"`3199 <https://wg21.link/LWG3199>`__","``istream >> bitset<0>``\  fails","Cologne","",""
+"`3202 <https://wg21.link/LWG3202>`__","P0318R1 was supposed to be revised","Cologne","|Complete|",""
+"`3206 <https://wg21.link/LWG3206>`__","``year_month_day``\  conversion to ``sys_days``\  uses not-existing member function","Cologne","|Complete|",""
+"`3208 <https://wg21.link/LWG3208>`__","``Boolean``\ 's expression requirements are ordered inconsistently","Cologne","|Nothing To Do|",""
+"`3209 <https://wg21.link/LWG3209>`__","Expression in ``year::ok()``\  returns clause is ill-formed","Cologne","|Complete|",""
+"","","","",""
+"`3231 <https://wg21.link/LWG3231>`__","``year_month_day_last::day``\  specification does not cover ``!ok()``\  values","Belfast","|Nothing To Do|",""
+"`3225 <https://wg21.link/LWG3225>`__","``zoned_time``\  converting constructor shall not be ``noexcept``\ ","Belfast","",""
+"`3190 <https://wg21.link/LWG3190>`__","``std::allocator::allocate``\  sometimes returns too little storage","Belfast","",""
+"`3218 <https://wg21.link/LWG3218>`__","Modifier for ``%d``\  parse flag does not match POSIX and ``format``\  specification","Belfast","",""
+"`3224 <https://wg21.link/LWG3224>`__","``zoned_time``\  constructor from ``TimeZonePtr``\  does not specify initialization of ``tp_``\ ","Belfast","",""
+"`3230 <https://wg21.link/LWG3230>`__","Format specifier ``%y/%Y``\  is missing locale alternative versions","Belfast","",""
+"`3232 <https://wg21.link/LWG3232>`__","Inconsistency in ``zoned_time``\  deduction guides","Belfast","",""
+"`3222 <https://wg21.link/LWG3222>`__","P0574R1 introduced preconditions on non-existent parameters","Belfast","",""
+"`3221 <https://wg21.link/LWG3221>`__","Result of ``year_month``\  arithmetic with ``months``\  is ambiguous","Belfast","|Complete|","8.0"
+"`3235 <https://wg21.link/LWG3235>`__","``parse``\  manipulator without abbreviation is not callable","Belfast","",""
+"`3246 <https://wg21.link/LWG3246>`__","What are the constraints on the template parameter of ``basic_format_arg``\ ?","Belfast","",""
+"`3253 <https://wg21.link/LWG3253>`__","``basic_syncbuf::basic_syncbuf()``\  should not be explicit","Belfast","",""
+"`3245 <https://wg21.link/LWG3245>`__","Unnecessary restriction on ``'%p'``\  parse specifier","Belfast","",""
+"`3244 <https://wg21.link/LWG3244>`__","Constraints for ``Source``\  in |sect|\ [fs.path.req] insufficiently constrainty","Belfast","",""
+"`3241 <https://wg21.link/LWG3241>`__","``chrono-spec``\  grammar ambiguity in |sect|\ [time.format]","Belfast","",""
+"`3257 <https://wg21.link/LWG3257>`__","Missing feature testing macro update from P0858","Belfast","",""
+"`3256 <https://wg21.link/LWG3256>`__","Feature testing macro for ``constexpr``\  algorithms","Belfast","|Complete|","13.0"
+"`3273 <https://wg21.link/LWG3273>`__","Specify ``weekday_indexed``\  to range of ``[0, 7]``\ ","Belfast","",""
+"`3070 <https://wg21.link/LWG3070>`__","``path::lexically_relative``\  causes surprising results if a filename can also be a  *root-name*","Belfast","",""
+"`3266 <https://wg21.link/LWG3266>`__","``to_chars(bool)``\  should be deleted","Belfast","",""
+"`3272 <https://wg21.link/LWG3272>`__","``%I%p``\  should parse/format ``duration``\  since midnight","Belfast","",""
+"`3259 <https://wg21.link/LWG3259>`__","The definition of *constexpr iterators* should be adjusted","Belfast","",""
+"`3103 <https://wg21.link/LWG3103>`__","Errors in taking subview of ``span``\  should be ill-formed where possible","Belfast","",""
+"`3274 <https://wg21.link/LWG3274>`__","Missing feature test macro for ``<span>``\ ","Belfast","",""
+"`3276 <https://wg21.link/LWG3276>`__","Class ``split_view::outer_iterator::value_type``\  should inherit from ``view_interface``\ ","Belfast","",""
+"`3277 <https://wg21.link/LWG3277>`__","Pre-increment on prvalues is not a requirement of ``weakly_incrementable``\ ","Belfast","",""
+"`3149 <https://wg21.link/LWG3149>`__","``DefaultConstructible``\  should require default initialization","Belfast","|Complete|","13.0"
+"","","","",""
+"`1203 <https://wg21.link/LWG1203>`__","More useful rvalue stream insertion","Prague","|Complete|","12.0"
+"`2859 <https://wg21.link/LWG2859>`__","Definition of *reachable* in [ptr.launder] misses pointer arithmetic from pointer-interconvertible object","Prague","",""
+"`3018 <https://wg21.link/LWG3018>`__","``shared_ptr``\  of function type","Prague","",""
+"`3050 <https://wg21.link/LWG3050>`__","Conversion specification problem in ``chrono::duration``\  constructor","Prague","",""
+"`3141 <https://wg21.link/LWG3141>`__","``CopyConstructible``\  doesn't preserve source values","Prague","|Nothing to do|",""
+"`3150 <https://wg21.link/LWG3150>`__","``UniformRandomBitGenerator``\  should validate ``min``\  and ``max``\ ","Prague","|Complete|","13.0"
+"`3175 <https://wg21.link/LWG3175>`__","The ``CommonReference``\  requirement of concept ``SwappableWith``\  is not satisfied in the example","Prague","|Complete|","13.0"
+"`3194 <https://wg21.link/LWG3194>`__","``ConvertibleTo``\  prose does not match code","Prague","|Complete|","13.0"
+"`3200 <https://wg21.link/LWG3200>`__","``midpoint``\  should not constrain ``T``\  is complete","Prague","|Nothing To Do|",""
+"`3201 <https://wg21.link/LWG3201>`__","``lerp``\  should be marked as ``noexcept``\ ","Prague","|Complete|",""
+"`3226 <https://wg21.link/LWG3226>`__","``zoned_time``\  constructor from ``string_view``\  should accept ``zoned_time<Duration2, TimeZonePtr2>``\ ","Prague","",""
+"`3233 <https://wg21.link/LWG3233>`__","Broken requirements for ``shared_ptr``\  converting constructors","Prague","",""
+"`3237 <https://wg21.link/LWG3237>`__","LWG 3038 and 3190 have inconsistent PRs","Prague","",""
+"`3238 <https://wg21.link/LWG3238>`__","Insufficiently-defined behavior of ``std::function``\  deduction guides","Prague","",""
+"`3242 <https://wg21.link/LWG3242>`__","``std::format``\ : missing rules for ``arg-id``\  in ``width``\  and ``precision``\ ","Prague","",""
+"`3243 <https://wg21.link/LWG3243>`__","``std::format``\  and negative zeroes","Prague","",""
+"`3247 <https://wg21.link/LWG3247>`__","``ranges::iter_move``\  should perform ADL-only lookup of ``iter_move``\ ","Prague","",""
+"`3248 <https://wg21.link/LWG3248>`__","``std::format``\  ``#b``\ , ``#B``\ , ``#o``\ , ``#x``\ , and ``#X``\   presentation types misformat negative numbers","Prague","",""
+"`3250 <https://wg21.link/LWG3250>`__","``std::format``\ : ``#``\  (alternate form) for NaN and inf","Prague","",""
+"`3251 <https://wg21.link/LWG3251>`__","Are ``std::format``\  alignment specifiers applied to string arguments?","Prague","",""
+"`3252 <https://wg21.link/LWG3252>`__","Parse locale's aware modifiers for commands are not consistent with POSIX spec","Prague","",""
+"`3254 <https://wg21.link/LWG3254>`__","Strike ``stop_token``\ 's ``operator!=``\ ","Prague","",""
+"`3255 <https://wg21.link/LWG3255>`__","``span``\ 's ``array``\  constructor is too strict","Prague","|Complete|",""
+"`3260 <https://wg21.link/LWG3260>`__","``year_month*``\  arithmetic rejects durations convertible to years","Prague","",""
+"`3262 <https://wg21.link/LWG3262>`__","Formatting of negative durations is not specified","Prague","",""
+"`3264 <https://wg21.link/LWG3264>`__","``sized_range``\  and ``ranges::size``\  redundantly use ``disable_sized_range``\ ","Prague","",""
+"`3269 <https://wg21.link/LWG3269>`__","Parse manipulators do not specify the result of the extraction from stream","Prague","",""
+"`3270 <https://wg21.link/LWG3270>`__","Parsing and formatting ``%j``\  with ``duration``\ s","Prague","",""
+"`3280 <https://wg21.link/LWG3280>`__","View converting constructors can cause constraint recursion and are unneeded","Prague","",""
+"`3281 <https://wg21.link/LWG3281>`__","Conversion from ``*pair-like*``\  types to ``subrange``\  is a silent semantic promotion","Prague","",""
+"`3282 <https://wg21.link/LWG3282>`__","``subrange``\  converting constructor should disallow derived to base conversions","Prague","",""
+"`3284 <https://wg21.link/LWG3284>`__","``random_access_iterator``\  semantic constraints accidentally promote difference type  using unary negate","Prague","",""
+"`3285 <https://wg21.link/LWG3285>`__","The type of a customization point object shall satisfy ``semiregular``\ ","Prague","",""
+"`3286 <https://wg21.link/LWG3286>`__","``ranges::size``\  is not required to be valid after a call to ``ranges::begin``\  on an input range","Prague","",""
+"`3291 <https://wg21.link/LWG3291>`__","``iota_view::iterator``\  has the wrong ``iterator_category``\ ","Prague","",""
+"`3292 <https://wg21.link/LWG3292>`__","``iota_view``\  is under-constrained","Prague","",""
+"`3294 <https://wg21.link/LWG3294>`__","``zoned_time``\  deduction guides misinterprets ``string``\ /``char*``\ ","Prague","",""
+"`3296 <https://wg21.link/LWG3296>`__","Inconsistent default argument for ``basic_regex<>::assign``\ ","Prague","|Complete|",""
+"`3299 <https://wg21.link/LWG3299>`__","Pointers don't need customized iterator behavior","Prague","",""
+"`3300 <https://wg21.link/LWG3300>`__","Non-array ``ssize``\  overload is underconstrained","Prague","",""
+"`3301 <https://wg21.link/LWG3301>`__","``transform_view::iterator``\  has incorrect ``iterator_category``\ ","Prague","",""
+"`3302 <https://wg21.link/LWG3302>`__","Range adaptor objects ``keys``\  and ``values``\  are unspecified","Prague","",""
+"`3303 <https://wg21.link/LWG3303>`__","Bad ""``constexpr``\ "" marker for ``destroy/destroy_n``\ ","Prague","",""
+"`3304 <https://wg21.link/LWG3304>`__","Allocate functions of ``std::polymorphic_allocator``\  should require ``[[nodiscard]]``\ ","Prague","",""
+"`3307 <https://wg21.link/LWG3307>`__","``std::allocator<void>().allocate(n)``\ ","Prague","",""
+"`3310 <https://wg21.link/LWG3310>`__","Replace ``SIZE_MAX``\  with ``numeric_limits<size_t>::max()``\ ","Prague","",""
+"`3313 <https://wg21.link/LWG3313>`__","``join_view::iterator::operator--``\  is incorrectly constrained","Prague","",""
+"`3314 <https://wg21.link/LWG3314>`__","Is stream insertion behavior locale dependent when ``Period::type``\  is ``micro``\ ?","Prague","",""
+"`3315 <https://wg21.link/LWG3315>`__","Correct Allocator Default Behavior","Prague","",""
+"`3316 <https://wg21.link/LWG3316>`__","Correctly define epoch for ``utc_clock``\  / ``utc_timepoint``\ ","Prague","",""
+"`3317 <https://wg21.link/LWG3317>`__","Incorrect ``operator<<``\  for floating-point durations","Prague","",""
+"`3318 <https://wg21.link/LWG3318>`__","Clarify whether clocks can represent time before their epoch","Prague","",""
+"`3319 <https://wg21.link/LWG3319>`__","Properly reference specification of IANA time zone database","Prague","",""
+"`3320 <https://wg21.link/LWG3320>`__","``span::cbegin/cend``\  methods produce different results than ``std::[ranges::]cbegin/cend``\ ","Prague","|Complete|",""
+"`3321 <https://wg21.link/LWG3321>`__","``uninitialized_construct_using_allocator``\  should use ``construct_at``\ ","Prague","",""
+"`3323 <https://wg21.link/LWG3323>`__","``*has-tuple-element*``\  helper concept needs ``convertible_to``\ ","Prague","",""
+"`3324 <https://wg21.link/LWG3324>`__","Special-case ``std::strong/weak/partial_order``\  for pointers","Prague","",""
+"`3325 <https://wg21.link/LWG3325>`__","Constrain return type of transformation function for ``transform_view``\ ","Prague","",""
+"`3326 <https://wg21.link/LWG3326>`__","``enable_view``\  has false positives","Prague","|In progress|",""
+"`3327 <https://wg21.link/LWG3327>`__","Format alignment specifiers vs. text direction","Prague","|Nothing To Do|",""
+"`3328 <https://wg21.link/LWG3328>`__","Clarify that ``std::string``\  is not good for UTF-8","Prague","",""
+"`3329 <https://wg21.link/LWG3329>`__","``totally_ordered_with``\  both directly and indirectly requires ``common_reference_with``\ ","Prague","|Complete|","13.0"
+"`3330 <https://wg21.link/LWG3330>`__","Include ``<compare>``\  from most library headers","Prague","",""
+"`3331 <https://wg21.link/LWG3331>`__","Define ``totally_ordered/_with``\  in terms of ``*partially-ordered-with*``\ ","Prague","|Complete|","13.0"
+"`3332 <https://wg21.link/LWG3332>`__","Issue in |sect|\ [time.format]","Prague","",""
+"`3334 <https://wg21.link/LWG3334>`__","``basic_osyncstream``\  move assignment and destruction calls ``basic_syncbuf::emit()``\  twice","Prague","",""
+"`3335 <https://wg21.link/LWG3335>`__","Resolve C++20 NB comments US 273 and GB 274","Prague","",""
+"`3338 <https://wg21.link/LWG3338>`__","Rename ``default_constructible``\  to ``default_initializable``\ ","Prague","|Complete|","13.0"
+"`3340 <https://wg21.link/LWG3340>`__","Formatting functions should throw on argument/format string mismatch in |sect|\ [format.functions]","Prague","",""
+"`3346 <https://wg21.link/LWG3346>`__","``pair``\  and ``tuple``\  copy and move constructor have backwards specification","Prague","",""
+"`3347 <https://wg21.link/LWG3347>`__","``std::pair<T, U>``\  now requires ``T``\  and ``U``\  to be less-than-comparable","Prague","",""
+"`3348 <https://wg21.link/LWG3348>`__","``__cpp_lib_unwrap_ref``\  in wrong header","Prague","",""
+"`3349 <https://wg21.link/LWG3349>`__","Missing ``__cpp_lib_constexpr_complex``\  for P0415R1","Prague","",""
+"`3350 <https://wg21.link/LWG3350>`__","Simplify return type of ``lexicographical_compare_three_way``\ ","Prague","",""
+"`3351 <https://wg21.link/LWG3351>`__","``ranges::enable_safe_range``\  should not be constrained","Prague","",""
+"`3352 <https://wg21.link/LWG3352>`__","``strong_equality``\  isn't a thing","Prague","",""
+"`3354 <https://wg21.link/LWG3354>`__","``has_strong_structural_equality``\  has a meaningless definition","Prague","",""
+"`3355 <https://wg21.link/LWG3355>`__","The memory algorithms should support move-only input iterators introduced by P1207","Prague","",""
+"`3356 <https://wg21.link/LWG3356>`__","``__cpp_lib_nothrow_convertible``\  should be ``__cpp_lib_is_nothrow_convertible``\ ","Prague","",""
+"`3358 <https://wg21.link/LWG3358>`__","|sect|\ [span.cons] is mistaken that ``to_address``\  can throw","Prague","",""
+"`3359 <https://wg21.link/LWG3359>`__","``<chrono>``\  leap second support should allow for negative leap seconds","Prague","",""
+"`3360 <https://wg21.link/LWG3360>`__","``three_way_comparable_with``\  is inconsistent with similar concepts","Prague","",""
+"`3362 <https://wg21.link/LWG3362>`__","Strike ``stop_source``\ 's ``operator!=``\ ","Prague","",""
+"`3363 <https://wg21.link/LWG3363>`__","``drop_while_view``\  should opt-out of ``sized_range``\ ","Prague","",""
+"`3364 <https://wg21.link/LWG3364>`__","Initialize data members of ranges and their iterators","Prague","",""
+"`3367 <https://wg21.link/LWG3367>`__","Integer-class conversions should not throw","Prague","",""
+"`3369 <https://wg21.link/LWG3369>`__","``span``\ 's deduction-guide for built-in arrays doesn't work","Prague","",""
+"`3371 <https://wg21.link/LWG3371>`__","``visit_format_arg``\  and ``make_format_args``\  are not hidden friends","Prague","",""
+"`3372 <https://wg21.link/LWG3372>`__","``vformat_to``\  should not try to deduce ``Out``\  twice","Prague","",""
+"`3373 <https://wg21.link/LWG3373>`__","``{to,from}_chars_result``\  and ``format_to_n_result``\  need the  ""we really mean what we say"" wording","Prague","",""
+"`3374 <https://wg21.link/LWG3374>`__","P0653 + P1006 should have made the other ``std::to_address``\  overload ``constexpr``\ ","Prague","|Complete|","12.0"
+"`3375 <https://wg21.link/LWG3375>`__","``decay``\  in ``viewable_range``\  should be ``remove_cvref``\ ","Prague","",""
+"`3377 <https://wg21.link/LWG3377>`__","``elements_view::iterator``\  befriends a specialization of itself","Prague","",""
+"`3379 <https://wg21.link/LWG3379>`__","""``safe``\ "" in several library names is misleading","Prague","|In Progress|",""
+"`3380 <https://wg21.link/LWG3380>`__","``common_type``\  and comparison categories","Prague","",""
+"`3381 <https://wg21.link/LWG3381>`__","``begin``\  and ``data``\  must agree for ``contiguous_range``\ ","Prague","",""
+"`3382 <https://wg21.link/LWG3382>`__","NTTP for ``pair``\  and ``array``\ ","Prague","",""
+"`3383 <https://wg21.link/LWG3383>`__","|sect|\ [time.zone.leap.nonmembers] ``sys_seconds``\  should be replaced with ``seconds``\ ","Prague","",""
+"`3384 <https://wg21.link/LWG3384>`__","``transform_view::*sentinel*``\  has an incorrect ``operator-``\ ","Prague","",""
+"`3385 <https://wg21.link/LWG3385>`__","``common_iterator``\  is not sufficiently constrained for non-copyable iterators","Prague","",""
+"`3387 <https://wg21.link/LWG3387>`__","|sect|\ [range.reverse.view] ``reverse_view<V>``\  unintentionally requires ``range<const V>``\ ","Prague","",""
+"`3388 <https://wg21.link/LWG3388>`__","``view``\  iterator types have ill-formed ``<=>``\  operators","Prague","",""
+"`3389 <https://wg21.link/LWG3389>`__","A move-only iterator still does not have a ``counted_iterator``\ ","Prague","",""
+"`3390 <https://wg21.link/LWG3390>`__","``make_move_iterator()``\  cannot be used to construct a ``move_iterator``\  for a move-only iterator","Prague","",""
+"`3393 <https://wg21.link/LWG3393>`__","Missing/incorrect feature test macro for coroutines","Prague","",""
+"`3395 <https://wg21.link/LWG3395>`__","Definition for three-way comparison needs to be updated (US 152)","Prague","",""
+"`3396 <https://wg21.link/LWG3396>`__","Clarify point of reference for ``source_location::current()``\  (DE 169)","Prague","",""
+"`3397 <https://wg21.link/LWG3397>`__","``ranges::basic_istream_view::iterator``\  should not provide ``iterator_category``\ ","Prague","",""
+"`3398 <https://wg21.link/LWG3398>`__","``tuple_element_t``\  is also wrong for ``const subrange``\ ","Prague","",""
+"`3446 <https://wg21.link/LWG3446>`__","``indirectly_readable_traits``\ ambiguity for types with both ``value_type``\ and ``element_type``\ ","November virtual meeting","|Complete|","13.0"
diff --git a/docs/Status/Cxx20Papers.csv b/docs/Status/Cxx20Papers.csv
new file mode 100644
index 0000000..7915b79
--- /dev/null
+++ b/docs/Status/Cxx20Papers.csv
@@ -0,0 +1,202 @@
+"Paper #","Group","Paper Name","Meeting","Status","First released version"
+"`P0463R1 <https://wg21.link/P0463R1>`__","LWG","Endian just Endian","Toronto","|Complete|","7.0"
+"`P0674R1 <https://wg21.link/P0674R1>`__","LWG","Extending make_shared to Support Arrays","Toronto","",""
+"","","","","",""
+"`P0020R6 <https://wg21.link/P0020R6>`__","LWG","Floating Point Atomic","Albuquerque","",""
+"`P0053R7 <https://wg21.link/P0053R7>`__","LWG","C++ Synchronized Buffered Ostream","Albuquerque","",""
+"`P0202R3 <https://wg21.link/P0202R3>`__","LWG","Add constexpr modifiers to functions in <algorithm> and <utility> Headers","Albuquerque","|Complete|","12.0"
+"`P0415R1 <https://wg21.link/P0415R1>`__","LWG","Constexpr for ``std::complex``\ ","Albuquerque","|In Progress|","7.0"
+"`P0439R0 <https://wg21.link/P0439R0>`__","LWG","Make ``std::memory_order``\  a scoped enumeration","Albuquerque","|Complete|",""
+"`P0457R2 <https://wg21.link/P0457R2>`__","LWG","String Prefix and Suffix Checking","Albuquerque","|Complete|","6.0"
+"`P0550R2 <https://wg21.link/P0550R2>`__","LWG","Transformation Trait ``remove_cvref``\ ","Albuquerque","|Complete|","6.0"
+"`P0600R1 <https://wg21.link/P0600R1>`__","LWG","nodiscard in the Library","Albuquerque","|In Progress| [#note-P0600]_","7.0"
+"`P0616R0 <https://wg21.link/P0616R0>`__","LWG","de-pessimize legacy <numeric> algorithms with std::move","Albuquerque","|Complete|","12.0"
+"`P0653R2 <https://wg21.link/P0653R2>`__","LWG","Utility to convert a pointer to a raw pointer","Albuquerque","|Complete|","6.0"
+"`P0718R2 <https://wg21.link/P0718R2>`__","LWG","Atomic shared_ptr","Albuquerque","",""
+"`P0767R1 <https://wg21.link/P0767R1>`__","CWG","Deprecate POD","Albuquerque","|Complete|","7.0"
+"`P0768R1 <https://wg21.link/P0768R1>`__","CWG","Library Support for the Spaceship (Comparison) Operator","Albuquerque","|Complete|",""
+"`P0777R1 <https://wg21.link/P0777R1>`__","LWG","Treating Unnecessary ``decay``\ ","Albuquerque","|Complete|","7.0"
+"`P0122R7 <https://wg21.link/P0122R7>`__","LWG","<span>","Jacksonville","|Complete|","7.0"
+"`P0355R7 <https://wg21.link/P0355R7>`__","LWG","Extending chrono to Calendars and Time Zones","Jacksonville","|In Progress|",""
+"`P0551R3 <https://wg21.link/P0551R3>`__","LWG","Thou Shalt Not Specialize ``std``\  Function Templates!","Jacksonville","|Complete|","11.0"
+"`P0753R2 <https://wg21.link/P0753R2>`__","LWG","Manipulators for C++ Synchronized Buffered Ostream","Jacksonville","",""
+"`P0754R2 <https://wg21.link/P0754R2>`__","LWG","<version>","Jacksonville","|Complete|","7.0"
+"`P0809R0 <https://wg21.link/P0809R0>`__","LWG","Comparing Unordered Containers","Jacksonville","|Nothing To Do|",""
+"`P0858R0 <https://wg21.link/P0858R0>`__","LWG","Constexpr iterator requirements","Jacksonville","",""
+"`P0905R1 <https://wg21.link/P0905R1>`__","CWG","Symmetry for spaceship","Jacksonville","",""
+"`P0966R1 <https://wg21.link/P0966R1>`__","LWG","``string::reserve``\  Should Not Shrink","Jacksonville","|Complete| [#note-P0966]_","12.0"
+"","","","","",""
+"`P0019R8 <https://wg21.link/P0019R8>`__","LWG","Atomic Ref","Rapperswil","",""
+"`P0458R2 <https://wg21.link/P0458R2>`__","LWG","Checking for Existence of an Element in Associative Containers","Rapperswil","|Complete|","13.0"
+"`P0475R1 <https://wg21.link/P0475R1>`__","LWG","LWG 2511: guaranteed copy elision for piecewise construction","Rapperswil","|Complete|",""
+"`P0476R2 <https://wg21.link/P0476R2>`__","LWG","Bit-casting object representations","Rapperswil","",""
+"`P0528R3 <https://wg21.link/P0528R3>`__","CWG","The Curious Case of Padding Bits, Featuring Atomic Compare-and-Exchange","Rapperswil","",""
+"`P0542R5 <https://wg21.link/P0542R5>`__","CWG","Support for contract based programming in C++","Rapperswil","*Removed in Cologne*","n/a"
+"`P0556R3 <https://wg21.link/P0556R3>`__","LWG","Integral power-of-2 operations","Rapperswil","|Complete|","9.0"
+"`P0619R4 <https://wg21.link/P0619R4>`__","LWG","Reviewing Deprecated Facilities of C++17 for C++20","Rapperswil","|Partial| [#note-P0619]_",""
+"`P0646R1 <https://wg21.link/P0646R1>`__","LWG","Improving the Return Value of Erase-Like Algorithms","Rapperswil","|Complete|","10.0"
+"`P0722R3 <https://wg21.link/P0722R3>`__","CWG","Efficient sized delete for variable sized classes","Rapperswil","|Complete|","9.0"
+"`P0758R1 <https://wg21.link/P0758R1>`__","LWG","Implicit conversion traits and utility functions","Rapperswil","|Complete|",""
+"`P0759R1 <https://wg21.link/P0759R1>`__","LWG","fpos Requirements","Rapperswil","|Complete|","11.0"
+"`P0769R2 <https://wg21.link/P0769R2>`__","LWG","Add shift to <algorithm>","Rapperswil","|Complete|","12.0"
+"`P0788R3 <https://wg21.link/P0788R3>`__","LWG","Standard Library Specification in a Concepts and Contracts World","Rapperswil","*Removed in Cologne*","n/a"
+"`P0879R0 <https://wg21.link/P0879R0>`__","LWG","Constexpr for swap and swap related functions Also resolves LWG issue 2800.","Rapperswil","|Complete|","13.0"
+"`P0887R1 <https://wg21.link/P0887R1>`__","LWG","The identity metafunction","Rapperswil","|Complete|","8.0"
+"`P0892R2 <https://wg21.link/P0892R2>`__","CWG","explicit(bool)","Rapperswil","",""
+"`P0898R3 <https://wg21.link/P0898R3>`__","LWG","Standard Library Concepts","Rapperswil","|Complete|","13.0"
+"`P0935R0 <https://wg21.link/P0935R0>`__","LWG","Eradicating unnecessarily explicit default constructors from the standard library","Rapperswil","|Complete|","12.0"
+"`P0941R2 <https://wg21.link/P0941R2>`__","CWG","Integrating feature-test macros into the C++ WD","Rapperswil","|In Progress|",""
+"`P1023R0 <https://wg21.link/P1023R0>`__","LWG","constexpr comparison operators for std::array","Rapperswil","|Complete|","8.0"
+"`P1025R1 <https://wg21.link/P1025R1>`__","CWG","Update The Reference To The Unicode Standard","Rapperswil","",""
+"`P1120R0 <https://wg21.link/P1120R0>`__","CWG","Consistency improvements for <=> and other comparison operators","Rapperswil","",""
+"","","","","",""
+"`P0318R1 <https://wg21.link/P0318R1>`__","LWG","unwrap_ref_decay and unwrap_reference","San Diego","|Complete|","8.0"
+"`P0356R5 <https://wg21.link/P0356R5>`__","LWG","Simplified partial function application","San Diego","|Complete|","13.0"
+"`P0357R3 <https://wg21.link/P0357R3>`__","LWG","reference_wrapper for incomplete types","San Diego","|Complete|","8.0"
+"`P0482R6 <https://wg21.link/P0482R6>`__","CWG","char8_t: A type for UTF-8 characters and strings","San Diego","|In Progress|",""
+"`P0487R1 <https://wg21.link/P0487R1>`__","LWG","Fixing ``operator>>(basic_istream&, CharT*)``\  (LWG 2499)","San Diego","|Complete|","8.0"
+"`P0591R4 <https://wg21.link/P0591R4>`__","LWG","Utility functions to implement uses-allocator construction","San Diego","* *",""
+"`P0595R2 <https://wg21.link/P0595R2>`__","CWG","P0595R2 std::is_constant_evaluated()","San Diego","|Complete|","9.0"
+"`P0602R4 <https://wg21.link/P0602R4>`__","LWG","variant and optional should propagate copy/move triviality","San Diego","|Complete|","8.0"
+"`P0608R3 <https://wg21.link/P0608R3>`__","LWG","A sane variant converting constructor","San Diego","|Complete|","9.0"
+"`P0655R1 <https://wg21.link/P0655R1>`__","LWG","visit<R>: Explicit Return Type for visit","San Diego","|Complete|","12.0"
+"`P0771R1 <https://wg21.link/P0771R1>`__","LWG","std::function move constructor should be noexcept","San Diego","|Complete|","6.0"
+"`P0896R4 <https://wg21.link/P0896R4>`__","LWG","The One Ranges Proposal","San Diego","|In Progress|",""
+"`P0899R1 <https://wg21.link/P0899R1>`__","LWG","P0899R1 - LWG 3016 is not a defect","San Diego","|Nothing To Do|",""
+"`P0919R3 <https://wg21.link/P0919R3>`__","LWG","Heterogeneous lookup for unordered containers","San Diego","|Complete|","12.0"
+"`P0972R0 <https://wg21.link/P0972R0>`__","LWG","<chrono> ``zero()``\ , ``min()``\ , and ``max()``\  should be noexcept","San Diego","|Complete|","8.0"
+"`P1006R1 <https://wg21.link/P1006R1>`__","LWG","Constexpr in std::pointer_traits","San Diego","|Complete|","8.0"
+"`P1007R3 <https://wg21.link/P1007R3>`__","LWG","``std::assume_aligned``\ ","San Diego","* *",""
+"`P1020R1 <https://wg21.link/P1020R1>`__","LWG","Smart pointer creation with default initialization","San Diego","* *",""
+"`P1032R1 <https://wg21.link/P1032R1>`__","LWG","Misc constexpr bits","San Diego","|Complete|","13.0"
+"`P1085R2 <https://wg21.link/P1085R2>`__","LWG","Should Span be Regular?","San Diego","|Complete|","8.0"
+"`P1123R0 <https://wg21.link/P1123R0>`__","LWG","Editorial Guidance for merging P0019r8 and P0528r3","San Diego","* *",""
+"`P1148R0 <https://wg21.link/P1148R0>`__","LWG","Cleaning up Clause 20","San Diego","* *",""
+"`P1165R1 <https://wg21.link/P1165R1>`__","LWG","Make stateful allocator propagation more consistent for ``operator+(basic_string)``\ ","San Diego","* *",""
+"`P1209R0 <https://wg21.link/P1209R0>`__","LWG","Adopt Consistent Container Erasure from Library Fundamentals 2 for C++20","San Diego","|Complete|","8.0"
+"`P1210R0 <https://wg21.link/P1210R0>`__","LWG","Completing the Rebase of Library Fundamentals, Version 3, Working Draft","San Diego","* *",""
+"`P1236R1 <https://wg21.link/P1236R1>`__","CWG","Alternative Wording for P0907R4 Signed Integers are Two's Complement","San Diego","* *",""
+"`P1248R1 <https://wg21.link/P1248R1>`__","LWG","Remove CommonReference requirement from StrictWeakOrdering (a.k.a Fixing Relations)","San Diego","|Complete|","13.0"
+"`P1285R0 <https://wg21.link/P1285R0>`__","LWG","Improving Completeness Requirements for Type Traits","San Diego","* *",""
+"`P1353R0 <https://wg21.link/P1353R0>`__","CWG","Missing feature test macros","San Diego","* *",""
+"","","","","",""
+"`P0339R6 <https://wg21.link/P0339R6>`__","LWG","polymorphic_allocator<> as a vocabulary type","Kona","",""
+"`P0340R3 <https://wg21.link/P0340R3>`__","LWG","Making std::underlying_type SFINAE-friendly","Kona","|Complete|","9.0"
+"`P0738R2 <https://wg21.link/P0738R2>`__","LWG","I Stream, You Stream, We All Stream for istream_iterator","Kona","",""
+"`P0811R3 <https://wg21.link/P0811R3>`__","LWG","Well-behaved interpolation for numbers and pointers","Kona","|Complete|","9.0"
+"`P0920R2 <https://wg21.link/P0920R2>`__","LWG","Precalculated hash values in lookup","Kona","Reverted by `P1661 <https://wg21.link/P1661>`__",""
+"`P1001R2 <https://wg21.link/P1001R2>`__","LWG","Target Vectorization Policies from Parallelism V2 TS to C++20","Kona","",""
+"`P1024R3 <https://wg21.link/P1024R3>`__","LWG","Usability Enhancements for std::span","Kona","|Complete|","9.0"
+"`P1164R1 <https://wg21.link/P1164R1>`__","LWG","Make create_directory() Intuitive","Kona","|Complete|","12.0"
+"`P1227R2 <https://wg21.link/P1227R2>`__","LWG","Signed ssize() functions, unsigned size() functions","Kona","|Complete|","9.0"
+"`P1252R2 <https://wg21.link/P1252R2>`__","LWG","Ranges Design Cleanup","Kona","",""
+"`P1286R2 <https://wg21.link/P1286R2>`__","CWG","Contra CWG DR1778","Kona","",""
+"`P1357R1 <https://wg21.link/P1357R1>`__","LWG","Traits for [Un]bounded Arrays","Kona","|Complete|","9.0"
+"`P1458R1 <https://wg21.link/P1458R1>`__","LWG","Mandating the Standard Library: Clause 16 - Language support library","Kona","|Complete|","9.0"
+"`P1459R1 <https://wg21.link/P1459R1>`__","LWG","Mandating the Standard Library: Clause 18 - Diagnostics library","Kona","|Complete|","9.0"
+"`P1462R1 <https://wg21.link/P1462R1>`__","LWG","Mandating the Standard Library: Clause 20 - Strings library","Kona","|Complete|","9.0"
+"`P1463R1 <https://wg21.link/P1463R1>`__","LWG","Mandating the Standard Library: Clause 21 - Containers library","Kona","",""
+"`P1464R1 <https://wg21.link/P1464R1>`__","LWG","Mandating the Standard Library: Clause 22 - Iterators library","Kona","|Complete|","9.0"
+"","","","","",""
+"`P0325 <https://wg21.link/P0325>`__","LWG","to_array from LFTS with updates","Cologne","|Complete|","10.0"
+"`P0408 <https://wg21.link/P0408>`__","LWG","Efficient Access to basic_stringbuf's Buffer","Cologne","",""
+"`P0466 <https://wg21.link/P0466>`__","LWG","Layout-compatibility and Pointer-interconvertibility Traits","Cologne","",""
+"`P0553 <https://wg21.link/P0553>`__","LWG","Bit operations","Cologne","|Complete|","9.0"
+"`P0631 <https://wg21.link/P0631>`__","LWG","Math Constants","Cologne","|Complete|","11.0"
+"`P0645 <https://wg21.link/P0645>`__","LWG","Text Formatting","Cologne","|In Progress|",""
+"`P0660 <https://wg21.link/P0660>`__","LWG","Stop Token and Joining Thread, Rev 10","Cologne","",""
+"`P0784 <https://wg21.link/P0784>`__","CWG","More constexpr containers","Cologne","|Complete|","12.0"
+"`P0980 <https://wg21.link/P0980>`__","LWG","Making std::string constexpr","Cologne","",""
+"`P1004 <https://wg21.link/P1004>`__","LWG","Making std::vector constexpr","Cologne","",""
+"`P1035 <https://wg21.link/P1035>`__","LWG","Input Range Adaptors","Cologne","",""
+"`P1065 <https://wg21.link/P1065>`__","LWG","Constexpr INVOKE","Cologne","|Complete|","12.0"
+"`P1135 <https://wg21.link/P1135>`__","LWG","The C++20 Synchronization Library","Cologne","|Complete|","11.0"
+"`P1207 <https://wg21.link/P1207>`__","LWG","Movability of Single-pass Iterators","Cologne","",""
+"`P1208 <https://wg21.link/P1208>`__","LWG","Adopt source_location for C++20","Cologne","",""
+"`P1355 <https://wg21.link/P1355>`__","LWG","Exposing a narrow contract for ceil2","Cologne","|Complete|","9.0"
+"`P1361 <https://wg21.link/P1361>`__","LWG","Integration of chrono with text formatting","Cologne","",""
+"`P1423 <https://wg21.link/P1423>`__","LWG","char8_t backward compatibility remediation","Cologne","|In Progress|",""
+"`P1424 <https://wg21.link/P1424>`__","LWG","'constexpr' feature macro concerns","Cologne","Superseded by `P1902 <https://wg21.link/P1902>`__",""
+"`P1466 <https://wg21.link/P1466>`__","LWG","Miscellaneous minor fixes for chrono","Cologne","",""
+"`P1474 <https://wg21.link/P1474>`__","LWG","Helpful pointers for ContiguousIterator","Cologne","",""
+"`P1502 <https://wg21.link/P1502>`__","LWG","Standard library header units for C++20","Cologne","",""
+"`P1522 <https://wg21.link/P1522>`__","LWG","Iterator Difference Type and Integer Overflow","Cologne","",""
+"`P1523 <https://wg21.link/P1523>`__","LWG","Views and Size Types","Cologne","",""
+"`P1612 <https://wg21.link/P1612>`__","LWG","Relocate Endian's Specification","Cologne","|Complete|","10.0"
+"`P1614 <https://wg21.link/P1614>`__","LWG","The Mothership has Landed","Cologne","|In Progress|",""
+"`P1638 <https://wg21.link/P1638>`__","LWG","basic_istream_view::iterator should not be copyable","Cologne","",""
+"`P1643 <https://wg21.link/P1643>`__","LWG","Add wait/notify to atomic_ref","Cologne","",""
+"`P1644 <https://wg21.link/P1644>`__","LWG","Add wait/notify to atomic<shared_ptr>","Cologne","",""
+"`P1650 <https://wg21.link/P1650>`__","LWG","Output std::chrono::days with 'd' suffix","Cologne","",""
+"`P1651 <https://wg21.link/P1651>`__","LWG","bind_front should not unwrap reference_wrapper","Cologne","|Complete|","13.0"
+"`P1652 <https://wg21.link/P1652>`__","LWG","Printf corner cases in std::format","Cologne","",""
+"`P1661 <https://wg21.link/P1661>`__","LWG","Remove dedicated precalculated hash lookup interface","Cologne","|Nothing To Do|",""
+"`P1754 <https://wg21.link/P1754>`__","LWG","Rename concepts to standard_case for C++20, while we still can","Cologne","|In Progress|",""
+"","","","","",""
+"`P0883 <https://wg21.link/P0883>`__","LWG","Fixing Atomic Initialization","Belfast","|Complete| [#note-P0883]_","13.0"
+"`P1391 <https://wg21.link/P1391>`__","LWG","Range constructor for std::string_view","Belfast","* *",""
+"`P1394 <https://wg21.link/P1394>`__","LWG","Range constructor for std::span","Belfast","* *",""
+"`P1456 <https://wg21.link/P1456>`__","LWG","Move-only views","Belfast","* *",""
+"`P1622 <https://wg21.link/P1622>`__","LWG","Mandating the Standard Library: Clause 32 - Thread support library","Belfast","* *",""
+"`P1645 <https://wg21.link/P1645>`__","LWG","constexpr for numeric algorithms","Belfast","|Complete|","12.0"
+"`P1664 <https://wg21.link/P1664>`__","LWG","reconstructible_range - a concept for putting ranges back together","Belfast","* *",""
+"`P1686 <https://wg21.link/P1686>`__","LWG","Mandating the Standard Library: Clause 27 - Time library","Belfast","* *",""
+"`P1690 <https://wg21.link/P1690>`__","LWG","Refinement Proposal for P0919 Heterogeneous lookup for unordered containers","Belfast","|Complete|","12.0"
+"`P1716 <https://wg21.link/P1716>`__","LWG","ranges compare algorithm are over-constrained","Belfast","* *",""
+"`P1718 <https://wg21.link/P1718>`__","LWG","Mandating the Standard Library: Clause 25 - Algorithms library","Belfast","* *",""
+"`P1719 <https://wg21.link/P1719>`__","LWG","Mandating the Standard Library: Clause 26 - Numerics library","Belfast","* *",""
+"`P1720 <https://wg21.link/P1720>`__","LWG","Mandating the Standard Library: Clause 28 - Localization library","Belfast","* *",""
+"`P1721 <https://wg21.link/P1721>`__","LWG","Mandating the Standard Library: Clause 29 - Input/Output library","Belfast","* *",""
+"`P1722 <https://wg21.link/P1722>`__","LWG","Mandating the Standard Library: Clause 30 - Regular Expression library","Belfast","* *",""
+"`P1723 <https://wg21.link/P1723>`__","LWG","Mandating the Standard Library: Clause 31 - Atomics library","Belfast","* *",""
+"`P1855 <https://wg21.link/P1855>`__","LWG","Make ``<compare>``\  freestanding","Belfast","* *",""
+"`P1862 <https://wg21.link/P1862>`__","LWG","Ranges adaptors for non-copyable iterators","Belfast","* *",""
+"`P1865 <https://wg21.link/P1865>`__","LWG","Add max() to latch and barrier","Belfast","|Complete|","11.0"
+"`P1869 <https://wg21.link/P1869>`__","LWG","Rename 'condition_variable_any' interruptible wait methods","Belfast","* *",""
+"`P1870 <https://wg21.link/P1870>`__","LWG","forwarding-range is too subtle","Belfast","|In Progress|",""
+"`P1871 <https://wg21.link/P1871>`__","LWG","Should concepts be enabled or disabled?","Belfast","* *",""
+"`P1872 <https://wg21.link/P1872>`__","LWG","span should have size_type, not index_type","Belfast","|Complete|","10.0"
+"`P1878 <https://wg21.link/P1878>`__","LWG","Constraining Readable Types","Belfast","* *",""
+"`P1892 <https://wg21.link/P1892>`__","LWG","Extended locale-specific presentation specifiers for std::format","Belfast","* *",""
+"`P1902 <https://wg21.link/P1902>`__","LWG","Missing feature-test macros 2018-2019","Belfast","* *",""
+"`P1959 <https://wg21.link/P1959>`__","LWG","Remove std::weak_equality and std::strong_equality","Belfast","* *",""
+"`P1960 <https://wg21.link/P1960>`__","LWG","NB Comment Changes Reviewed by SG1","Belfast","* *",""
+"`P1961 <https://wg21.link/P1961>`__","LWG","Harmonizing the definitions of total order for pointers","Belfast","* *",""
+"`P1965 <https://wg21.link/P1965>`__","LWG","Blanket Wording for Specifying ""Hidden Friends""","Belfast","* *",""
+"","","","","",""
+"`P0586 <https://wg21.link/P0586>`__","LWG","Safe integral comparisons","Prague","|Complete|","13.0"
+"`P0593 <https://wg21.link/P0593>`__","CWG","Implicit creation of objects for low-level object manipulation","Prague","* *",""
+"`P1115 <https://wg21.link/P1115>`__","LWG","Improving the Return Value of Erase-Like Algorithms II: Free erase/erase if","Prague","|Complete|","11.0"
+"`P1243 <https://wg21.link/P1243>`__","LWG","Rangify New Algorithms","Prague","* *",""
+"`P1460 <https://wg21.link/P1460>`__","LWG","Mandating the Standard Library: Clause 20 - Utilities library","Prague","* *",""
+"`P1739 <https://wg21.link/P1739>`__","LWG","Avoid template bloat for safe_ranges in combination with ""subrange-y"" view adaptors","Prague","* *",""
+"`P1831 <https://wg21.link/P1831>`__","LWG","Deprecating volatile: library","Prague","* *",""
+"`P1868 <https://wg21.link/P1868>`__","LWG","width: clarifying units of width and precision in std::format","Prague","* *",""
+"`P1908 <https://wg21.link/P1908>`__","CWG","Reserving Attribute Namespaces for Future Use","Prague","* *",""
+"`P1937 <https://wg21.link/P1937>`__","CWG","Fixing inconsistencies between constexpr and consteval functions","Prague","* *",""
+"`P1956 <https://wg21.link/P1956>`__","LWG","On the names of low-level bit manipulation functions","Prague","|Complete|","12.0"
+"`P1957 <https://wg21.link/P1957>`__","CWG","Converting from ``T*``\  to bool should be considered narrowing (re: US 212)","Prague","* *",""
+"`P1963 <https://wg21.link/P1963>`__","LWG","Fixing US 313","Prague","* *",""
+"`P1964 <https://wg21.link/P1964>`__","LWG","Wording for boolean-testable","Prague","|Complete|","13.0"
+"`P1970 <https://wg21.link/P1970>`__","LWG","Consistency for size() functions: Add ranges::ssize","Prague","* *",""
+"`P1973 <https://wg21.link/P1973>`__","LWG","Rename ""_default_init"" Functions, Rev1","Prague","* *",""
+"`P1976 <https://wg21.link/P1976>`__","LWG","Fixed-size span construction from dynamic range","Prague","|Complete|","11.0"
+"`P1981 <https://wg21.link/P1981>`__","LWG","Rename leap to leap_second","Prague","* *",""
+"`P1982 <https://wg21.link/P1982>`__","LWG","Rename link to time_zone_link","Prague","* *",""
+"`P1983 <https://wg21.link/P1983>`__","LWG","Wording for GB301, US296, US292, US291, and US283","Prague","* *",""
+"`P1994 <https://wg21.link/P1994>`__","LWG","elements_view needs its own sentinel","Prague","* *",""
+"`P2002 <https://wg21.link/P2002>`__","CWG","Defaulted comparison specification cleanups","Prague","* *",""
+"`P2045 <https://wg21.link/P2045>`__","LWG","Missing Mandates for the standard library","Prague","* *",""
+"`P2085 <https://wg21.link/P2085>`__","CWG","Consistent defaulted comparisons","Prague","* *",""
+"`P2091 <https://wg21.link/P2091>`__","LWG","Issues with range access CPOs","Prague","* *",""
+"`P2101 <https://wg21.link/P2101>`__","LWG","'Models' subsumes 'satisfies' (Wording for US298 and US300)","Prague","* *",""
+"`P2102 <https://wg21.link/P2102>`__","LWG","Make 'implicit expression variations' more explicit (Wording for US185)","Prague","* *",""
+"`P2106 <https://wg21.link/P2106>`__","LWG","Alternative wording for GB315 and GB316","Prague","* *",""
+"`P2116 <https://wg21.link/P2116>`__","LWG","Remove tuple-like protocol support from fixed-extent span","Prague","|Complete|","11.0"
+"`P2231 <https://wg21.link/P2231>`__","LWG","Missing constexpr in std::optional and std::variant","February 2021","|In progress|","13.0"
+"`P2325 <https://wg21.link/P2325>`__","LWG","Views should not be required to be default constructible","June 2021","|In progress|",""
+"`P2210R2 <https://wg21.link/P2210R2>`__","LWG",Superior String Splitting,"June 2021","",""
+"`P2216R3 <https://wg21.link/P2216R3>`__","LWG",std::format improvements,"June 2021","",""
+"`P2281R1 <https://wg21.link/P2281R1>`__","LWG",Clarifying range adaptor objects,"June 2021","",""
+"`P2328R1 <https://wg21.link/P2328R1>`__","LWG",join_view should join all views of ranges,"June 2021","",""
+"`P2367R0 <https://wg21.link/P2367R0>`__","LWG",Remove misuses of list-initialization from Clause 24,"June 2021","",""
\ No newline at end of file
diff --git a/docs/Status/Cxx2b.rst b/docs/Status/Cxx2b.rst
new file mode 100644
index 0000000..cdd1b9c
--- /dev/null
+++ b/docs/Status/Cxx2b.rst
@@ -0,0 +1,50 @@
+.. _cxx2b-status:

+

+================================

+libc++ C++2b Status

+================================

+

+.. include:: ../Helpers/Styles.rst

+

+.. contents::

+   :local:

+

+

+Overview

+================================

+

+In November 2020, the C++ standard committee adopted the first changes to the next version of the C++ standard, known here as "C++2b" (probably to be C++23).

+

+This page shows the status of libc++; the status of clang's support of the language features is `here <https://clang.llvm.org/cxx_status.html#cxx23>`__.

+

+.. attention:: Features in unreleased drafts of the standard are subject to change.

+

+The groups that have contributed papers:

+

+-  CWG - Core Language Working group

+-  LWG - Library working group

+-  SG1 - Study group #1 (Concurrency working group)

+

+.. note:: "Nothing to do" means that no library changes were needed to implement this change.

+

+.. _paper-status-cxx2b:

+

+Paper Status

+====================================

+

+.. csv-table::

+   :file: Cxx2bPapers.csv

+   :header-rows: 1

+   :widths: auto

+

+.. _issues-status-cxx2b:

+

+Library Working Group Issues Status

+====================================

+

+.. csv-table::

+   :file: Cxx2bIssues.csv

+   :header-rows: 1

+   :widths: auto

+

+Last Updated: 22-July-2021

diff --git a/docs/Status/Cxx2bIssues.csv b/docs/Status/Cxx2bIssues.csv
new file mode 100644
index 0000000..3e745c5
--- /dev/null
+++ b/docs/Status/Cxx2bIssues.csv
@@ -0,0 +1,99 @@
+"Issue #","Issue Name","Meeting","Status","First released version"
+"`2839 <https://wg21.link/LWG2839>`__","Self-move-assignment of library types, again","November 2020","",""
+"`3117 <https://wg21.link/LWG3117>`__","Missing ``packaged_task`` deduction guides","November 2020","",""
+"`3143 <https://wg21.link/LWG3143>`__","``monotonic_buffer_resource`` growth policy is unclear","November 2020","",""
+"`3195 <https://wg21.link/LWG3195>`__","What is the stored pointer value of an empty weak_ptr?","November 2020","",""
+"`3211 <https://wg21.link/LWG3211>`__","``std::tuple<>`` should be trivially constructible","November 2020","",""
+"`3236 <https://wg21.link/LWG3236>`__","Random access iterator requirements lack limiting relational operators domain to comparing those from the same range","November 2020","",""
+"`3265 <https://wg21.link/LWG3265>`__","``move_iterator``'s conversions are more broken after P1207","November 2020","Fixed by `LWG3435 <https://wg21.link/LWG3435>`__",""
+"`3435 <https://wg21.link/LWG3435>`__","``three_way_comparable_with<reverse_iterator<int*>, reverse_iterator<const int*>>``","November 2020","|Complete|","13.0"
+"`3432 <https://wg21.link/LWG3432>`__","Missing requirement for comparison_category","November 2020","",""
+"`3447 <https://wg21.link/LWG3447>`__","Deduction guides for ``take_view`` and ``drop_view`` have different constraints","November 2020","",""
+"`3450 <https://wg21.link/LWG3450>`__","The const overloads of ``take_while_view::begin/end`` are underconstrained","November 2020","",""
+"`3464 <https://wg21.link/LWG3464>`__","``istream::gcount()`` can overflow","November 2020","",""
+"`2731 <https://wg21.link/LWG2731>`__","Existence of ``lock_guard<MutexTypes...>::mutex_type`` typedef unclear","November 2020","",""
+"`2743 <https://wg21.link/LWG2743>`__","P0083R3 ``node_handle`` private members missing ""exposition only"" comment","November 2020","",""
+"`2820 <https://wg21.link/LWG2820>`__","Clarify ``<cstdint>`` macros","November 2020","",""
+"`3120 <https://wg21.link/LWG3120>`__","Unclear behavior of ``monotonic_buffer_resource::release()``","November 2020","",""
+"`3170 <https://wg21.link/LWG3170>`__","``is_always_equal`` added to ``std::allocator`` makes the standard library treat derived types as always equal","November 2020","",""
+"`3036 <https://wg21.link/LWG3036>`__","``polymorphic_allocator::destroy`` is extraneous","November 2020","",""
+"`3171 <https://wg21.link/LWG3171>`__","LWG2989 breaks ``directory_entry`` stream insertion","November 2020","",""
+"`3306 <https://wg21.link/LWG3306>`__","``ranges::advance`` violates its preconditions","November 2020","",""
+"`3403 <https://wg21.link/LWG3403>`__","Domain of ``ranges::ssize(E)`` doesn't ``match ranges::size(E)``","November 2020","",""
+"`3404 <https://wg21.link/LWG3404>`__","Finish removing subrange's conversions from pair-like","November 2020","",""
+"`3405 <https://wg21.link/LWG3405>`__","``common_view``'s converting constructor is bad, too","November 2020","",""
+"`3406 <https://wg21.link/LWG3406>`__","``elements_view::begin()`` and ``elements_view::end()`` have incompatible constraints","November 2020","",""
+"`3419 <https://wg21.link/LWG3419>`__","[algorithms.requirements]/15 doesn't reserve as many rights as it intends to","November 2020","",""
+"`3420 <https://wg21.link/LWG3420>`__","cpp17-iterator should check that the type looks like an iterator first","November 2020","",""
+"`3421 <https://wg21.link/LWG3421>`__","Imperfect ADL emulation for boolean-testable","November 2020","",""
+"`3425 <https://wg21.link/LWG3425>`__","``condition_variable_any`` fails to constrain its Lock parameters","November 2020","",""
+"`3426 <https://wg21.link/LWG3426>`__","``operator<=>(const unique_ptr<T, D>&, nullptr_t)`` can't get no satisfaction","November 2020","",""
+"`3427 <https://wg21.link/LWG3427>`__","``operator<=>(const shared_ptr<T>&, nullptr_t)`` definition ill-formed","November 2020","",""
+"`3428 <https://wg21.link/LWG3428>`__","``single_view``'s in place constructor should be explicit","November 2020","",""
+"`3434 <https://wg21.link/LWG3434>`__","``ios_base`` never reclaims memory for iarray and parray","November 2020","",""
+"`3437 <https://wg21.link/LWG3437>`__","``__cpp_lib_polymorphic_allocator`` is in the wrong header","November 2020","",""
+"`3446 <https://wg21.link/LWG3446>`__","``indirectly_readable_traits`` ambiguity for types with both ``value_type`` and ``element_type``","November 2020","",""
+"`3448 <https://wg21.link/LWG3448>`__","``transform_view``'s sentinel<false> not comparable with ``iterator<true>``","November 2020","",""
+"`3449 <https://wg21.link/LWG3449>`__","take_view and take_while_view's ``sentinel<false>`` not comparable with their const iterator","November 2020","",""
+"`3453 <https://wg21.link/LWG3453>`__","Generic code cannot call ``ranges::advance(i, s)``","November 2020","",""
+"`3455 <https://wg21.link/LWG3455>`__","Incorrect Postconditions on ``unique_ptr`` move assignment","November 2020","|Nothing To Do|",""
+"`3460 <https://wg21.link/LWG3460>`__","Unimplementable ``noop_coroutine_handle`` guarantees","November 2020","",""
+"`3461 <https://wg21.link/LWG3461>`__","``convertible_to``'s description mishandles cv-qualified void","November 2020","",""
+"`3465 <https://wg21.link/LWG3465>`__","compare_partial_order_fallback requires ``F < E``","November 2020","",""
+"`3466 <https://wg21.link/LWG3466>`__","Specify the requirements for ``promise``/``future``/``shared_future`` consistently","November 2020","",""
+"`3467 <https://wg21.link/LWG3467>`__","``bool`` can't be an integer-like type","November 2020","",""
+"`3472 <https://wg21.link/LWG3472>`__","``counted_iterator`` is missing preconditions","November 2020","",""
+"`3473 <https://wg21.link/LWG3473>`__","Normative encouragement in non-normative note","November 2020","",""
+"`3474 <https://wg21.link/LWG3474>`__","Nesting ``join_views`` is broken because of CTAD","November 2020","",""
+"`3476 <https://wg21.link/LWG3476>`__","``thread`` and ``jthread`` constructors require that the parameters be move-constructible but never move construct the parameters","November 2020","",""
+"`3477 <https://wg21.link/LWG3477>`__","Simplify constraints for semiregular-box","November 2020","",""
+"`3482 <https://wg21.link/LWG3482>`__","``drop_view``'s const begin should additionally require sized_range","November 2020","",""
+"`3483 <https://wg21.link/LWG3483>`__","``transform_view::iterator``'s difference is overconstrained","November 2020","",""
+"","","","",""
+"`3391 <https://wg21.link/LWG3391>`__","Problems with ``counted_iterator``/``move_iterator::base() const &``","February 2021","",""
+"`3433 <https://wg21.link/LWG3433>`__","``subrange::advance(n)`` has UB when ``n < 0``","February 2021","",""
+"`3490 <https://wg21.link/LWG3490>`__","``ranges::drop_while_view::begin()`` is missing a precondition","February 2021","",""
+"`3492 <https://wg21.link/LWG3492>`__","Minimal improvements to ``elements_view::iterator``","February 2021","",""
+"`3494 <https://wg21.link/LWG3494>`__","Allow ranges to be conditionally borrowed","February 2021","Superseded by `P2017R1 <https://wg21.link/P2017R1>`__",""
+"`3495 <https://wg21.link/LWG3495>`__","``constexpr launder`` makes pointers to inactive members of unions usable","February 2021","",""
+"`3500 <https://wg21.link/LWG3500>`__","``join_view::iterator::operator->()`` is bogus","February 2021","",""
+"`3502 <https://wg21.link/LWG3502>`__","``elements_view`` should not be allowed to return dangling reference","February 2021","",""
+"`3505 <https://wg21.link/LWG3505>`__","``split_view::outer-iterator::operator++`` misspecified","February 2021","",""
+"","","","",""
+`2774 <https://wg21.link/LWG2774>`__,"``std::function`` construction vs assignment","June 2021","",""
+`2818 <https://wg21.link/LWG2818>`__,"``::std::`` everywhere rule needs tweaking","June 2021","",""
+`2997 <https://wg21.link/LWG2997>`__,"LWG 491 and the specification of ``{forward_,}list::unique``","June 2021","",""
+`3410 <https://wg21.link/LWG3410>`__,"``lexicographical_compare_three_way`` is overspecified","June 2021","",""
+`3430 <https://wg21.link/LWG3430>`__,"``std::fstream`` & co. should be constructible from string_view","June 2021","",""
+`3462 <https://wg21.link/LWG3462>`__,"§[formatter.requirements]: Formatter requirements forbid use of ``fc.arg()``","June 2021","",""
+`3481 <https://wg21.link/LWG3481>`__,"``viewable_range`` mishandles lvalue move-only views","June 2021","",""
+`3506 <https://wg21.link/LWG3506>`__,"Missing allocator-extended constructors for ``priority_queue``","June 2021","",""
+`3517 <https://wg21.link/LWG3517>`__,"``join_view::iterator``'s ``iter_swap`` is underconstrained","June 2021","",""
+`3518 <https://wg21.link/LWG3518>`__,"Exception requirements on char trait operations unclear","June 2021","",""
+`3519 <https://wg21.link/LWG3519>`__,"Incomplete synopses for <random> classes","June 2021","",""
+`3520 <https://wg21.link/LWG3520>`__,"``iter_move`` and ``iter_swap`` are inconsistent for ``transform_view::iterator``","June 2021","",""
+`3521 <https://wg21.link/LWG3521>`__,"Overly strict requirements on ``qsort`` and ``bsearch``","June 2021","",""
+`3522 <https://wg21.link/LWG3522>`__,"Missing requirement on ``InputIterator`` template parameter for ``priority_queue`` constructors","June 2021","",""
+`3523 <https://wg21.link/LWG3523>`__,"``iota_view::sentinel`` is not always ``iota_view``'s sentinel","June 2021","",""
+`3526 <https://wg21.link/LWG3526>`__,"Return types of ``uses_allocator_construction_args`` unspecified","June 2021","",""
+`3527 <https://wg21.link/LWG3527>`__,"``uses_allocator_construction_args`` handles rvalue pairs of rvalue references incorrectly","June 2021","",""
+`3528 <https://wg21.link/LWG3528>`__,"``make_from_tuple`` can perform (the equivalent of) a C-style cast","June 2021","",""
+`3529 <https://wg21.link/LWG3529>`__,"``priority_queue(first, last)`` should construct ``c`` with ``(first, last)``","June 2021","",""
+`3530 <https://wg21.link/LWG3530>`__,"``BUILTIN-PTR-MEOW`` should not opt the type out of syntactic checks","June 2021","",""
+`3532 <https://wg21.link/LWG3532>`__,"``split_view<V, P>::inner-iterator<true>::operator++(int)`` should depend on ``Base``","June 2021","",""
+`3533 <https://wg21.link/LWG3533>`__,"Make ``base() const &`` consistent across iterator wrappers that supports ``input_iterators``","June 2021","",""
+`3536 <https://wg21.link/LWG3536>`__,"Should ``chrono::from_stream()`` assign zero to duration for failure?","June 2021","",""
+`3539 <https://wg21.link/LWG3539>`__,"``format_to`` must not copy models of ``output_iterator<const charT&>``","June 2021","",""
+`3540 <https://wg21.link/LWG3540>`__,"§[format.arg] There should be no const in ``basic_format_arg(const T* p)``","June 2021","",""
+`3541 <https://wg21.link/LWG3541>`__,"``indirectly_readable_traits`` should be SFINAE-friendly for all types","June 2021","",""
+`3542 <https://wg21.link/LWG3542>`__,"``basic_format_arg`` mishandles ``basic_string_view`` with custom traits","June 2021","",""
+`3543 <https://wg21.link/LWG3543>`__,"Definition of when ``counted_iterators`` refer to the same sequence isn't quite right","June 2021","",""
+`3544 <https://wg21.link/LWG3544>`__,"``format-arg-store::args`` is unintentionally not exposition-only","June 2021","",""
+`3546 <https://wg21.link/LWG3546>`__,"``common_iterator``'s postfix-proxy is not quite right","June 2021","",""
+`3548 <https://wg21.link/LWG3548>`__,"``shared_ptr`` construction from ``unique_ptr`` should move (not copy) the deleter","June 2021","",""
+`3549 <https://wg21.link/LWG3549>`__,"``view_interface`` is overspecified to derive from ``view_base``","June 2021","",""
+`3551 <https://wg21.link/LWG3551>`__,"``borrowed_{iterator,subrange}_t`` are overspecified","June 2021","",""
+`3552 <https://wg21.link/LWG3552>`__,"Parallel specialized memory algorithms should require forward iterators","June 2021","",""
+`3553 <https://wg21.link/LWG3553>`__,"Useless constraint in ``split_view::outer-iterator::value_type::begin()``","June 2021","",""
+`3555 <https://wg21.link/LWG3555>`__,"``{transform,elements}_view::iterator::iterator_concept`` should consider const-qualification of the underlying range","June 2021","",""
+"","","","",""
diff --git a/docs/Status/Cxx2bPapers.csv b/docs/Status/Cxx2bPapers.csv
new file mode 100644
index 0000000..4df0bfc
--- /dev/null
+++ b/docs/Status/Cxx2bPapers.csv
@@ -0,0 +1,25 @@
+"Paper #","Group","Paper Name","Meeting","Status","First released version"
+"`P0881R7 <https://wg21.link/P0881R7>`__","LWG","A Proposal to add stacktrace library","Autumn 2020","",""
+"`P0943R6 <https://wg21.link/P0943R6>`__","LWG","Support C atomics in C++","Autumn 2020","",""
+"`P1048R1 <https://wg21.link/P1048R1>`__","LWG","A proposal for a type trait to detect scoped enumerations","Autumn 2020","|Complete|","12.0"
+"`P1679R3 <https://wg21.link/P1679R3>`__","LWG","string contains function","Autumn 2020","|Complete|","12.0"
+"","","","","",""
+"`P1682R3 <https://wg21.link/P1682R3>`__","LWG","std::to_underlying for enumerations","February 2021","|Complete|","13.0"
+"`P2017R1 <https://wg21.link/P2017R1>`__","LWG","Conditionally borrowed ranges","February 2021","",""
+"`P2160R1 <https://wg21.link/P2160R1>`__","LWG","Locks lock lockables","February 2021","",""
+"`P2162R2 <https://wg21.link/P2162R2>`__","LWG","Inheriting from std::variant","February 2021","|Complete|","13.0"
+"`P2212R2 <https://wg21.link/P2212R2>`__","LWG","Relax Requirements for time_point::clock","February 2021","",""
+"`P2259R1 <https://wg21.link/P2259R1>`__","LWG","Repairing input range adaptors and counted_iterator","February 2021","",""
+"","","","","",""
+"`P0401R6 <https://wg21.link/P0401R6>`__","LWG","Providing size feedback in the Allocator interface","June 2021","",
+"`P0448R4 <https://wg21.link/P0448R4>`__","LWG","A strstream replacement using span<charT> as buffer","June 2021","",""
+"`P1132R8 <https://wg21.link/P1132R8>`__","LWG","out_ptr - a scalable output pointer abstraction","June 2021","",""
+"`P1328R1 <https://wg21.link/P1328R1>`__","LWG","Making std::type_info::operator== constexpr","June 2021","",""
+"`P1425R4 <https://wg21.link/P1425R4>`__","LWG","Iterators pair constructors for stack and queue","June 2021","",""
+"`P1518R2 <https://wg21.link/P1518R2>`__","LWG","Stop overconstraining allocators in container deduction guides","June 2021","|Complete|","13.0"
+"`P1659R3 <https://wg21.link/P1659R3>`__","LWG","starts_with and ends_with","June 2021","",""
+"`P1951R1 <https://wg21.link/P1951R1>`__","LWG","Default Arguments for pair Forwarding Constructor","June 2021","",""
+"`P1989R2 <https://wg21.link/P1989R2>`__","LWG","Range constructor for std::string_view","June 2021","",""
+"`P2136R3 <https://wg21.link/P2136R3>`__","LWG","invoke_r","June 2021","",""
+"`P2166R1 <https://wg21.link/P2166R1>`__","LWG","A Proposal to Prohibit std::basic_string and std::basic_string_view construction from nullptr","June 2021","|Complete|","13.0"
+"","","","","",""
\ No newline at end of file
diff --git a/docs/Status/Format.rst b/docs/Status/Format.rst
new file mode 100644
index 0000000..948b1b7
--- /dev/null
+++ b/docs/Status/Format.rst
@@ -0,0 +1,53 @@
+.. format-status:
+
+================================
+libc++ Format Status
+================================
+
+.. include:: ../Helpers/Styles.rst
+
+.. contents::
+   :local:
+
+
+Overview
+========
+
+This document contains the status of the C++20 Format library in libc++. It is used to
+track both the status of the sub-projects of the Format library and who is assigned to
+these sub-projects. This is imperative to effective implementation so that work is not
+duplicated and implementors are not blocked by each other.
+
+
+If you are interested in contributing to the libc++ Format library, please send
+a message to the #libcxx channel in the LLVM discord. Please *do not* start
+working on any of the assigned items below.
+
+
+Sub-Projects in the Format library
+==================================
+
+.. csv-table::
+   :file: FormatPaper.csv
+   :header-rows: 1
+   :widths: auto
+
+
+Misc. Items and TODOs
+=====================
+
+(Please mark all Format-related TODO comments with the string ``TODO FMT``, so we
+can find them easily.)
+
+    * C++23 may break the ABI with `P2216 <https://wg21.link/P2216>`_.
+      This ABI break may be backported to C++20. Therefore the library will not
+      be available on platforms where the ABI break is an issue.
+
+
+Paper and Issue Status
+======================
+
+.. csv-table::
+   :file: FormatIssues.csv
+   :header-rows: 1
+   :widths: auto
diff --git a/docs/Status/FormatIssues.csv b/docs/Status/FormatIssues.csv
new file mode 100644
index 0000000..7f4218d
--- /dev/null
+++ b/docs/Status/FormatIssues.csv
@@ -0,0 +1,31 @@
+Number,Name,Assignee,Patch,Status,First released version
+`P0645 <https://wg21.link/P0645>`_,"Text Formatting",Mark de Wever,,|partial|,
+`P1652 <https://wg21.link/P1652>`_,"Printf corner cases in std::format",Mark de Wever,`D103433 <https://reviews.llvm.org/D103433>`__,Review,
+`P1892 <https://wg21.link/P1892>`_,"Extended locale-specific presentation specifiers for std::format",Mark de Wever,`D103368 <https://reviews.llvm.org/D103368>`__,Review,
+`P1868 <https://wg21.link/P1868>`_,"width: clarifying units of width and precision in std::format (Implements the unicode support.)",Mark de Wever,"`D103413 <https://reviews.llvm.org/D103413>`__ `D103425 <https://reviews.llvm.org/D103425>`__ `D103670 <https://reviews.llvm.org/D103670>`__",Review,
+`P2216 <https://wg21.link/P2216>`_,"std::format improvements",,,,
+`LWG-3242 <https://wg21.link/LWG3242>`_,"std::format: missing rules for arg-id in width and precision",Mark de Wever,`D103368 <https://reviews.llvm.org/D103368>`__,Review,
+`LWG-3243 <https://wg21.link/LWG3243>`_,"std::format and negative zeroes",,,,
+`LWG-3246 <https://wg21.link/LWG3246>`_,"What are the constraints on the template parameter of basic_format_arg?",,,,
+`LWG-3248 <https://wg21.link/LWG3248>`_,"std::format #b, #B, #o, #x, and #X presentation types misformat negative numbers",Mark de Wever,`D103433 <https://reviews.llvm.org/D103433>`__,Review,
+`LWG-3250 <https://wg21.link/LWG3250>`_,"std::format: # (alternate form) for NaN and inf",,,,
+`LWG-3327 <https://wg21.link/LWG3327>`_,"Format alignment specifiers vs. text direction",,,|Nothing To Do|,
+`LWG-3340 <https://wg21.link/LWG3340>`_,"Formatting functions should throw on argument/format string mismatch in [format.functions]",,,,
+`LWG-3371 <https://wg21.link/LWG3371>`_,"visit_format_arg and make_format_args are not hidden friends",Mark de Wever,`D103357 <https://llvm.org/D103357>`__,Review,
+`LWG-3372 <https://wg21.link/LWG3372>`_,"vformat_to should not try to deduce Out twice",,,,
+`LWG-3373 <https://wg21.link/LWG3373>`_,"{to,from}_chars_result and format_to_n_result need the 'we really mean what we say'",,,,
+`LWG-3462 <https://wg21.link/LWG3462>`_,"§[formatter.requirements]: Formatter requirements forbid use of fc.arg()",,,,
+`LWG-3539 <https://wg21.link/LWG3539>`_,"format_to must not copy models of output_iterator<const charT&>",,,,
+`LWG-3540 <https://wg21.link/LWG3540>`_,"§[format.arg] There should be no const in basic_format_arg(const T* p)",,,,
+`LWG-3541 <https://wg21.link/LWG3541>`_,"indirectly_readable_traits should be SFINAE-friendly for all types",,,,
+`LWG-3542 <https://wg21.link/LWG3542>`_,"basic_format_arg mishandles basic_string_view with custom traits",,,,
+`LWG-3544 <https://wg21.link/LWG3544>`_,"format-arg-store::args is unintentionally not exposition-only",,,,
+
+`P1361 <https://wg21.link/P1361>`_,"Integration of chrono with text formatting",,,,
+`LWG-3218 <https://wg21.link/LWG3218>`_,"Modifier for %d parse flag does not match POSIX and format specification",,,,
+`LWG-3230 <https://wg21.link/LWG3230>`_,"Format specifier %y/%Y is missing locale alternative versions",,,,
+`LWG-3241 <https://wg21.link/LWG3241>`_,"chrono-spec grammar ambiguity in [time.format]",,,,
+`LWG-3262 <https://wg21.link/LWG3262>`_,"Formatting of negative durations is not specified",,,,
+`LWG-3270 <https://wg21.link/LWG3270>`_,"Parsing and formatting %j with durations",,,,
+`LWG-3272 <https://wg21.link/LWG3272>`_,"%I%p should parse/format duration since midnight",,,,
+`LWG-3332 <https://wg21.link/LWG3332>`_,"Issue in [time.format]",,,,
diff --git a/docs/Status/FormatPaper.csv b/docs/Status/FormatPaper.csv
new file mode 100644
index 0000000..afdf883
--- /dev/null
+++ b/docs/Status/FormatPaper.csv
@@ -0,0 +1,48 @@
+Section,Description,Dependencies,Assignee,Patch,Status,First released version
+[charconv.to.chars],"Fix integral conformance",,Mark de Wever,`D100722 <https://llvm.org/D100722>`__,|Complete|,Clang 13
+[charconv.to.chars],"Add floating-point conversion",`D100722 <https://llvm.org/D100722>`__,"Mark de Wever (Code provided by Stephan T. Lavavej of Microsoft)",`D70631 <https://llvm.org/D70631>`__,In progress,
+[format.error],"Class format_error",,Mark de Wever,`D92214 <https://llvm.org/D92214>`__,|Complete|,Clang 13
+[format.parse.ctx],"Class template basic_format_parse_context",,Mark de Wever,`D93166 <https://llvm.org/D93166>`__,|Complete|,Clang 13
+[format.context],"Class template basic_format_context",,Mark de Wever,`D103357 <https://llvm.org/D103357>`__,Review,
+[format.args],"Class template basic_format_args",,Mark de Wever,`D103357 <https://llvm.org/D103357>`__,Review,
+[format.arg],"Class template basic_format_arg",,Mark de Wever,`D103357 <https://llvm.org/D103357>`__,Review,
+[format.arg],"Class template basic_format_arg - handle",,,,,,
+[format.arg],"Class template basic_format_arg - pointers",,,,,,
+[format.arg.store],"Class template format-arg-store",,Mark de Wever,`D103357 <https://llvm.org/D103357>`__,Review,
+[format.formatter.spec],"Formatter specializations - character types",,Mark de Wever,"`D96664 <https://llvm.org/D96664>`__ `D103466 <https://llvm.org/D103466>`__",Review,
+[format.formatter.spec],"Formatter specializations - string types",,Mark de Wever,"`D96664 <https://llvm.org/D96664>`__ `D103425 <https://reviews.llvm.org/D103425>`__",Review,
+[format.formatter.spec],"Formatter specializations - boolean type",,Mark de Wever,"`D96664 <https://llvm.org/D96664>`__ `D103670 <https://reviews.llvm.org/D103670>`__",Review,
+[format.formatter.spec],"Formatter specializations - integral types",,Mark de Wever,"`D96664 <https://llvm.org/D96664>`__ `D103433 <https://reviews.llvm.org/D103433>`__",Review,
+[format.formatter.spec],"Formatter specializations - floating-point types",`D70631 <https://llvm.org/D70631>`__,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.formatter.spec],"Formatter specializations - pointer types",,,,,,
+[format.string.std],"Standard format specifiers - character types",,Mark de Wever,`D103368 <https://reviews.llvm.org/D103368>`__,Review,
+[format.string.std],"Standard format specifiers - string types",`D103379 <https://reviews.llvm.org/D103379>`__,Mark de Wever,"`D103368 <https://reviews.llvm.org/D103368>`__ `D103413 <https://reviews.llvm.org/D103413>`__",Review,
+[format.string.std],"Standard format specifiers - boolean type",`D103379 <https://reviews.llvm.org/D103379>`__,Mark de Wever,"`D103368 <https://reviews.llvm.org/D103368>`__ `D103413 <https://reviews.llvm.org/D103413>`__",Review,
+[format.string.std],"Standard format specifiers - integral types",,Mark de Wever,`D103368 <https://reviews.llvm.org/D103368>`__,Review,
+[format.string.std],"Standard format specifiers - floating-point types",,Mark de Wever,,,,
+[format.string.std],"Standard format specifiers - pointer types",,Mark de Wever,,,,
+[format.functions],"Format functions - format(string_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - format(wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - format(const locale& loc, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - format(const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - vformat(string_view fmt, format_args args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - vformat(wstring_view fmt, wformat_args args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - vformat(const locale& loc, string_view fmt, format_args args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - vformat(const locale& loc, wstring_view fmt, wformat_args args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - format_to(Out out, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - vformat_to(Out out, string_view fmt, format_args_t<type_identity_t<Out>, char> args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - vformat_to(Out out, wstring_view fmt, format_args_t<type_identity_t<Out>, char> args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - vformat_to(Out out, const locale& loc, string_view fmt, format_args_t<type_identity_t<Out>, char> args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - vformat_to(Out out, const locale& loc, wstring_view fmt,format_args_t<type_identity_t<Out>, wchar_t> args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - format_to_n(Out out, iter_difference_t<Out> n, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - format_to_n(Out out, iter_difference_t<Out> n, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, const locale& loc, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - formatted_size(string_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - formatted_size(wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - formatted_size(const locale& loc, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - formatted_size(const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 <https://llvm.org/D96664>`__,Review,
+[format.functions],"Format functions - Implement locale support",,Mark de Wever,,In progress,,
+[format.functions],"Format functions - Improve performance format_to_n",,Mark de Wever,,,,
+[format.functions],"Format functions - Improve performance formatted size",,Mark de Wever,,,,
diff --git a/docs/Status/Ranges.rst b/docs/Status/Ranges.rst
new file mode 100644
index 0000000..66b2ba3
--- /dev/null
+++ b/docs/Status/Ranges.rst
@@ -0,0 +1,51 @@
+.. ranges-status:
+
+================================
+libc++ Ranges Status
+================================
+
+.. include:: ../Helpers/Styles.rst
+
+.. contents::
+   :local:
+
+
+Overview
+================================
+
+This document contains the status of the C++20 Ranges library in libc++. It is used to
+track both the status of the sub-projects of the ranges library and who is assigned to
+these sub-projects. This is imperative to effective implementation so that work is not
+duplicated and implementors are not blocked by each other.
+
+If you are interested in contributing to the libc++ Ranges library, please send a message
+to the #libcxx channel in the LLVM discord. Please *do not* start working on any of the
+assigned items below.
+
+
+Sub-Projects in the One Ranges Proposal
+=======================================
+
+.. csv-table::
+   :file: RangesPaper.csv
+   :header-rows: 1
+   :widths: auto
+
+
+Misc. Items and TODOs
+====================================
+
+(Note: files with required updates will contain the TODO at the beginning of the list item
+so they can be easily found via global search.)
+
+    * TODO(XX_SPACESHIP_CONCEPTS): when spaceship support is added to various STL types, we need to update some concept tests.
+
+Paper and Issue Status
+====================================
+
+(Note: stolen from MSVC `here <https://github.com/microsoft/STL/issues/39>`_.)
+
+.. csv-table::
+   :file: RangesIssues.csv
+   :header-rows: 1
+   :widths: auto
\ No newline at end of file
diff --git a/docs/Status/RangesIssues.csv b/docs/Status/RangesIssues.csv
new file mode 100644
index 0000000..4cd6c3d
--- /dev/null
+++ b/docs/Status/RangesIssues.csv
@@ -0,0 +1,80 @@
+"Number","Name","Status","Assignee"
+`P0896R4 <https://wg21.link/P0896R4>`__,<ranges>,,
+`P1035R7 <https://wg21.link/P1035R7>`__,Input Range Adaptors,,
+`P1207R4 <https://wg21.link/P1207R4>`__,Movability Of Single-Pass Iterators,,
+`P1243R4 <https://wg21.link/P1243R4>`__,Rangify New Algorithms,,
+`P1248R1 <https://wg21.link/P1248R1>`__,Fixing Relations,,
+`P1252R2 <https://wg21.link/P1252R2>`__,Ranges Design Cleanup,,
+`P1391R4 <https://wg21.link/P1391R4>`__,Range Constructor For string_view,,
+`P1456R1 <https://wg21.link/P1456R1>`__,Move-Only Views,,
+`P1474R1 <https://wg21.link/P1474R1>`__,Helpful Pointers For contiguous_iterator,,
+`P1522R1 <https://wg21.link/P1522R1>`__,Iterator Difference Type And Integer Overflow,,
+`P1523R1 <https://wg21.link/P1523R1>`__,Views And Size Types,,
+`P1638R1 <https://wg21.link/P1638R1>`__,basic_istream_view::iterator Should Not Be Copyable,,
+`P1716R3 <https://wg21.link/P1716R3>`__,Range Comparison Algorithms Are Over-Constrained,,
+`P1739R4 <https://wg21.link/P1739R4>`__,Avoiding Template Bloat For Ranges,,
+`P1862R1 <https://wg21.link/P1862R1>`__,Range Adaptors For Non-Copyable Iterators,,
+`P1870R1 <https://wg21.link/P1870R1>`__,safe_range,,
+`P1871R1 <https://wg21.link/P1871R1>`__,disable_sized_sentinel_for,,
+`P1878R1 <https://wg21.link/P1878R1>`__,Constraining Readable Types,,
+`P1970R2 <https://wg21.link/P1970R2>`__,ranges::ssize,,
+`P1983R0 <https://wg21.link/P1983R0>`__,Fixing Minor Ranges Issues,,
+`P1994R1 <https://wg21.link/P1994R1>`__,elements_view Needs Its Own sentinel,,
+`P2091R0 <https://wg21.link/P2091R0>`__,Fixing Issues With Range Access CPOs,,
+`P2106R0 <https://wg21.link/P2106R0>`__,Range Algorithm Result Types,,
+
+`P2325R3 <https://wg21.link/P2325R3>`__,Views should not be required to be default constructible ,,
+`P2328R1 <https://wg21.link/P2328R1>`__,join_view should join all views of ranges,,
+`P2210R2 <https://wg21.link/P2210R2>`__,Superior String Splitting,,
+`P2281R1 <https://wg21.link/P2281R1>`__,Clarifying range adaptor objects,,
+`P2367R0 <https://wg21.link/P2367R0>`__,Remove misuses of list-initialization from Clause 24,,
+
+`LWG3169 <https://wg21.link/lwg3169>`__, ranges permutation generators discard useful information,,
+`LWG3173 <https://wg21.link/lwg3173>`__, Enable CTAD for ref-view,,
+`LWG3179 <https://wg21.link/lwg3179>`__, subrange should always model Range,,
+`LWG3180 <https://wg21.link/lwg3180>`__, Inconsistently named return type for ranges::minmax_element,,
+`LWG3183 <https://wg21.link/lwg3183>`__, Normative permission to specialize Ranges variable templates,,
+`LWG3186 <https://wg21.link/lwg3186>`__, "ranges removal, partition, and partial_sort_copy algorithms discard useful information",,
+`LWG3191 <https://wg21.link/lwg3191>`__, std::ranges::shuffle synopsis does not match algorithm definition,,
+`LWG3276 <https://wg21.link/lwg3276>`__, Class split_view::outer_iterator::value_type should inherit from view_interface,,
+`LWG3280 <https://wg21.link/lwg3280>`__, View converting constructors can cause constraint recursion and are unneeded,,
+`LWG3281 <https://wg21.link/lwg3281>`__, Conversion from pair-like types to subrange is a silent semantic promotion,,
+`LWG3282 <https://wg21.link/lwg3282>`__, subrange converting constructor should disallow derived to base conversions,,
+`LWG3286 <https://wg21.link/lwg3286>`__, ranges::size is not required to be valid after a call to ranges::begin on an input range,,
+`LWG3291 <https://wg21.link/lwg3291>`__, iota_view::iterator has the wrong iterator_category,,
+`LWG3292 <https://wg21.link/lwg3292>`__, iota_view is under-constrained,,
+`LWG3299 <https://wg21.link/lwg3299>`__, Pointers don't need customized iterator behavior,,
+`LWG3301 <https://wg21.link/lwg3301>`__, transform_view::iterator has incorrect iterator_category,,
+`LWG3302 <https://wg21.link/lwg3302>`__, Range adaptor objects keys and values are unspecified,,
+`LWG3313 <https://wg21.link/lwg3313>`__, join_view::iterator::operator-- is incorrectly constrained,,
+`LWG3323 <https://wg21.link/lwg3323>`__, has-tuple-element helper concept needs convertible_to,,
+`LWG3325 <https://wg21.link/lwg3325>`__, Constrain return type of transformation function for transform_view,,
+`LWG3335 <https://wg21.link/lwg3335>`__, range_size_t and views::all_t,,
+`LWG3355 <https://wg21.link/lwg3355>`__, The memory algorithms should support move-only input iterators introduced by P1207,,
+`LWG3363 <https://wg21.link/lwg3363>`__, drop_while_view should opt-out of sized_range,,
+`LWG3364 <https://wg21.link/lwg3364>`__, Initialize data members of ranges and their iterators,,
+`LWG3381 <https://wg21.link/lwg3381>`__, begin and data must agree for contiguous_range,,
+`LWG3384 <https://wg21.link/lwg3384>`__, transform_view::sentinel has an incorrect operator-,,
+`LWG3385 <https://wg21.link/lwg3385>`__, common_iterator is not sufficiently constrained for non-copyable iterators,,
+`LWG3387 <https://wg21.link/lwg3387>`__, [range.reverse.view] reverse_view<V> unintentionally requires range<const V>,,
+`LWG3388 <https://wg21.link/lwg3388>`__, view iterator types have ill-formed <=> operators,,
+`LWG3389 <https://wg21.link/lwg3389>`__, A move-only iterator still does not have a counted_iterator,,
+`LWG3397 <https://wg21.link/lwg3397>`__, ranges::basic_istream_view::iterator should not provide iterator_category,,
+`LWG3398 <https://wg21.link/lwg3398>`__, tuple_element_t is also wrong for const subrange,,
+`LWG3474 <https://wg21.link/lwg3474>`__, Nesting join_views is broken because of CTAD,,
+`LWG3481 <https://wg21.link/LWG3481>`__,"viewable_range mishandles lvalue move-only views",,
+`LWG3500 <https://wg21.link/lwg3500>`__, join_view::iterator::operator->() is bogus,,
+`LWG3505 <https://wg21.link/lwg3505>`__, split_view::outer-iterator::operator++ misspecified,,
+`LWG3517 <https://wg21.link/LWG3517>`__,"join_view::iterator's iter_swap is underconstrained",,
+`LWG3520 <https://wg21.link/LWG3520>`__,"iter_move and iter_swap are inconsistent for transform_view::iterator",,
+`LWG3522 <https://wg21.link/LWG3522>`__,"Missing requirement on InputIterator template parameter for priority_queue constructors",,
+`LWG3523 <https://wg21.link/LWG3523>`__,"iota_view::sentinel is not always iota_view's sentinel",,
+`LWG3532 <https://wg21.link/LWG3532>`__,"split_view<V, P>::inner-iterator<true>::operator++(int) should depend on Base",,
+`LWG3533 <https://wg21.link/LWG3533>`__,"Make base() const & consistent across iterator wrappers that supports input_iterators",,
+`LWG3541 <https://wg21.link/LWG3541>`__,"indirectly_readable_traits should be SFINAE-friendly for all types",,
+`LWG3543 <https://wg21.link/LWG3543>`__,"Definition of when counted_iterators refer to the same sequence isn't quite right",,
+`LWG3546 <https://wg21.link/LWG3546>`__,"common_iterator's postfix-proxy is not quite right",,
+`LWG3549 <https://wg21.link/LWG3549>`__,"view_interface is overspecified to derive from view_base",,
+`LWG3551 <https://wg21.link/LWG3551>`__,"borrowed_{iterator,subrange}_t are overspecified",,
+`LWG3553 <https://wg21.link/LWG3553>`__,"Useless constraint in split_view::outer-iterator::value_type::begin()",,
+`LWG3555 <https://wg21.link/LWG3555>`__,"{transform,elements}_view::iterator::iterator_concept should consider const-qualification of the underlying range",,
diff --git a/docs/Status/RangesPaper.csv b/docs/Status/RangesPaper.csv
new file mode 100644
index 0000000..a7d2897
--- /dev/null
+++ b/docs/Status/RangesPaper.csv
@@ -0,0 +1,149 @@
+Section,Description,Dependencies,Assignee,Complete
+[tuple.helper],Update <tuple> includes.,None,Unassigned,Not started
+`[range.cmp] <http://wg21.link/range.cmp>`_,"| `ranges::equal_to <https://llvm.org/D100429>`_
+| `ranges::not_equal_to <https://llvm.org/D100429>`_
+| `ranges::less <https://llvm.org/D100429>`_
+| `ranges::greater <https://llvm.org/D100429>`_
+| `ranges::less_equal <https://llvm.org/D100429>`_
+| `ranges::greater_equal <https://llvm.org/D100429>`_",None,Zoe Carver,✅
+`[readable.traits] <http://wg21.link/readable.traits>`_,"| `indirectly_readable_traits <https://llvm.org/D99461>`_
+| `iter_value_t <https://llvm.org/D99863>`_",None,Christopher Di Bella,✅
+`[incrementable.traits] <http://wg21.link/incrementable.traits>`_,"| `incrementable_traits <https://llvm.org/D99141>`_
+| `iter_difference_t <https://llvm.org/D99863>`_",,Christopher Di Bella,✅
+`[iterator.traits] <http://wg21.link/iterator.traits>`_,`Updates to iterator_traits <https://llvm.org/D99855>`_,"| indirectly_readable_traits
+| incrementable_traits",Christopher Di Bella,✅
+`[special.mem.concepts] <http://wg21.link/special.mem.concepts>`_,"| *no-throw-input-iterator*
+| *no-throw-sentinel-for*
+| *no-throw-input-range*
+| *no-throw-forward-iterator*
+| *no-throw-forward-range*","| [iterator.concepts]
+| [range.refinements]",Unassigned,Not started
+`[specialized.algorithms] <http://wg21.link/specialized.algorithms>`_,"| ranges::uninitialized_default_construct
+| ranges::uninitialized_default_construct_n
+| ranges::uninitialized_value_construct
+| ranges::uninitialized_value_construct_n
+| ranges::uninitialized_copy
+| ranges::uninitialized_copy_n
+| ranges::uninitialized_move
+| ranges::uninitialized_move_n
+| ranges::uninitialized_fill
+| ranges::uninitialized_fill_n
+| ranges::construct_at
+| ranges::destroy
+| ranges::destroy_at
+| ranges::destroy_n",[special.mem.concepts],Unassigned,Not started
+[strings],Adds begin/end and updates const_iterator.,[iterator.concepts],Unassigned,Not started
+[views.span],Same as [strings],[iterator.concepts],Unassigned,Not started
+`[iterator.cust.move] <http://wg21.link/iterator.cust.move>`_,`ranges::iter_move <https://llvm.org/D99873>`_,,Zoe Carver,✅
+`[iterator.cust.swap] <http://wg21.link/iterator.cust.swap>`_,`ranges::iter_swap <https://llvm.org/D102809>`_,iter_value_t,Zoe Carver,✅
+`[iterator.concepts] <http://wg21.link/iterator.concepts>`_,"| `indirectly_readable <https://llvm.org/D100073>`_
+| `indirectly_writable <https://llvm.org/D100073>`_
+| `weakly_incrementable <https://llvm.org/D100080>`_
+| `incrementable <https://llvm.org/D100080>`_
+| `input_or_output_iterator <https://llvm.org/D100160>`_
+| `sentinel_for <https://llvm.org/D100160>`_
+| `sized_sentinel_for <https://llvm.org/D101371>`_
+| `input_iterator <https://llvm.org/D100271>`_
+| `output_iterator <https://llvm.org/D106704>`_
+| `forward_iterator <https://llvm.org/D100275>`_
+| `bidirectional_iterator <https://llvm.org/D100278>`_
+| `random_access_iterator <https://llvm.org/D101316>`_
+| `contiguous_iterator <https://llvm.org/D101396>`_",,Various,✅
+`[indirectcallable.indirectinvocable] <http://wg21.link/indirectcallable.indirectinvocable>`_,"| indirectly_unary_invocable
+| `indirectly_regular_unary_invocable <https://llvm.org/D101277>`_
+| `indirectly_unary_predicate <https://llvm.org/D101277>`_
+| `indirectly_binary_predicate <https://llvm.org/D101277>`_
+| `indirectly_equivalence_relation <https://llvm.org/D101277>`_
+| `indirectly_strict_weak_order <https://llvm.org/D101277>`_",[readable.traits],Louis Dionne,✅
+`[projected] <http://wg21.link/projected>`_,`ranges::projected <https://llvm.org/D101277>`_,[iterator.concepts],Louis Dionne,✅
+`[common.alg.req] <http://wg21.link/common.alg.req>`_: pt. 1,"| `indirectly_movable <https://llvm.org/D102639>`_
+| `indirectly_movable_storable <https://llvm.org/D102639>`_
+| indirectly_copyable
+| indirectly_copyable_storable",[iterator.concepts],Zoe Carver,In progress
+[common.alg.req]: pt. 2,indirectly_swappable,"| [iterator.concepts]
+| [iterator.cust.swap]",Zoe Carver,✅
+[common.alg.req]: pt. 3,indirectly_comparable,[projected],Louis Dionne,Not started
+[common.alg.req]: pt. 4,"| permutable
+| mergeable
+| sortable",[iterator.concepts],Unassigned,Not started
+[std.iterator.tags],,[iterator.traits],Unassigned,Not started
+`[range.iter.ops] <http://wg21.link/range.iter.ops>`_,"| `ranges::advance <https://llvm.org/D101922>`_
+| `ranges::distance <https://llvm.org/D102789>`_
+| `ranges::next <https://llvm.org/D102563>`_
+| `ranges::prev <https://llvm.org/D102564>`_",[iterator.concepts],Christopher Di Bella,In progress
+[predef.iterators],Updates to predefined iterators.,"| [iterator.concepts]
+| [iterator.cust.swap]
+| [iterator.cust.move]",Unassigned,Not started
+[move.sentinel],,[predef.iterators],Unassigned,Not started
+[common.iterator],,"| [iterator.concepts]
+| [iterator.cust.swap]
+| [iterator.cust.move]",Zoe Carver,✅
+[default.sentinels],std::default_sentinel_t.,No dependencies,Zoe Carver,✅
+[counted.iterator],,"| [iterator.concepts]
+| [iterator.cust.swap]
+| [iterator.cust.move]
+| [default.sentinels]",Zoe Carver,✅
+[stream.iterators],,[default.sentinels],Unassigned,Not started
+`[range.access] <http://wg21.link/range.access>`_,"| `ranges::begin <https://llvm.org/D100255>`_
+| `ranges::end <https://llvm.org/D100255>`_
+| `range::cbegin <https://llvm.org/D100255>`_
+| `ranges::cend <https://llvm.org/D100255>`_
+| ranges::rbegin
+| ranges::rend
+| ranges::crbegin
+| ranges::crend
+| `ranges::size <https://llvm.org/D101079>`_
+| `ranges::ssize <https://llvm.org/D101189>`_
+| `ranges::empty <https://llvm.org/D101193>`_
+| `ranges::data <https://llvm.org/D101476>`_
+| ranges::cdata",[iterator.concepts],Christopher Di Bella and Zoe Carver,In progress
+`[range.range] <http://wg21.link/range.range>`_,"| `ranges::range <https://llvm.org/D100269>`_
+| `ranges::borrowed_range <https://llvm.org/D102426>`_
+| `ranges::enable_borrowed_range <https://llvm.org/D90999>`_
+| `ranges::iterator_t <https://llvm.org/D100255>`_
+| `ranges::sentinel_t <https://llvm.org/D100269>`_
+| `ranges::range_difference_t <https://llvm.org/D100269>`_
+| `ranges::range_size_t <https://llvm.org/D106708>`_
+| `ranges::range_value_t <https://llvm.org/D100269>`_
+| `ranges::range_reference_t <https://llvm.org/D100269>`_
+| `ranges::range_rvalue_reference_t <https://llvm.org/D100269>`_",[range.access],Christopher Di Bella,✅
+`[range.sized] <http://wg21.link/range.sized>`_,"| `ranges::sized_range <https://llvm.org/D102434>`_
+| `ranges::disable_sized_range <https://llvm.org/D102434>`_","| [range.primitives]
+| [range.range]",Christopher Di Bella,✅
+`[range.view] <http://wg21.link/range.view>`_,"| `ranges::enable_view <https://llvm.org/D101547>`_
+| `ranges::view_base <https://llvm.org/D101547>`_
+| `ranges::view <https://llvm.org/D101547>`_",[range.range],Louis Dionne,✅
+`[range.refinements] <http://wg21.link/range.refinements>`_,"| ranges::output_range
+| `ranges::input_range <https://llvm.org/D100271>`_
+| `ranges::forward_range: `D100275 <https://llvm.org/D100275>`_
+| `ranges::bidirectional_range <https://llvm.org/D100278>`_
+| `ranges::random_access_range <https://llvm.org/D101316>`_
+| ranges::contiguous_range
+| `ranges::common_range <https://llvm.org/D100269>`_",[range.range],Christopher Di Bella,✅
+`[range.refinements]`_,`ranges::viewable_range <https://llvm.org/D105816>`_,[range.range],Louis Dionne,✅
+`[range.utility.helpers] <http://wg21.link/range.utility.helpers>`_,"| *simple-view*
+| *has-arrow*
+| *not-same-as*","| [range.range]
+| [iterator.concept.input]",Zoe Carver,✅
+`[view.interface] <http://wg21.link/view.interface>`_,"`ranges::view_interface <https://llvm.org/D101737>`_","| [ranges.range]
+| [range.view]
+| [range.iterator.op.prev]
+| [range.refinements]",Zoe Carver,✅
+`[range.subrange] <http://wg21.link/range.subrange>`_,`ranges::subrange <https://llvm.org/D102006>`_,[view.interface],Zoe Carver,✅
+`[range.dangling] <http://wg21.link/range.dangling>`_,"| ranges::dangling
+| ranges::borrowed_iterator_t
+| ranges::borrowed_subrange_t","| [range.range]
+| [range.subrange]",Christopher Di Bella,✅
+`[range.all] <http://wg21.link/range.all>`_,`view::all <https://llvm.org/D102028>`_,"[range.subrange], [range.view.ref]",Zoe Carver,✅
+`[range.view.ref] <http://wg21.link/range.view>`_,`ref-view <https://llvm.org/D102020>`_,[view.interface],Zoe Carver,✅
+`[range.filter] <http://wg21.link/range.filter>`_,filter_view,[range.all],Louis Dionne,Not started
+`[range.transform] <http://wg21.link/range.transform>`_,`transform_view <https://llvm.org/D103056>`_,[range.all],Zoe Carver,✅
+`[range.iota] <http://wg21.link/range.iota>`_,iota_view,[range.all],Louis Dionne,Not started
+`[range.take] <http://wg21.link/range.take>`_,take_view,[range.all],Zoe Carver,In Progress
+`[range.join] <http://wg21.link/range.join>`_,join_view,[range.all],Christopher Di Bella,Not started
+`[range.empty] <http://wg21.link/range.empty>`_,`empty_view <https://llvm.org/D103208>`_,[view.interface],Zoe Carver,✅
+`[range.single] <http://wg21.link/range.single>`_,single_view,[view.interface],Zoe Carver,In Progress
+`[range.split] <http://wg21.link/range.split>`_,split_view,[range.all],Unassigned,Not started
+`[range.counted] <http://wg21.link/range.counted>`_,view::counted,[range.subrange],Zoe Carver,Not started
+`[range.common] <http://wg21.link/range.common>`_,common_view,[range.all],Zoe Carver,✅
+`[range.reverse] <http://wg21.link/range.reverse>`_,reverse_view,[range.all],Unassigned,Not started
diff --git a/docs/TestingLibcxx.rst b/docs/TestingLibcxx.rst
new file mode 100644
index 0000000..ddb8a6d
--- /dev/null
+++ b/docs/TestingLibcxx.rst
@@ -0,0 +1,263 @@
+==============
+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-cxx``.
+
+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: https://llvm.org/docs/CommandGuide/lit.html
+
+Usage
+-----
+
+After building libc++, you can run parts of the libc++ test suite by simply
+running ``llvm-lit`` on a specified test or directory. If you're unsure
+whether the required libraries have been built, you can use the
+`cxx-test-depends` target. For example:
+
+.. code-block:: bash
+
+  $ cd <monorepo-root>
+  $ make -C <build> cxx-test-depends # If you want to make sure the targets get rebuilt
+  $ <build>/bin/llvm-lit -sv libcxx/test/std/re # Run all of the std::regex tests
+  $ <build>/bin/llvm-lit -sv libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp # Run a single test
+  $ <build>/bin/llvm-lit -sv libcxx/test/std/atomics libcxx/test/std/threads # Test std::thread and std::atomic
+
+In the default configuration, the tests are built against headers that form a
+fake installation root of libc++. This installation root has to be updated when
+changes are made to the headers, so you should re-run the `cxx-test-depends`
+target before running the tests manually with `lit` when you make any sort of
+change, including to the headers.
+
+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
+
+  $ <build>/bin/llvm-lit -sv libcxx/test/std/containers # Run the tests with the newest -std
+  $ <build>/bin/llvm-lit -sv libcxx/test/std/containers --param=std=c++03 # 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
+
+  $ <build>/bin/llvm-lit -sv libcxx/test --param=compile_flags='-Wcustom-warning'
+  $ <build>/bin/llvm-lit -sv libcxx/test --param=link_flags='-L/custom/library/path'
+
+Some other common examples include:
+
+.. code-block:: bash
+
+  # Specify a custom compiler.
+  $ <build>/bin/llvm-lit -sv libcxx/test/std --param=cxx_under_test=/opt/bin/g++
+
+  # Disable warnings in the test suite
+  $ <build>/bin/llvm-lit -sv libcxx/test --param=enable_warnings=False
+
+  # Use UBSAN when running the tests.
+  $ <build>/bin/llvm-lit -sv libcxx/test --param=use_sanitizer=Undefined
+
+Using a custom site configuration
+---------------------------------
+
+By default, the libc++ test suite will use a site configuration that matches
+the current CMake configuration. It does so by generating a ``lit.site.cfg``
+file in the build directory from one of the configuration file templates in
+``libcxx/test/configs/``, and pointing ``llvm-lit`` (which is a wrapper around
+``llvm/utils/lit/lit.py``) to that file. So when you're running
+``<build>/bin/llvm-lit``, the generated ``lit.site.cfg`` file is always loaded
+instead of ``libcxx/test/lit.cfg.py``. If you want to use a custom site
+configuration, simply point the CMake build to it using
+``-DLIBCXX_TEST_CONFIG=<path-to-site-config>``, and that site configuration
+will be used instead. That file can use CMake variables inside it to make
+configuration easier.
+
+   .. code-block:: bash
+
+     $ cmake <options> -DLIBCXX_TEST_CONFIG=<path-to-site-config>
+     $ make -C <build> cxx-test-depends
+     $ <build>/bin/llvm-lit -sv libcxx/test # will use your custom config file
+
+
+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:: stdlib=<stdlib name>
+
+  **Values**: libc++, libstdc++, msvc
+
+  Specify the C++ standard library being tested. The default is libc++ if this
+  option is not provided. This option is intended to allow running the libc++
+  test suite against other standard library implementations.
+
+.. option:: std=<standard version>
+
+  **Values**: c++03, c++11, c++14, c++17, c++20, c++2b
+
+  Change the standard version used when building the tests.
+
+.. option:: cxx_headers=<path/to/headers>
+
+  Specify the c++ standard library 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.
+
+
+.. 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`.
+
+.. option:: use_system_cxx_lib=<bool>
+
+  **Default**: False
+
+  Enable or disable testing against the installed version of libc++ library.
+  This impacts whether the ``use_system_cxx_lib`` Lit feature is defined or
+  not. The ``cxx_library_root`` and ``cxx_runtime_root`` parameters should
+  still be used to specify the path of the library to link to and run against,
+  respectively.
+
+.. 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:: llvm_unwinder
+
+  Enable the use of LLVM unwinder instead of libgcc.
+
+.. option:: builtins_library
+
+  Path to the builtins library to use instead of libgcc.
+
+
+Writing Tests
+-------------
+
+When writing tests for the libc++ test suite, you should follow a few guidelines.
+This will ensure that your tests can run on a wide variety of hardware and under
+a wide variety of configurations. We have several unusual configurations such as
+building the tests on one host but running them on a different host, which add a
+few requirements to the test suite. Here's some stuff you should know:
+
+- All tests are run in a temporary directory that is unique to that test and
+  cleaned up after the test is done.
+- When a test needs data files as inputs, these data files can be saved in the
+  repository (when reasonable) and referenced by the test as
+  ``// FILE_DEPENDENCIES: <path-to-dependencies>``. Copies of these files or
+  directories will be made available to the test in the temporary directory
+  where it is run.
+- You should never hardcode a path from the build-host in a test, because that
+  path will not necessarily be available on the host where the tests are run.
+- You should try to reduce the runtime dependencies of each test to the minimum.
+  For example, requiring Python to run a test is bad, since Python is not
+  necessarily available on all devices we may want to run the tests on (even
+  though supporting Python is probably trivial for the build-host).
+
+Benchmarks
+==========
+
+Libc++ contains benchmark tests separately from the test of the test suite.
+The benchmarks are written using the `Google Benchmark`_ library, a copy of which
+is stored in the libc++ repository.
+
+For more information about using the Google Benchmark library see the
+`official documentation <https://github.com/google/benchmark>`_.
+
+.. _`Google Benchmark`: https://github.com/google/benchmark
+
+Building Benchmarks
+-------------------
+
+The benchmark tests are not built by default. The benchmarks can be built using
+the ``cxx-benchmarks`` target.
+
+An example build would look like:
+
+.. code-block:: bash
+
+  $ cd build
+  $ cmake [options] <path to libcxx sources>
+  $ make cxx-benchmarks
+
+This will build all of the benchmarks under ``<libcxx-src>/benchmarks`` to be
+built against the just-built libc++. The compiled tests are output into
+``build/benchmarks``.
+
+The benchmarks can also be built against the platforms native standard library
+using the ``-DLIBCXX_BUILD_BENCHMARKS_NATIVE_STDLIB=ON`` CMake option. This
+is useful for comparing the performance of libc++ to other standard libraries.
+The compiled benchmarks are named ``<test>.libcxx.out`` if they test libc++ and
+``<test>.native.out`` otherwise.
+
+Also See:
+
+  * :ref:`Building Libc++ <build instructions>`
+  * :ref:`CMake Options`
+
+Running Benchmarks
+------------------
+
+The benchmarks must be run manually by the user. Currently there is no way
+to run them as part of the build.
+
+For example:
+
+.. code-block:: bash
+
+  $ cd build/benchmarks
+  $ make cxx-benchmarks
+  $ ./algorithms.libcxx.out # Runs all the benchmarks
+  $ ./algorithms.libcxx.out --benchmark_filter=BM_Sort.* # Only runs the sort benchmarks
+
+For more information about running benchmarks see `Google Benchmark`_.
diff --git a/docs/UsingLibcxx.rst b/docs/UsingLibcxx.rst
new file mode 100644
index 0000000..8631236
--- /dev/null
+++ b/docs/UsingLibcxx.rst
@@ -0,0 +1,346 @@
+.. _using-libcxx:
+
+============
+Using libc++
+============
+
+.. contents::
+  :local:
+
+Usually, libc++ is packaged and shipped by a vendor through some delivery vehicle
+(operating system distribution, SDK, toolchain, etc) and users don't need to do
+anything special in order to use the library.
+
+This page contains information about configuration knobs that can be used by
+users when they know libc++ is used by their toolchain, and how to use libc++
+when it is not the default library used by their toolchain.
+
+
+Using a different version of the C++ Standard
+=============================================
+
+Libc++ implements the various versions of the C++ Standard. Changing the version of
+the standard can be done by passing ``-std=c++XY`` to the compiler. Libc++ will
+automatically detect what Standard is being used and will provide functionality that
+matches that Standard in the library.
+
+.. code-block:: bash
+
+  $ clang++ -std=c++17 test.cpp
+
+.. warning::
+  Using ``-std=c++XY`` with a version of the Standard that has not been ratified yet
+  is considered unstable. Libc++ reserves the right to make breaking changes to the
+  library until the standard has been ratified.
+
+
+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``. Note that not all
+vendors ship ``libc++experimental.a``, and as a result, you may not be
+able to use those experimental features.
+
+.. code-block:: bash
+
+  $ clang++ test.cpp -lc++experimental
+
+.. 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.
+    * When the standardized version of an experimental feature is implemented,
+      the experimental feature is removed two releases after the non-experimental
+      version has shipped. The full policy is explained :ref:`here <experimental features>`.
+
+
+Using libc++ when it is not the system default
+==============================================
+
+On systems where libc++ is provided but is not the default, Clang provides a flag
+called ``-stdlib=`` that can be used to decide which standard library is used.
+Using ``-stdlib=libc++`` will select libc++:
+
+.. code-block:: bash
+
+  $ clang++ -stdlib=libc++ test.cpp
+
+On systems where libc++ is the library in use by default such as macOS and FreeBSD,
+this flag is not required.
+
+
+.. _alternate libcxx:
+
+Using a custom built libc++
+===========================
+
+Most compilers provide a way to disable the default behavior for finding the
+standard library and to override it with custom paths. With Clang, this can
+be done with:
+
+.. code-block:: bash
+
+  $ clang++ -nostdinc++ -nostdlib++           \
+            -isystem <install>/include/c++/v1 \
+            -L <install>/lib                  \
+            -Wl,-rpath,<install>/lib          \
+            -lc++                             \
+            test.cpp
+
+The option ``-Wl,-rpath,<install>/lib`` adds a runtime library search path,
+which causes the system's dynamic linker to look for libc++ in ``<install>/lib``
+whenever the program is loaded.
+
+GCC does not support the ``-nostdlib++`` flag, so one must use ``-nodefaultlibs``
+instead. Since that removes all the standard system libraries and not just libc++,
+the system libraries must be re-added manually. For example:
+
+.. code-block:: bash
+
+  $ g++ -nostdinc++ -nodefaultlibs           \
+        -isystem <install>/include/c++/v1    \
+        -L <install>/lib                     \
+        -Wl,-rpath,<install>/lib             \
+        -lc++ -lc++abi -lm -lc -lgcc_s -lgcc \
+        test.cpp
+
+
+GDB Pretty printers for libc++
+==============================
+
+GDB does not support pretty-printing of libc++ symbols by default. However, libc++ does
+provide pretty-printers itself. Those can be used as:
+
+.. code-block:: bash
+
+  $ gdb -ex "source <libcxx>/utils/gdb/libcxx/printers.py" \
+        -ex "python register_libcxx_printer_loader()" \
+        <args>
+
+
+Libc++ Configuration Macros
+===========================
+
+Libc++ provides a number of configuration macros which can be used to enable
+or disable extended libc++ behavior, including enabling "debug mode" or
+thread safety annotations.
+
+**_LIBCPP_DEBUG**:
+  See :ref:`using-debug-mode` for more information.
+
+**_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS**:
+  This macro is used to enable -Wthread-safety annotations on libc++'s
+  ``std::mutex`` and ``std::lock_guard``. By default, these annotations are
+  disabled and must be manually enabled by the user.
+
+**_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS**:
+  This macro is used to disable all visibility annotations inside libc++.
+  Defining this macro and then building libc++ with hidden visibility gives a
+  build of libc++ which does not export any symbols, which can be useful when
+  building statically for inclusion into another library.
+
+**_LIBCPP_DISABLE_EXTERN_TEMPLATE**:
+  This macro is used to disable extern template declarations in the libc++
+  headers. The intended use case is for clients who wish to use the libc++
+  headers without taking a dependency on the libc++ library itself.
+
+**_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS**:
+  This macro disables the additional diagnostics generated by libc++ using the
+  `diagnose_if` attribute. These additional diagnostics include checks for:
+
+    * Giving `set`, `map`, `multiset`, `multimap` and their `unordered_`
+      counterparts a comparator which is not const callable.
+    * Giving an unordered associative container a hasher that is not const
+      callable.
+
+**_LIBCPP_NO_VCRUNTIME**:
+  Microsoft's C and C++ headers are fairly entangled, and some of their C++
+  headers are fairly hard to avoid. In particular, `vcruntime_new.h` gets pulled
+  in from a lot of other headers and provides definitions which clash with
+  libc++ headers, such as `nothrow_t` (note that `nothrow_t` is a struct, so
+  there's no way for libc++ to provide a compatible definition, since you can't
+  have multiple definitions).
+
+  By default, libc++ solves this problem by deferring to Microsoft's vcruntime
+  headers where needed. However, it may be undesirable to depend on vcruntime
+  headers, since they may not always be available in cross-compilation setups,
+  or they may clash with other headers. The `_LIBCPP_NO_VCRUNTIME` macro
+  prevents libc++ from depending on vcruntime headers. Consequently, it also
+  prevents libc++ headers from being interoperable with vcruntime headers (from
+  the aforementioned clashes), so users of this macro are promising to not
+  attempt to combine libc++ headers with the problematic vcruntime headers. This
+  macro also currently prevents certain `operator new`/`operator delete`
+  replacement scenarios from working, e.g. replacing `operator new` and
+  expecting a non-replaced `operator new[]` to call the replaced `operator new`.
+
+**_LIBCPP_ENABLE_NODISCARD**:
+  Allow the library to add ``[[nodiscard]]`` attributes to entities not specified
+  as ``[[nodiscard]]`` by the current language dialect. This includes
+  backporting applications of ``[[nodiscard]]`` from newer dialects and
+  additional extended applications at the discretion of the library. All
+  additional applications of ``[[nodiscard]]`` are disabled by default.
+  See :ref:`Extended Applications of [[nodiscard]] <nodiscard extension>` for
+  more information.
+
+**_LIBCPP_DISABLE_NODISCARD_EXT**:
+  This macro prevents the library from applying ``[[nodiscard]]`` to entities
+  purely as an extension. See :ref:`Extended Applications of [[nodiscard]] <nodiscard extension>`
+  for more information.
+
+**_LIBCPP_DISABLE_DEPRECATION_WARNINGS**:
+  This macro disables warnings when using deprecated components. For example,
+  using `std::auto_ptr` when compiling in C++11 mode will normally trigger a
+  warning saying that `std::auto_ptr` is deprecated. If the macro is defined,
+  no warning will be emitted. By default, this macro is not defined.
+
+C++17 Specific Configuration Macros
+-----------------------------------
+**_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES**:
+  This macro is used to re-enable all the features removed in C++17. The effect
+  is equivalent to manually defining each macro listed below.
+
+**_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR**:
+  This macro is used to re-enable `auto_ptr`.
+
+**_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS**:
+  This macro is used to re-enable the `binder1st`, `binder2nd`,
+  `pointer_to_unary_function`, `pointer_to_binary_function`, `mem_fun_t`,
+  `mem_fun1_t`, `mem_fun_ref_t`, `mem_fun1_ref_t`, `const_mem_fun_t`,
+  `const_mem_fun1_t`, `const_mem_fun_ref_t`, and `const_mem_fun1_ref_t`
+  class templates, and the `bind1st`, `bind2nd`, `mem_fun`, `mem_fun_ref`,
+  and `ptr_fun` functions.
+
+**_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE**:
+  This macro is used to re-enable the `random_shuffle` algorithm.
+
+**_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS**:
+  This macro is used to re-enable `set_unexpected`, `get_unexpected`, and
+  `unexpected`.
+
+C++20 Specific Configuration Macros:
+------------------------------------
+**_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17**:
+  This macro can be used to disable diagnostics emitted from functions marked
+  ``[[nodiscard]]`` in dialects after C++17.  See :ref:`Extended Applications of [[nodiscard]] <nodiscard extension>`
+  for more information.
+
+**_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES**:
+  This macro is used to re-enable all the features removed in C++20. The effect
+  is equivalent to manually defining each macro listed below.
+
+**_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS**:
+  This macro is used to re-enable redundant members of `allocator<T>`,
+  including `pointer`, `reference`, `rebind`, `address`, `max_size`,
+  `construct`, `destroy`, and the two-argument overload of `allocate`.
+
+**_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS**:
+  This macro is used to re-enable the `argument_type`, `result_type`,
+  `first_argument_type`, and `second_argument_type` members of class
+  templates such as `plus`, `logical_not`, `hash`, and `owner_less`.
+
+**_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS**:
+  This macro is used to re-enable `not1`, `not2`, `unary_negate`,
+  and `binary_negate`.
+
+**_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR**:
+  This macro is used to re-enable `raw_storage_iterator`.
+
+**_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS**:
+  This macro is used to re-enable `is_literal_type`, `is_literal_type_v`,
+  `result_of` and `result_of_t`.
+
+
+Libc++ Extensions
+=================
+
+This section documents various extensions provided by libc++, how they're
+provided, and any information regarding how to use them.
+
+.. _nodiscard extension:
+
+Extended applications of ``[[nodiscard]]``
+------------------------------------------
+
+The ``[[nodiscard]]`` attribute is intended to help users find bugs where
+function return values are ignored when they shouldn't be. After C++17 the
+C++ standard has started to declared such library functions as ``[[nodiscard]]``.
+However, this application is limited and applies only to dialects after C++17.
+Users who want help diagnosing misuses of STL functions may desire a more
+liberal application of ``[[nodiscard]]``.
+
+For this reason libc++ provides an extension that does just that! The
+extension must be enabled by defining ``_LIBCPP_ENABLE_NODISCARD``. The extended
+applications of ``[[nodiscard]]`` takes two forms:
+
+1. Backporting ``[[nodiscard]]`` to entities declared as such by the
+   standard in newer dialects, but not in the present one.
+
+2. Extended applications of ``[[nodiscard]]``, at the library's discretion,
+   applied to entities never declared as such by the standard.
+
+Users may also opt-out of additional applications ``[[nodiscard]]`` using
+additional macros.
+
+Applications of the first form, which backport ``[[nodiscard]]`` from a newer
+dialect, may be disabled using macros specific to the dialect in which it was
+added. For example, ``_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17``.
+
+Applications of the second form, which are pure extensions, may be disabled
+by defining ``_LIBCPP_DISABLE_NODISCARD_EXT``.
+
+
+Entities declared with ``_LIBCPP_NODISCARD_EXT``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This section lists all extended applications of ``[[nodiscard]]`` to entities
+which no dialect declares as such (See the second form described above).
+
+* ``adjacent_find``
+* ``all_of``
+* ``any_of``
+* ``binary_search``
+* ``clamp``
+* ``count_if``
+* ``count``
+* ``equal_range``
+* ``equal``
+* ``find_end``
+* ``find_first_of``
+* ``find_if_not``
+* ``find_if``
+* ``find``
+* ``get_temporary_buffer``
+* ``includes``
+* ``is_heap_until``
+* ``is_heap``
+* ``is_partitioned``
+* ``is_permutation``
+* ``is_sorted_until``
+* ``is_sorted``
+* ``lexicographical_compare``
+* ``lower_bound``
+* ``max_element``
+* ``max``
+* ``min_element``
+* ``min``
+* ``minmax_element``
+* ``minmax``
+* ``mismatch``
+* ``none_of``
+* ``remove_if``
+* ``remove``
+* ``search_n``
+* ``search``
+* ``unique``
+* ``upper_bound``
+* ``lock_guard``'s constructors
+* ``as_const``
+* ``forward``
+* ``move``
+* ``move_if_noexcept``
+* ``identity::operator()``
+* ``to_integer``
+* ``to_underlying``
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..f3c904c
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,252 @@
+# -*- 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
+from datetime import date
+
+# 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-%d, LLVM Project' % date.today().year
+
+# 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 = '13.0'
+# The full version, including alpha/beta/rc tags.
+release = '13.0'
+
+# 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', 'Helpers']
+
+# 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 configuration.
+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..c52e42b
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,220 @@
+.. _index:
+
+=============================
+"libc++" C++ Standard Library
+=============================
+
+Overview
+========
+
+libc++ is a new implementation of the C++ standard library, targeting C++11 and
+above.
+
+* 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: 1
+
+   ReleaseNotes
+   UsingLibcxx
+   BuildingLibcxx
+   TestingLibcxx
+   Contributing
+   Status/Cxx14
+   Status/Cxx17
+   Status/Cxx20
+   Status/Cxx2b
+   Status/Ranges
+   Status/Format
+
+
+.. toctree::
+    :hidden:
+
+    AddingNewCIJobs
+    FeatureTestMacroTable
+
+
+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:
+
+Platform and Compiler Support
+=============================
+
+Libc++ aims to support common compilers that implement the C++11 Standard. In order to strike a
+good balance between stability for users and maintenance cost, testing coverage and development
+velocity, libc++ drops support for older compilers as newer ones are released.
+
+============ =============== ========================== =====================
+Compiler     Versions        Restrictions               Support policy
+============ =============== ========================== =====================
+Clang        11, 12                                     latest two stable releases per `LLVM's release page <https://releases.llvm.org>`_
+AppleClang   12                                         latest stable release per `Xcode's release page <https://developer.apple.com/documentation/xcode-release-notes>`_
+GCC          11              In C++11 or later only     latest stable release per `GCC's release page <https://gcc.gnu.org/releases.html>`_
+============ =============== ========================== =====================
+
+Libc++ also supports common platforms and architectures:
+
+=============== ========================= ============================
+Target platform Target architecture       Notes
+=============== ========================= ============================
+macOS 10.9+     i386, x86_64, arm64       Building the shared library itself requires targetting macOS 10.11+
+FreeBSD 10+     i386, x86_64, arm
+Linux           i386, x86_64, arm, arm64
+Windows         x86_64
+=============== ========================= ============================
+
+Generally speaking, libc++ should work on any platform that provides a fairly complete
+C Standard Library. It is also possible to turn off parts of the library for use on
+systems that provide incomplete support.
+
+However, libc++ aims to provide a high-quality implementation of the C++ Standard
+Library, especially when it comes to correctness. As such, we aim to have test coverage
+for all the platforms and compilers that we claim to support. If a platform or compiler
+is not listed here, it is not officially supported. It may happen to work, and
+in practice the library is known to work on some platforms not listed here, but
+we don't make any guarantees. If you would like your compiler and/or platform
+to be formally supported and listed here,
+please work with the libc++ team to set up testing for your configuration.
+
+
+C++ Dialect Support
+===================
+
+* C++11 - Complete
+* :ref:`C++14 - Complete <cxx14-status>`
+* :ref:`C++17 - In Progress <cxx17-status>`
+* :ref:`C++20 - In Progress <cxx20-status>`
+* :ref:`C++2b - In Progress <cxx2b-status>`
+* :ref:`C++ Feature Test Macro Status <feature-status>`
+
+
+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.
+
+
+A full list of currently open libc++ bugs can be `found here`__.
+
+.. __:  https://bugs.llvm.org/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/ABIVersioning
+   DesignDocs/AtomicDesign
+   DesignDocs/CapturingConfigInfo
+   DesignDocs/DebugMode
+   DesignDocs/ExperimentalFeatures
+   DesignDocs/ExtendedCXX03Support
+   DesignDocs/FeatureTestMacros
+   DesignDocs/FileTimeType
+   DesignDocs/NoexceptPolicy
+   DesignDocs/ThreadingSupportAPI
+   DesignDocs/UniquePtrTrivialAbi
+   DesignDocs/VisibilityMacros
+
+
+Build Bots and Test Coverage
+============================
+
+* `Buildkite CI pipeline <https://buildkite.com/llvm-project/libcxx-ci>`_
+* `LLVM Buildbot Builders <http://lab.llvm.org:8011>`_
+* :ref:`Adding New CI Jobs <AddingNewCIJobs>`
+
+
+Getting Involved
+================
+
+First please review our `Developer's Policy <https://llvm.org/docs/DeveloperPolicy.html>`__
+and `Getting started with LLVM <https://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 `libcxx-dev mailing list`_ or on IRC.
+
+**Patches**
+
+If you want to contribute a patch to libc++, the best place for that is
+`Phabricator <https://llvm.org/docs/Phabricator.html>`_. Please add `libcxx-commits` as a subscriber.
+Also make sure you are subscribed to the `libcxx-commits mailing list <http://lists.llvm.org/mailman/listinfo/libcxx-commits>`_.
+
+**Discussion and Questions**
+
+Send discussions and questions to the
+`libcxx-dev mailing list <http://lists.llvm.org/mailman/listinfo/libcxx-dev>`_.
+
+
+Quick Links
+===========
+* `LLVM Homepage <https://llvm.org/>`_
+* `libc++abi Homepage <http://libcxxabi.llvm.org/>`_
+* `LLVM Bugzilla <https://bugs.llvm.org/>`_
+* `libcxx-commits Mailing List`_
+* `libcxx-dev Mailing List`_
+* `Browse libc++ Sources <https://github.com/llvm/llvm-project/tree/main/libcxx/>`_
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index bbf7ea4..5fba760 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -1,13 +1,442 @@
-if (NOT LIBCXX_INSTALL_SUPPORT_HEADERS)
-  set(LIBCXX_SUPPORT_HEADER_PATTERN PATTERN "support" EXCLUDE)
+set(files
+  __algorithm/adjacent_find.h
+  __algorithm/all_of.h
+  __algorithm/any_of.h
+  __algorithm/binary_search.h
+  __algorithm/clamp.h
+  __algorithm/comp_ref_type.h
+  __algorithm/comp.h
+  __algorithm/copy_backward.h
+  __algorithm/copy_if.h
+  __algorithm/copy_n.h
+  __algorithm/copy.h
+  __algorithm/count_if.h
+  __algorithm/count.h
+  __algorithm/equal_range.h
+  __algorithm/equal.h
+  __algorithm/fill_n.h
+  __algorithm/fill.h
+  __algorithm/find_end.h
+  __algorithm/find_first_of.h
+  __algorithm/find_if_not.h
+  __algorithm/find_if.h
+  __algorithm/find.h
+  __algorithm/for_each_n.h
+  __algorithm/for_each.h
+  __algorithm/generate_n.h
+  __algorithm/generate.h
+  __algorithm/half_positive.h
+  __algorithm/includes.h
+  __algorithm/inplace_merge.h
+  __algorithm/is_heap_until.h
+  __algorithm/is_heap.h
+  __algorithm/is_partitioned.h
+  __algorithm/is_permutation.h
+  __algorithm/is_sorted_until.h
+  __algorithm/is_sorted.h
+  __algorithm/iter_swap.h
+  __algorithm/lexicographical_compare.h
+  __algorithm/lower_bound.h
+  __algorithm/make_heap.h
+  __algorithm/max_element.h
+  __algorithm/max.h
+  __algorithm/merge.h
+  __algorithm/min_element.h
+  __algorithm/min.h
+  __algorithm/minmax_element.h
+  __algorithm/minmax.h
+  __algorithm/mismatch.h
+  __algorithm/move_backward.h
+  __algorithm/move.h
+  __algorithm/next_permutation.h
+  __algorithm/none_of.h
+  __algorithm/nth_element.h
+  __algorithm/partial_sort_copy.h
+  __algorithm/partial_sort.h
+  __algorithm/partition_copy.h
+  __algorithm/partition_point.h
+  __algorithm/partition.h
+  __algorithm/pop_heap.h
+  __algorithm/prev_permutation.h
+  __algorithm/push_heap.h
+  __algorithm/remove_copy_if.h
+  __algorithm/remove_copy.h
+  __algorithm/remove_if.h
+  __algorithm/remove.h
+  __algorithm/replace_copy_if.h
+  __algorithm/replace_copy.h
+  __algorithm/replace_if.h
+  __algorithm/replace.h
+  __algorithm/reverse_copy.h
+  __algorithm/reverse.h
+  __algorithm/rotate_copy.h
+  __algorithm/rotate.h
+  __algorithm/sample.h
+  __algorithm/search_n.h
+  __algorithm/search.h
+  __algorithm/set_difference.h
+  __algorithm/set_intersection.h
+  __algorithm/set_symmetric_difference.h
+  __algorithm/set_union.h
+  __algorithm/shift_left.h
+  __algorithm/shift_right.h
+  __algorithm/shuffle.h
+  __algorithm/sift_down.h
+  __algorithm/sort_heap.h
+  __algorithm/sort.h
+  __algorithm/stable_partition.h
+  __algorithm/stable_sort.h
+  __algorithm/swap_ranges.h
+  __algorithm/transform.h
+  __algorithm/unique_copy.h
+  __algorithm/unique.h
+  __algorithm/unwrap_iter.h
+  __algorithm/upper_bound.h
+  __availability
+  __bit_reference
+  __bits
+  __bsd_locale_defaults.h
+  __bsd_locale_fallbacks.h
+  __config
+  __debug
+  __errc
+  __format/format_error.h
+  __format/format_parse_context.h
+  __function_like.h
+  __functional_base
+  __functional/binary_function.h
+  __functional/binary_negate.h
+  __functional/bind_front.h
+  __functional/bind.h
+  __functional/binder1st.h
+  __functional/binder2nd.h
+  __functional/default_searcher.h
+  __functional/function.h
+  __functional/hash.h
+  __functional/identity.h
+  __functional/invoke.h
+  __functional/is_transparent.h
+  __functional/mem_fn.h
+  __functional/mem_fun_ref.h
+  __functional/not_fn.h
+  __functional/operations.h
+  __functional/perfect_forward.h
+  __functional/pointer_to_binary_function.h
+  __functional/pointer_to_unary_function.h
+  __functional/ranges_operations.h
+  __functional/reference_wrapper.h
+  __functional/unary_function.h
+  __functional/unary_negate.h
+  __functional/unwrap_ref.h
+  __functional/weak_result_type.h
+  __hash_table
+  __iterator/access.h
+  __iterator/advance.h
+  __iterator/back_insert_iterator.h
+  __iterator/common_iterator.h
+  __iterator/concepts.h
+  __iterator/counted_iterator.h
+  __iterator/data.h
+  __iterator/default_sentinel.h
+  __iterator/distance.h
+  __iterator/empty.h
+  __iterator/erase_if_container.h
+  __iterator/front_insert_iterator.h
+  __iterator/incrementable_traits.h
+  __iterator/insert_iterator.h
+  __iterator/istream_iterator.h
+  __iterator/istreambuf_iterator.h
+  __iterator/iter_move.h
+  __iterator/iter_swap.h
+  __iterator/iterator_traits.h
+  __iterator/iterator.h
+  __iterator/move_iterator.h
+  __iterator/next.h
+  __iterator/ostream_iterator.h
+  __iterator/ostreambuf_iterator.h
+  __iterator/prev.h
+  __iterator/projected.h
+  __iterator/readable_traits.h
+  __iterator/reverse_access.h
+  __iterator/reverse_iterator.h
+  __iterator/size.h
+  __iterator/wrap_iter.h
+  __libcpp_version
+  __locale
+  __memory/addressof.h
+  __memory/allocation_guard.h
+  __memory/allocator_arg_t.h
+  __memory/allocator_traits.h
+  __memory/allocator.h
+  __memory/auto_ptr.h
+  __memory/compressed_pair.h
+  __memory/construct_at.h
+  __memory/pointer_safety.h
+  __memory/pointer_traits.h
+  __memory/raw_storage_iterator.h
+  __memory/shared_ptr.h
+  __memory/temporary_buffer.h
+  __memory/uninitialized_algorithms.h
+  __memory/unique_ptr.h
+  __memory/uses_allocator.h
+  __mutex_base
+  __node_handle
+  __nullptr
+  __random/uniform_int_distribution.h
+  __ranges/access.h
+  __ranges/all.h
+  __ranges/common_view.h
+  __ranges/concepts.h
+  __ranges/copyable_box.h
+  __ranges/dangling.h
+  __ranges/data.h
+  __ranges/drop_view.h
+  __ranges/empty_view.h
+  __ranges/empty.h
+  __ranges/enable_borrowed_range.h
+  __ranges/enable_view.h
+  __ranges/non_propagating_cache.h
+  __ranges/ref_view.h
+  __ranges/size.h
+  __ranges/subrange.h
+  __ranges/transform_view.h
+  __ranges/view_interface.h
+  __split_buffer
+  __std_stream
+  __string
+  __support/android/locale_bionic.h
+  __support/fuchsia/xlocale.h
+  __support/ibm/gettod_zos.h
+  __support/ibm/limits.h
+  __support/ibm/locale_mgmt_aix.h
+  __support/ibm/locale_mgmt_zos.h
+  __support/ibm/nanosleep.h
+  __support/ibm/support.h
+  __support/ibm/xlocale.h
+  __support/musl/xlocale.h
+  __support/newlib/xlocale.h
+  __support/nuttx/xlocale.h
+  __support/openbsd/xlocale.h
+  __support/solaris/floatingpoint.h
+  __support/solaris/wchar.h
+  __support/solaris/xlocale.h
+  __support/win32/limits_msvc_win32.h
+  __support/win32/locale_win32.h
+  __support/xlocale/__nop_locale_mgmt.h
+  __support/xlocale/__posix_l_fallback.h
+  __support/xlocale/__strtonum_fallback.h
+  __threading_support
+  __tree
+  __tuple
+  __undef_macros
+  __utility/__decay_copy.h
+  __utility/as_const.h
+  __utility/cmp.h
+  __utility/declval.h
+  __utility/exchange.h
+  __utility/forward.h
+  __utility/in_place.h
+  __utility/integer_sequence.h
+  __utility/move.h
+  __utility/pair.h
+  __utility/piecewise_construct.h
+  __utility/rel_ops.h
+  __utility/swap.h
+  __utility/to_underlying.h
+  __variant/monostate.h
+  algorithm
+  any
+  array
+  atomic
+  barrier
+  bit
+  bitset
+  cassert
+  ccomplex
+  cctype
+  cerrno
+  cfenv
+  cfloat
+  charconv
+  chrono
+  cinttypes
+  ciso646
+  climits
+  clocale
+  cmath
+  codecvt
+  compare
+  complex
+  complex.h
+  concepts
+  condition_variable
+  csetjmp
+  csignal
+  cstdarg
+  cstdbool
+  cstddef
+  cstdint
+  cstdio
+  cstdlib
+  cstring
+  ctgmath
+  ctime
+  ctype.h
+  cwchar
+  cwctype
+  deque
+  errno.h
+  exception
+  execution
+  experimental/__config
+  experimental/__memory
+  experimental/algorithm
+  experimental/coroutine
+  experimental/deque
+  experimental/filesystem
+  experimental/forward_list
+  experimental/functional
+  experimental/iterator
+  experimental/list
+  experimental/map
+  experimental/memory_resource
+  experimental/propagate_const
+  experimental/regex
+  experimental/set
+  experimental/simd
+  experimental/string
+  experimental/type_traits
+  experimental/unordered_map
+  experimental/unordered_set
+  experimental/utility
+  experimental/vector
+  ext/__hash
+  ext/hash_map
+  ext/hash_set
+  fenv.h
+  filesystem
+  float.h
+  format
+  forward_list
+  fstream
+  functional
+  future
+  initializer_list
+  inttypes.h
+  iomanip
+  ios
+  iosfwd
+  iostream
+  istream
+  iterator
+  latch
+  limits
+  limits.h
+  list
+  locale
+  locale.h
+  map
+  math.h
+  memory
+  module.modulemap
+  mutex
+  new
+  numbers
+  numeric
+  optional
+  ostream
+  queue
+  random
+  ranges
+  ranges
+  ratio
+  regex
+  scoped_allocator
+  semaphore
+  set
+  setjmp.h
+  shared_mutex
+  span
+  sstream
+  stack
+  stdbool.h
+  stddef.h
+  stdexcept
+  stdint.h
+  stdio.h
+  stdlib.h
+  streambuf
+  string
+  string_view
+  string.h
+  strstream
+  system_error
+  tgmath.h
+  thread
+  tuple
+  type_traits
+  typeindex
+  typeinfo
+  unordered_map
+  unordered_set
+  utility
+  valarray
+  variant
+  vector
+  version
+  wchar.h
+  wctype.h
+  )
+
+configure_file("__config_site.in" "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site" @ONLY)
+
+set(_all_includes "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site")
+foreach(f ${files})
+  set(src "${CMAKE_CURRENT_SOURCE_DIR}/${f}")
+  set(dst "${LIBCXX_GENERATED_INCLUDE_DIR}/${f}")
+  add_custom_command(OUTPUT ${dst}
+    DEPENDS ${src}
+    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
+    COMMENT "Copying CXX header ${f}")
+  list(APPEND _all_includes "${dst}")
+endforeach()
+
+add_custom_target(generate-cxx-headers ALL DEPENDS ${_all_includes})
+
+add_library(cxx-headers INTERFACE)
+add_dependencies(cxx-headers generate-cxx-headers ${LIBCXX_CXX_ABI_HEADER_TARGET})
+# TODO: Use target_include_directories once we figure out why that breaks the runtimes build
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
+  target_compile_options(cxx-headers INTERFACE /I${LIBCXX_GENERATED_INCLUDE_DIR}
+                                     INTERFACE /I${LIBCXX_GENERATED_INCLUDE_TARGET_DIR})
+else()
+  target_compile_options(cxx-headers INTERFACE -I${LIBCXX_GENERATED_INCLUDE_DIR}
+                                     INTERFACE -I${LIBCXX_GENERATED_INCLUDE_TARGET_DIR})
 endif()
 
-install(DIRECTORY .
-  DESTINATION include/c++/v1
-  FILES_MATCHING
-  PATTERN "*"
-  PATTERN "CMakeLists.txt" EXCLUDE
-  PATTERN ".svn" EXCLUDE
-  ${LIBCXX_SUPPORT_HEADER_PATTERN}
-  PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
-  )
+if (LIBCXX_INSTALL_HEADERS)
+  foreach(file ${files})
+    get_filename_component(dir ${file} DIRECTORY)
+    install(FILES ${file}
+      DESTINATION ${LIBCXX_INSTALL_INCLUDE_DIR}/${dir}
+      COMPONENT cxx-headers
+      PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+    )
+  endforeach()
+
+  # Install the generated __config_site.
+  install(FILES ${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site
+    DESTINATION ${LIBCXX_INSTALL_INCLUDE_TARGET_DIR}
+    PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+    COMPONENT cxx-headers)
+
+  if (NOT CMAKE_CONFIGURATION_TYPES)
+    add_custom_target(install-cxx-headers
+                      DEPENDS cxx-headers
+                      COMMAND "${CMAKE_COMMAND}"
+                              -DCMAKE_INSTALL_COMPONENT=cxx-headers
+                              -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
+    # Stripping is a no-op for headers
+    add_custom_target(install-cxx-headers-stripped DEPENDS install-cxx-headers)
+  endif()
+endif()
diff --git a/include/__algorithm/adjacent_find.h b/include/__algorithm/adjacent_find.h
new file mode 100644
index 0000000..0a2aa05
--- /dev/null
+++ b/include/__algorithm/adjacent_find.h
@@ -0,0 +1,51 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_ADJACENT_FIND_H
+#define _LIBCPP___ALGORITHM_ADJACENT_FIND_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) {
+  if (__first != __last) {
+    _ForwardIterator __i = __first;
+    while (++__i != __last) {
+      if (__pred(*__first, *__i))
+        return __first;
+      __first = __i;
+    }
+  }
+  return __last;
+}
+
+template <class _ForwardIterator>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+adjacent_find(_ForwardIterator __first, _ForwardIterator __last) {
+  typedef typename iterator_traits<_ForwardIterator>::value_type __v;
+  return _VSTD::adjacent_find(__first, __last, __equal_to<__v>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_ADJACENT_FIND_H
diff --git a/include/__algorithm/all_of.h b/include/__algorithm/all_of.h
new file mode 100644
index 0000000..7d6ed50
--- /dev/null
+++ b/include/__algorithm/all_of.h
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_ALL_OF_H
+#define _LIBCPP___ALGORITHM_ALL_OF_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _Predicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
+  for (; __first != __last; ++__first)
+    if (!__pred(*__first))
+      return false;
+  return true;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_ALL_OF_H
diff --git a/include/__algorithm/any_of.h b/include/__algorithm/any_of.h
new file mode 100644
index 0000000..d5a6c09
--- /dev/null
+++ b/include/__algorithm/any_of.h
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_ANY_OF_H
+#define _LIBCPP___ALGORITHM_ANY_OF_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _Predicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
+  for (; __first != __last; ++__first)
+    if (__pred(*__first))
+      return true;
+  return false;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_ANY_OF_H
diff --git a/include/__algorithm/binary_search.h b/include/__algorithm/binary_search.h
new file mode 100644
index 0000000..766f5da
--- /dev/null
+++ b/include/__algorithm/binary_search.h
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_BINARY_SEARCH_H
+#define _LIBCPP___ALGORITHM_BINARY_SEARCH_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/lower_bound.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _ForwardIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+__binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+    __first = _VSTD::__lower_bound<_Compare>(__first, __last, __value_, __comp);
+    return __first != __last && !__comp(__value_, *__first);
+}
+
+template <class _ForwardIterator, class _Tp, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    return _VSTD::__binary_search<_Comp_ref>(__first, __last, __value_, __comp);
+}
+
+template <class _ForwardIterator, class _Tp>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+{
+    return _VSTD::binary_search(__first, __last, __value_,
+                             __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+}
+
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_BINARY_SEARCH_H
diff --git a/include/__algorithm/clamp.h b/include/__algorithm/clamp.h
new file mode 100644
index 0000000..f8eba03
--- /dev/null
+++ b/include/__algorithm/clamp.h
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_CLAMP_H
+#define _LIBCPP___ALGORITHM_CLAMP_H
+
+#include <__config>
+#include <__debug>
+#include <__algorithm/comp.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+// clamp
+template<class _Tp, class _Compare>
+_LIBCPP_NODISCARD_EXT 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>
+_LIBCPP_NODISCARD_EXT 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
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_CLAMP_H
diff --git a/include/__algorithm/comp.h b/include/__algorithm/comp.h
new file mode 100644
index 0000000..2039cf7
--- /dev/null
+++ b/include/__algorithm/comp.h
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_COMP_H
+#define _LIBCPP___ALGORITHM_COMP_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// I'd like to replace these with _VSTD::equal_to<void>, but can't because:
+//   * That only works with C++14 and later, and
+//   * We haven't included <functional> here.
+template <class _T1, class _T2 = _T1>
+struct __equal_to
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;}
+};
+
+template <class _T1>
+struct __equal_to<_T1, _T1>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
+};
+
+template <class _T1>
+struct __equal_to<const _T1, _T1>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
+};
+
+template <class _T1>
+struct __equal_to<_T1, const _T1>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
+};
+
+template <class _T1, class _T2 = _T1>
+struct __less
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;}
+};
+
+template <class _T1>
+struct __less<_T1, _T1>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+};
+
+template <class _T1>
+struct __less<const _T1, _T1>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+};
+
+template <class _T1>
+struct __less<_T1, const _T1>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_COMP_H
diff --git a/include/__algorithm/comp_ref_type.h b/include/__algorithm/comp_ref_type.h
new file mode 100644
index 0000000..b3bca82
--- /dev/null
+++ b/include/__algorithm/comp_ref_type.h
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
+#define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
+
+#include <__config>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifdef _LIBCPP_DEBUG
+
+template <class _Compare>
+struct __debug_less
+{
+    _Compare &__comp_;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
+    __debug_less(_Compare& __c) : __comp_(__c) {}
+
+    template <class _Tp, class _Up>
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
+    bool operator()(const _Tp& __x,  const _Up& __y)
+    {
+        bool __r = __comp_(__x, __y);
+        if (__r)
+            __do_compare_assert(0, __y, __x);
+        return __r;
+    }
+
+    template <class _Tp, class _Up>
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
+    bool operator()(_Tp& __x,  _Up& __y)
+    {
+        bool __r = __comp_(__x, __y);
+        if (__r)
+            __do_compare_assert(0, __y, __x);
+        return __r;
+    }
+
+    template <class _LHS, class _RHS>
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
+    inline _LIBCPP_INLINE_VISIBILITY
+    decltype((void)declval<_Compare&>()(
+        declval<_LHS &>(), declval<_RHS &>()))
+    __do_compare_assert(int, _LHS & __l, _RHS & __r) {
+        _LIBCPP_ASSERT(!__comp_(__l, __r),
+            "Comparator does not induce a strict weak ordering");
+    }
+
+    template <class _LHS, class _RHS>
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
+    inline _LIBCPP_INLINE_VISIBILITY
+    void __do_compare_assert(long, _LHS &, _RHS &) {}
+};
+
+#endif // _LIBCPP_DEBUG
+
+template <class _Comp>
+struct __comp_ref_type {
+  // Pass the comparator by lvalue reference. Or in debug mode, using a
+  // debugging wrapper that stores a reference.
+#ifndef _LIBCPP_DEBUG
+  typedef typename add_lvalue_reference<_Comp>::type type;
+#else
+  typedef __debug_less<_Comp> type;
+#endif
+};
+
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
diff --git a/include/__algorithm/copy.h b/include/__algorithm/copy.h
new file mode 100644
index 0000000..9db7434
--- /dev/null
+++ b/include/__algorithm/copy.h
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_COPY_H
+#define _LIBCPP___ALGORITHM_COPY_H
+
+#include <__config>
+#include <__algorithm/unwrap_iter.h>
+#include <__iterator/iterator_traits.h>
+#include <cstring>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// copy
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+__copy_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    for (; __first != __last; ++__first, (void) ++__result)
+        *__result = *__first;
+    return __result;
+}
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    return _VSTD::__copy_constexpr(__first, __last, __result);
+}
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_same<typename remove_const<_Tp>::type, _Up>::value &&
+    is_trivially_copy_assignable<_Up>::value,
+    _Up*
+>::type
+__copy(_Tp* __first, _Tp* __last, _Up* __result)
+{
+    const size_t __n = static_cast<size_t>(__last - __first);
+    if (__n > 0)
+        _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+    return __result + __n;
+}
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    if (__libcpp_is_constant_evaluated()) {
+        return _VSTD::__copy_constexpr(__first, __last, __result);
+    } else {
+        return _VSTD::__rewrap_iter(__result,
+            _VSTD::__copy(_VSTD::__unwrap_iter(__first),
+                          _VSTD::__unwrap_iter(__last),
+                          _VSTD::__unwrap_iter(__result)));
+    }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_COPY_H
diff --git a/include/__algorithm/copy_backward.h b/include/__algorithm/copy_backward.h
new file mode 100644
index 0000000..03a9c5f
--- /dev/null
+++ b/include/__algorithm/copy_backward.h
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_COPY_BACKWARD_H
+#define _LIBCPP___ALGORITHM_COPY_BACKWARD_H
+
+#include <__config>
+#include <__algorithm/unwrap_iter.h>
+#include <__iterator/iterator_traits.h>
+#include <cstring>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _BidirectionalIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+__copy_backward_constexpr(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
+{
+    while (__first != __last)
+        *--__result = *--__last;
+    return __result;
+}
+
+template <class _BidirectionalIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
+{
+    return _VSTD::__copy_backward_constexpr(__first, __last, __result);
+}
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_same<typename remove_const<_Tp>::type, _Up>::value &&
+    is_trivially_copy_assignable<_Up>::value,
+    _Up*
+>::type
+__copy_backward(_Tp* __first, _Tp* __last, _Up* __result)
+{
+    const size_t __n = static_cast<size_t>(__last - __first);
+    if (__n > 0)
+    {
+        __result -= __n;
+        _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+    }
+    return __result;
+}
+
+template <class _BidirectionalIterator1, class _BidirectionalIterator2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_BidirectionalIterator2
+copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
+              _BidirectionalIterator2 __result)
+{
+    if (__libcpp_is_constant_evaluated()) {
+        return _VSTD::__copy_backward_constexpr(__first, __last, __result);
+    } else {
+        return _VSTD::__rewrap_iter(__result,
+            _VSTD::__copy_backward(_VSTD::__unwrap_iter(__first),
+                                   _VSTD::__unwrap_iter(__last),
+                                   _VSTD::__unwrap_iter(__result)));
+    }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_COPY_BACKWARD_H
diff --git a/include/__algorithm/copy_if.h b/include/__algorithm/copy_if.h
new file mode 100644
index 0000000..153304c
--- /dev/null
+++ b/include/__algorithm/copy_if.h
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_COPY_IF_H
+#define _LIBCPP___ALGORITHM_COPY_IF_H
+
+#include <__config>
+#include <__algorithm/unwrap_iter.h>
+#include <__iterator/iterator_traits.h>
+#include <cstring>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template<class _InputIterator, class _OutputIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+copy_if(_InputIterator __first, _InputIterator __last,
+        _OutputIterator __result, _Predicate __pred)
+{
+    for (; __first != __last; ++__first)
+    {
+        if (__pred(*__first))
+        {
+            *__result = *__first;
+            ++__result;
+        }
+    }
+    return __result;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_COPY_IF_H
diff --git a/include/__algorithm/copy_n.h b/include/__algorithm/copy_n.h
new file mode 100644
index 0000000..bbfeb86
--- /dev/null
+++ b/include/__algorithm/copy_n.h
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_COPY_N_H
+#define _LIBCPP___ALGORITHM_COPY_N_H
+
+#include <__config>
+#include <__algorithm/copy.h>
+#include <__algorithm/unwrap_iter.h>
+#include <__iterator/iterator_traits.h>
+#include <cstring>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template<class _InputIterator, class _Size, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+typename enable_if
+<
+    __is_cpp17_input_iterator<_InputIterator>::value &&
+   !__is_cpp17_random_access_iterator<_InputIterator>::value,
+    _OutputIterator
+>::type
+copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
+{
+    typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
+    _IntegralSize __n = __orig_n;
+    if (__n > 0)
+    {
+        *__result = *__first;
+        ++__result;
+        for (--__n; __n > 0; --__n)
+        {
+            ++__first;
+            *__result = *__first;
+            ++__result;
+        }
+    }
+    return __result;
+}
+
+template<class _InputIterator, class _Size, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+typename enable_if
+<
+    __is_cpp17_random_access_iterator<_InputIterator>::value,
+    _OutputIterator
+>::type
+copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
+{
+    typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
+    _IntegralSize __n = __orig_n;
+    return _VSTD::copy(__first, __first + __n, __result);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_COPY_N_H
diff --git a/include/__algorithm/count.h b/include/__algorithm/count.h
new file mode 100644
index 0000000..7f2d195
--- /dev/null
+++ b/include/__algorithm/count.h
@@ -0,0 +1,40 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_COUNT_H
+#define _LIBCPP___ALGORITHM_COUNT_H
+
+#include <__config>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _Tp>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    typename iterator_traits<_InputIterator>::difference_type
+    count(_InputIterator __first, _InputIterator __last, const _Tp& __value_) {
+  typename iterator_traits<_InputIterator>::difference_type __r(0);
+  for (; __first != __last; ++__first)
+    if (*__first == __value_)
+      ++__r;
+  return __r;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_COUNT_H
diff --git a/include/__algorithm/count_if.h b/include/__algorithm/count_if.h
new file mode 100644
index 0000000..a5efffb
--- /dev/null
+++ b/include/__algorithm/count_if.h
@@ -0,0 +1,40 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_COUNT_IF_H
+#define _LIBCPP___ALGORITHM_COUNT_IF_H
+
+#include <__config>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _Predicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    typename iterator_traits<_InputIterator>::difference_type
+    count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
+  typename iterator_traits<_InputIterator>::difference_type __r(0);
+  for (; __first != __last; ++__first)
+    if (__pred(*__first))
+      ++__r;
+  return __r;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_COUNT_IF_H
diff --git a/include/__algorithm/equal.h b/include/__algorithm/equal.h
new file mode 100644
index 0000000..bc67559
--- /dev/null
+++ b/include/__algorithm/equal.h
@@ -0,0 +1,90 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_EQUAL_H
+#define _LIBCPP___ALGORITHM_EQUAL_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__iterator/iterator_traits.h>
+#include <iterator> // FIXME: replace with <__iterator/distance.h> when it lands
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
+  for (; __first1 != __last1; ++__first1, (void)++__first2)
+    if (!__pred(*__first1, *__first2))
+      return false;
+  return true;
+}
+
+template <class _InputIterator1, class _InputIterator2>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
+  typedef typename iterator_traits<_InputIterator1>::value_type __v1;
+  typedef typename iterator_traits<_InputIterator2>::value_type __v2;
+  return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>());
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+__equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
+        _BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) {
+  for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
+    if (!__pred(*__first1, *__first2))
+      return false;
+  return __first1 == __last1 && __first2 == __last2;
+}
+
+template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
+        _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag,
+        random_access_iterator_tag) {
+  if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
+    return false;
+  return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2,
+                      typename add_lvalue_reference<_BinaryPredicate>::type>(__first1, __last1, __first2, __pred);
+}
+
+template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
+      _BinaryPredicate __pred) {
+  return _VSTD::__equal<typename add_lvalue_reference<_BinaryPredicate>::type>(
+      __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_InputIterator1>::iterator_category(),
+      typename iterator_traits<_InputIterator2>::iterator_category());
+}
+
+template <class _InputIterator1, class _InputIterator2>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
+  typedef typename iterator_traits<_InputIterator1>::value_type __v1;
+  typedef typename iterator_traits<_InputIterator2>::value_type __v2;
+  return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(),
+                        typename iterator_traits<_InputIterator1>::iterator_category(),
+                        typename iterator_traits<_InputIterator2>::iterator_category());
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_EQUAL_H
diff --git a/include/__algorithm/equal_range.h b/include/__algorithm/equal_range.h
new file mode 100644
index 0000000..9694dae
--- /dev/null
+++ b/include/__algorithm/equal_range.h
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_EQUAL_RANGE_H
+#define _LIBCPP___ALGORITHM_EQUAL_RANGE_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/half_positive.h>
+#include <__algorithm/lower_bound.h>
+#include <__algorithm/upper_bound.h>
+#include <iterator>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _ForwardIterator, class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator>
+__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
+    difference_type __len = _VSTD::distance(__first, __last);
+    while (__len != 0)
+    {
+        difference_type __l2 = _VSTD::__half_positive(__len);
+        _ForwardIterator __m = __first;
+        _VSTD::advance(__m, __l2);
+        if (__comp(*__m, __value_))
+        {
+            __first = ++__m;
+            __len -= __l2 + 1;
+        }
+        else if (__comp(__value_, *__m))
+        {
+            __last = __m;
+            __len = __l2;
+        }
+        else
+        {
+            _ForwardIterator __mp1 = __m;
+            return pair<_ForwardIterator, _ForwardIterator>
+                   (
+                      _VSTD::__lower_bound<_Compare>(__first, __m, __value_, __comp),
+                      _VSTD::__upper_bound<_Compare>(++__mp1, __last, __value_, __comp)
+                   );
+        }
+    }
+    return pair<_ForwardIterator, _ForwardIterator>(__first, __first);
+}
+
+template <class _ForwardIterator, class _Tp, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+pair<_ForwardIterator, _ForwardIterator>
+equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    return _VSTD::__equal_range<_Comp_ref>(__first, __last, __value_, __comp);
+}
+
+template <class _ForwardIterator, class _Tp>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+pair<_ForwardIterator, _ForwardIterator>
+equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+{
+    return _VSTD::equal_range(__first, __last, __value_,
+                             __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_EQUAL_RANGE_H
diff --git a/include/__algorithm/fill.h b/include/__algorithm/fill.h
new file mode 100644
index 0000000..4fefe86
--- /dev/null
+++ b/include/__algorithm/fill.h
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_FILL_H
+#define _LIBCPP___ALGORITHM_FILL_H
+
+#include <__config>
+#include <__algorithm/fill_n.h>
+#include <__iterator/iterator_traits.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag)
+{
+    for (; __first != __last; ++__first)
+        *__first = __value_;
+}
+
+template <class _RandomAccessIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag)
+{
+    _VSTD::fill_n(__first, __last - __first, __value_);
+}
+
+template <class _ForwardIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+{
+    _VSTD::__fill(__first, __last, __value_, typename iterator_traits<_ForwardIterator>::iterator_category());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_FILL_H
diff --git a/include/__algorithm/fill_n.h b/include/__algorithm/fill_n.h
new file mode 100644
index 0000000..34a245e
--- /dev/null
+++ b/include/__algorithm/fill_n.h
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_FILL_N_H
+#define _LIBCPP___ALGORITHM_FILL_N_H
+
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _OutputIterator, class _Size, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
+{
+    for (; __n > 0; ++__first, (void) --__n)
+        *__first = __value_;
+    return __first;
+}
+
+template <class _OutputIterator, class _Size, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
+{
+   return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value_);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_FILL_N_H
diff --git a/include/__algorithm/find.h b/include/__algorithm/find.h
new file mode 100644
index 0000000..bc593dc
--- /dev/null
+++ b/include/__algorithm/find.h
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_FIND_H
+#define _LIBCPP___ALGORITHM_FIND_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _Tp>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator
+find(_InputIterator __first, _InputIterator __last, const _Tp& __value_) {
+  for (; __first != __last; ++__first)
+    if (*__first == __value_)
+      break;
+  return __first;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_FIND_H
diff --git a/include/__algorithm/find_end.h b/include/__algorithm/find_end.h
new file mode 100644
index 0000000..f4277f0
--- /dev/null
+++ b/include/__algorithm/find_end.h
@@ -0,0 +1,154 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_FIND_END_OF_H
+#define _LIBCPP___ALGORITHM_FIND_END_OF_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__iterator/iterator_traits.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+                                                           _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+                                                           _BinaryPredicate __pred, forward_iterator_tag,
+                                                           forward_iterator_tag) {
+  // modeled after search algorithm
+  _ForwardIterator1 __r = __last1; // __last1 is the "default" answer
+  if (__first2 == __last2)
+    return __r;
+  while (true) {
+    while (true) {
+      if (__first1 == __last1) // if source exhausted return last correct answer
+        return __r;            //    (or __last1 if never found)
+      if (__pred(*__first1, *__first2))
+        break;
+      ++__first1;
+    }
+    // *__first1 matches *__first2, now match elements after here
+    _ForwardIterator1 __m1 = __first1;
+    _ForwardIterator2 __m2 = __first2;
+    while (true) {
+      if (++__m2 == __last2) { // Pattern exhaused, record answer and search for another one
+        __r = __first1;
+        ++__first1;
+        break;
+      }
+      if (++__m1 == __last1) // Source exhausted, return last answer
+        return __r;
+      if (!__pred(*__m1, *__m2)) // mismatch, restart with a new __first
+      {
+        ++__first1;
+        break;
+      } // else there is a match, check next elements
+    }
+  }
+}
+
+template <class _BinaryPredicate, class _BidirectionalIterator1, class _BidirectionalIterator2>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1 __find_end(
+    _BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, _BidirectionalIterator2 __first2,
+    _BidirectionalIterator2 __last2, _BinaryPredicate __pred, bidirectional_iterator_tag, bidirectional_iterator_tag) {
+  // modeled after search algorithm (in reverse)
+  if (__first2 == __last2)
+    return __last1; // Everything matches an empty sequence
+  _BidirectionalIterator1 __l1 = __last1;
+  _BidirectionalIterator2 __l2 = __last2;
+  --__l2;
+  while (true) {
+    // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks
+    while (true) {
+      if (__first1 == __l1) // return __last1 if no element matches *__first2
+        return __last1;
+      if (__pred(*--__l1, *__l2))
+        break;
+    }
+    // *__l1 matches *__l2, now match elements before here
+    _BidirectionalIterator1 __m1 = __l1;
+    _BidirectionalIterator2 __m2 = __l2;
+    while (true) {
+      if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern)
+        return __m1;
+      if (__m1 == __first1) // Otherwise if source exhaused, pattern not found
+        return __last1;
+      if (!__pred(*--__m1, *--__m2)) // if there is a mismatch, restart with a new __l1
+      {
+        break;
+      } // else there is a match, check next elements
+    }
+  }
+}
+
+template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 __find_end(
+    _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
+    _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag) {
+  // Take advantage of knowing source and pattern lengths.  Stop short when source is smaller than pattern
+  typename iterator_traits<_RandomAccessIterator2>::difference_type __len2 = __last2 - __first2;
+  if (__len2 == 0)
+    return __last1;
+  typename iterator_traits<_RandomAccessIterator1>::difference_type __len1 = __last1 - __first1;
+  if (__len1 < __len2)
+    return __last1;
+  const _RandomAccessIterator1 __s = __first1 + (__len2 - 1); // End of pattern match can't go before here
+  _RandomAccessIterator1 __l1 = __last1;
+  _RandomAccessIterator2 __l2 = __last2;
+  --__l2;
+  while (true) {
+    while (true) {
+      if (__s == __l1)
+        return __last1;
+      if (__pred(*--__l1, *__l2))
+        break;
+    }
+    _RandomAccessIterator1 __m1 = __l1;
+    _RandomAccessIterator2 __m2 = __l2;
+    while (true) {
+      if (__m2 == __first2)
+        return __m1;
+      // no need to check range on __m1 because __s guarantees we have enough source
+      if (!__pred(*--__m1, *--__m2)) {
+        break;
+      }
+    }
+  }
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
+find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+         _BinaryPredicate __pred) {
+  return _VSTD::__find_end<typename add_lvalue_reference<_BinaryPredicate>::type>(
+      __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_ForwardIterator1>::iterator_category(),
+      typename iterator_traits<_ForwardIterator2>::iterator_category());
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
+find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
+  typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
+  typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
+  return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_FIND_END_OF_H
diff --git a/include/__algorithm/find_first_of.h b/include/__algorithm/find_first_of.h
new file mode 100644
index 0000000..d956c8d
--- /dev/null
+++ b/include/__algorithm/find_first_of.h
@@ -0,0 +1,57 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_FIND_FIRST_OF_H
+#define _LIBCPP___ALGORITHM_FIND_FIRST_OF_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1 __find_first_of_ce(_ForwardIterator1 __first1,
+                                                                   _ForwardIterator1 __last1,
+                                                                   _ForwardIterator2 __first2,
+                                                                   _ForwardIterator2 __last2, _BinaryPredicate __pred) {
+  for (; __first1 != __last1; ++__first1)
+    for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
+      if (__pred(*__first1, *__j))
+        return __first1;
+  return __last1;
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
+find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
+              _ForwardIterator2 __last2, _BinaryPredicate __pred) {
+  return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred);
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 find_first_of(
+    _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
+  typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
+  typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
+  return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_FIND_FIRST_OF_H
diff --git a/include/__algorithm/find_if.h b/include/__algorithm/find_if.h
new file mode 100644
index 0000000..456cc5b
--- /dev/null
+++ b/include/__algorithm/find_if.h
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_FIND_IF_H
+#define _LIBCPP___ALGORITHM_FIND_IF_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _Predicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator
+find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
+  for (; __first != __last; ++__first)
+    if (__pred(*__first))
+      break;
+  return __first;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_FIND_IF_H
diff --git a/include/__algorithm/find_if_not.h b/include/__algorithm/find_if_not.h
new file mode 100644
index 0000000..d7d2516
--- /dev/null
+++ b/include/__algorithm/find_if_not.h
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_FIND_IF_NOT_H
+#define _LIBCPP___ALGORITHM_FIND_IF_NOT_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _Predicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator
+find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
+  for (; __first != __last; ++__first)
+    if (!__pred(*__first))
+      break;
+  return __first;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_FIND_IF_NOT_H
diff --git a/include/__algorithm/for_each.h b/include/__algorithm/for_each.h
new file mode 100644
index 0000000..e71a36a
--- /dev/null
+++ b/include/__algorithm/for_each.h
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_FOR_EACH_H
+#define _LIBCPP___ALGORITHM_FOR_EACH_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _Function>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Function for_each(_InputIterator __first,
+                                                                                  _InputIterator __last,
+                                                                                  _Function __f) {
+  for (; __first != __last; ++__first)
+    __f(*__first);
+  return __f;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_FOR_EACH_H
diff --git a/include/__algorithm/for_each_n.h b/include/__algorithm/for_each_n.h
new file mode 100644
index 0000000..77f6c86
--- /dev/null
+++ b/include/__algorithm/for_each_n.h
@@ -0,0 +1,47 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_FOR_EACH_N_H
+#define _LIBCPP___ALGORITHM_FOR_EACH_N_H
+
+#include <__config>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+template <class _InputIterator, class _Size, class _Function>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator for_each_n(_InputIterator __first,
+                                                                                         _Size __orig_n,
+                                                                                         _Function __f) {
+  typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
+  _IntegralSize __n = __orig_n;
+  while (__n > 0) {
+    __f(*__first);
+    ++__first;
+    --__n;
+  }
+  return __first;
+}
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_FOR_EACH_N_H
diff --git a/include/__algorithm/generate.h b/include/__algorithm/generate.h
new file mode 100644
index 0000000..d3e1133
--- /dev/null
+++ b/include/__algorithm/generate.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_GENERATE_H
+#define _LIBCPP___ALGORITHM_GENERATE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator, class _Generator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen)
+{
+    for (; __first != __last; ++__first)
+        *__first = __gen();
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_GENERATE_H
diff --git a/include/__algorithm/generate_n.h b/include/__algorithm/generate_n.h
new file mode 100644
index 0000000..c312598
--- /dev/null
+++ b/include/__algorithm/generate_n.h
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_GENERATE_N_H
+#define _LIBCPP___ALGORITHM_GENERATE_N_H
+
+#include <__config>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _OutputIterator, class _Size, class _Generator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen)
+{
+    typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
+    _IntegralSize __n = __orig_n;
+    for (; __n > 0; ++__first, (void) --__n)
+        *__first = __gen();
+    return __first;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_GENERATE_N_H
diff --git a/include/__algorithm/half_positive.h b/include/__algorithm/half_positive.h
new file mode 100644
index 0000000..b03efc4
--- /dev/null
+++ b/include/__algorithm/half_positive.h
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_HALF_POSITIVE_H
+#define _LIBCPP___ALGORITHM_HALF_POSITIVE_H
+
+#include <__config>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Perform division by two quickly for positive integers (llvm.org/PR39129)
+
+template <typename _Integral>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+typename enable_if
+<
+    is_integral<_Integral>::value,
+    _Integral
+>::type
+__half_positive(_Integral __value)
+{
+    return static_cast<_Integral>(static_cast<typename make_unsigned<_Integral>::type>(__value) / 2);
+}
+
+template <typename _Tp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+typename enable_if
+<
+    !is_integral<_Tp>::value,
+    _Tp
+>::type
+__half_positive(_Tp __value)
+{
+    return __value / 2;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_HALF_POSITIVE_H
diff --git a/include/__algorithm/includes.h b/include/__algorithm/includes.h
new file mode 100644
index 0000000..ff298a5
--- /dev/null
+++ b/include/__algorithm/includes.h
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_INCLUDES_H
+#define _LIBCPP___ALGORITHM_INCLUDES_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _InputIterator1, class _InputIterator2>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+__includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
+           _Compare __comp)
+{
+    for (; __first2 != __last2; ++__first1)
+    {
+        if (__first1 == __last1 || __comp(*__first2, *__first1))
+            return false;
+        if (!__comp(*__first1, *__first2))
+            ++__first2;
+    }
+    return true;
+}
+
+template <class _InputIterator1, class _InputIterator2, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
+         _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    return _VSTD::__includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);
+}
+
+template <class _InputIterator1, class _InputIterator2>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2)
+{
+    return _VSTD::includes(__first1, __last1, __first2, __last2,
+                          __less<typename iterator_traits<_InputIterator1>::value_type,
+                                 typename iterator_traits<_InputIterator2>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_INCLUDES_H
diff --git a/include/__algorithm/inplace_merge.h b/include/__algorithm/inplace_merge.h
new file mode 100644
index 0000000..c74633a
--- /dev/null
+++ b/include/__algorithm/inplace_merge.h
@@ -0,0 +1,231 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_INPLACE_MERGE_H
+#define _LIBCPP___ALGORITHM_INPLACE_MERGE_H
+
+#include <__config>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/comp.h>
+#include <__algorithm/lower_bound.h>
+#include <__algorithm/min.h>
+#include <__algorithm/move.h>
+#include <__algorithm/rotate.h>
+#include <__algorithm/upper_bound.h>
+#include <__iterator/iterator_traits.h>
+#include <__utility/swap.h>
+#include <memory>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Predicate>
+class __invert // invert the sense of a comparison
+{
+private:
+    _Predicate __p_;
+public:
+    _LIBCPP_INLINE_VISIBILITY __invert() {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __invert(_Predicate __p) : __p_(__p) {}
+
+    template <class _T1>
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _T1& __x) {return !__p_(__x);}
+
+    template <class _T1, class _T2>
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);}
+};
+
+template <class _Compare, class _InputIterator1, class _InputIterator2,
+          class _OutputIterator>
+void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1,
+                          _InputIterator2 __first2, _InputIterator2 __last2,
+                          _OutputIterator __result, _Compare __comp)
+{
+    for (; __first1 != __last1; ++__result)
+    {
+        if (__first2 == __last2)
+        {
+            _VSTD::move(__first1, __last1, __result);
+            return;
+        }
+
+        if (__comp(*__first2, *__first1))
+        {
+            *__result = _VSTD::move(*__first2);
+            ++__first2;
+        }
+        else
+        {
+            *__result = _VSTD::move(*__first1);
+            ++__first1;
+        }
+    }
+    // __first2 through __last2 are already in the right spot.
+}
+
+template <class _Compare, class _BidirectionalIterator>
+void
+__buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
+                _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
+                                 typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
+                typename iterator_traits<_BidirectionalIterator>::value_type* __buff)
+{
+    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+    __destruct_n __d(0);
+    unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
+    if (__len1 <= __len2)
+    {
+        value_type* __p = __buff;
+        for (_BidirectionalIterator __i = __first; __i != __middle; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p)
+            ::new ((void*)__p) value_type(_VSTD::move(*__i));
+        _VSTD::__half_inplace_merge<_Compare>(__buff, __p, __middle, __last, __first, __comp);
+    }
+    else
+    {
+        value_type* __p = __buff;
+        for (_BidirectionalIterator __i = __middle; __i != __last; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p)
+            ::new ((void*)__p) value_type(_VSTD::move(*__i));
+        typedef reverse_iterator<_BidirectionalIterator> _RBi;
+        typedef reverse_iterator<value_type*> _Rv;
+        typedef __invert<_Compare> _Inverted;
+        _VSTD::__half_inplace_merge<_Inverted>(_Rv(__p), _Rv(__buff),
+                                    _RBi(__middle), _RBi(__first),
+                                    _RBi(__last), _Inverted(__comp));
+    }
+}
+
+template <class _Compare, class _BidirectionalIterator>
+void
+__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
+                _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
+                                 typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
+                typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size)
+{
+    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
+    while (true)
+    {
+        // if __middle == __last, we're done
+        if (__len2 == 0)
+            return;
+        if (__len1 <= __buff_size || __len2 <= __buff_size)
+            return _VSTD::__buffered_inplace_merge<_Compare>
+                   (__first, __middle, __last, __comp, __len1, __len2, __buff);
+        // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0
+        for (; true; ++__first, (void) --__len1)
+        {
+            if (__len1 == 0)
+                return;
+            if (__comp(*__middle, *__first))
+                break;
+        }
+        // __first < __middle < __last
+        // *__first > *__middle
+        // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that
+        //     all elements in:
+        //         [__first, __m1)  <= [__middle, __m2)
+        //         [__middle, __m2) <  [__m1, __middle)
+        //         [__m1, __middle) <= [__m2, __last)
+        //     and __m1 or __m2 is in the middle of its range
+        _BidirectionalIterator __m1;  // "median" of [__first, __middle)
+        _BidirectionalIterator __m2;  // "median" of [__middle, __last)
+        difference_type __len11;      // distance(__first, __m1)
+        difference_type __len21;      // distance(__middle, __m2)
+        // binary search smaller range
+        if (__len1 < __len2)
+        {   // __len >= 1, __len2 >= 2
+            __len21 = __len2 / 2;
+            __m2 = __middle;
+            _VSTD::advance(__m2, __len21);
+            __m1 = _VSTD::__upper_bound<_Compare>(__first, __middle, *__m2, __comp);
+            __len11 = _VSTD::distance(__first, __m1);
+        }
+        else
+        {
+            if (__len1 == 1)
+            {   // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1
+                // It is known *__first > *__middle
+                swap(*__first, *__middle);
+                return;
+            }
+            // __len1 >= 2, __len2 >= 1
+            __len11 = __len1 / 2;
+            __m1 = __first;
+            _VSTD::advance(__m1, __len11);
+            __m2 = _VSTD::__lower_bound<_Compare>(__middle, __last, *__m1, __comp);
+            __len21 = _VSTD::distance(__middle, __m2);
+        }
+        difference_type __len12 = __len1 - __len11;  // distance(__m1, __middle)
+        difference_type __len22 = __len2 - __len21;  // distance(__m2, __last)
+        // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last)
+        // swap middle two partitions
+        __middle = _VSTD::rotate(__m1, __middle, __m2);
+        // __len12 and __len21 now have swapped meanings
+        // merge smaller range with recursive call and larger with tail recursion elimination
+        if (__len11 + __len21 < __len12 + __len22)
+        {
+            _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
+//          _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
+            __first = __middle;
+            __middle = __m2;
+            __len1 = __len12;
+            __len2 = __len22;
+        }
+        else
+        {
+            _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
+//          _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
+            __last = __middle;
+            __middle = __m1;
+            __len1 = __len11;
+            __len2 = __len21;
+        }
+    }
+}
+
+template <class _BidirectionalIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
+              _Compare __comp)
+{
+    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
+    difference_type __len1 = _VSTD::distance(__first, __middle);
+    difference_type __len2 = _VSTD::distance(__middle, __last);
+    difference_type __buf_size = _VSTD::min(__len1, __len2);
+    pair<value_type*, ptrdiff_t> __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size);
+    unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first);
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2,
+                                            __buf.first, __buf.second);
+}
+
+template <class _BidirectionalIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last)
+{
+    _VSTD::inplace_merge(__first, __middle, __last,
+                        __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_INPLACE_MERGE_H
diff --git a/include/__algorithm/is_heap.h b/include/__algorithm/is_heap.h
new file mode 100644
index 0000000..bc3682d
--- /dev/null
+++ b/include/__algorithm/is_heap.h
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_IS_HEAP_H
+#define _LIBCPP___ALGORITHM_IS_HEAP_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/is_heap_until.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _RandomAccessIterator, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    return _VSTD::is_heap_until(__first, __last, __comp) == __last;
+}
+
+template<class _RandomAccessIterator>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_IS_HEAP_H
diff --git a/include/__algorithm/is_heap_until.h b/include/__algorithm/is_heap_until.h
new file mode 100644
index 0000000..8c52edb
--- /dev/null
+++ b/include/__algorithm/is_heap_until.h
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H
+#define _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _RandomAccessIterator, class _Compare>
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
+is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    difference_type __len = __last - __first;
+    difference_type __p = 0;
+    difference_type __c = 1;
+    _RandomAccessIterator __pp = __first;
+    while (__c < __len)
+    {
+        _RandomAccessIterator __cp = __first + __c;
+        if (__comp(*__pp, *__cp))
+            return __cp;
+        ++__c;
+        ++__cp;
+        if (__c == __len)
+            return __last;
+        if (__comp(*__pp, *__cp))
+            return __cp;
+        ++__p;
+        ++__pp;
+        __c = 2 * __p + 1;
+    }
+    return __last;
+}
+
+template<class _RandomAccessIterator>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_RandomAccessIterator
+is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    return _VSTD::is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H
diff --git a/include/__algorithm/is_partitioned.h b/include/__algorithm/is_partitioned.h
new file mode 100644
index 0000000..43de665
--- /dev/null
+++ b/include/__algorithm/is_partitioned.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_IS_PARTITIONED_H
+#define _LIBCPP___ALGORITHM_IS_PARTITIONED_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _Predicate>
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred)
+{
+    for (; __first != __last; ++__first)
+        if (!__pred(*__first))
+            break;
+    if ( __first == __last )
+        return true;
+    ++__first;
+    for (; __first != __last; ++__first)
+        if (__pred(*__first))
+            return false;
+    return true;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_IS_PARTITIONED_H
diff --git a/include/__algorithm/is_permutation.h b/include/__algorithm/is_permutation.h
new file mode 100644
index 0000000..0545eb7
--- /dev/null
+++ b/include/__algorithm/is_permutation.h
@@ -0,0 +1,168 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_IS_PERMUTATION_H
+#define _LIBCPP___ALGORITHM_IS_PERMUTATION_H
+
+#include <__algorithm/comp.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <iterator> // FIXME: replace with <__iterator/distance.h> when it lands
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
+               _BinaryPredicate __pred) {
+  //  shorten sequences as much as possible by lopping of any equal prefix
+  for (; __first1 != __last1; ++__first1, (void)++__first2)
+    if (!__pred(*__first1, *__first2))
+      break;
+  if (__first1 == __last1)
+    return true;
+
+  //  __first1 != __last1 && *__first1 != *__first2
+  typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
+  _D1 __l1 = _VSTD::distance(__first1, __last1);
+  if (__l1 == _D1(1))
+    return false;
+  _ForwardIterator2 __last2 = _VSTD::next(__first2, __l1);
+  // For each element in [f1, l1) see if there are the same number of
+  //    equal elements in [f2, l2)
+  for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) {
+    //  Have we already counted the number of *__i in [f1, l1)?
+    _ForwardIterator1 __match = __first1;
+    for (; __match != __i; ++__match)
+      if (__pred(*__match, *__i))
+        break;
+    if (__match == __i) {
+      // Count number of *__i in [f2, l2)
+      _D1 __c2 = 0;
+      for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
+        if (__pred(*__i, *__j))
+          ++__c2;
+      if (__c2 == 0)
+        return false;
+      // Count number of *__i in [__i, l1) (we can start with 1)
+      _D1 __c1 = 1;
+      for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)
+        if (__pred(*__i, *__j))
+          ++__c1;
+      if (__c1 != __c2)
+        return false;
+    }
+  }
+  return true;
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
+  typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
+  typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
+  return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>());
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
+                 _ForwardIterator2 __last2, _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) {
+  //  shorten sequences as much as possible by lopping of any equal prefix
+  for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
+    if (!__pred(*__first1, *__first2))
+      break;
+  if (__first1 == __last1)
+    return __first2 == __last2;
+  else if (__first2 == __last2)
+    return false;
+
+  typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
+  _D1 __l1 = _VSTD::distance(__first1, __last1);
+
+  typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2;
+  _D2 __l2 = _VSTD::distance(__first2, __last2);
+  if (__l1 != __l2)
+    return false;
+
+  // For each element in [f1, l1) see if there are the same number of
+  //    equal elements in [f2, l2)
+  for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) {
+    //  Have we already counted the number of *__i in [f1, l1)?
+    _ForwardIterator1 __match = __first1;
+    for (; __match != __i; ++__match)
+      if (__pred(*__match, *__i))
+        break;
+    if (__match == __i) {
+      // Count number of *__i in [f2, l2)
+      _D1 __c2 = 0;
+      for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
+        if (__pred(*__i, *__j))
+          ++__c2;
+      if (__c2 == 0)
+        return false;
+      // Count number of *__i in [__i, l1) (we can start with 1)
+      _D1 __c1 = 1;
+      for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)
+        if (__pred(*__i, *__j))
+          ++__c1;
+      if (__c1 != __c2)
+        return false;
+    }
+  }
+  return true;
+}
+
+template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool __is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1,
+                                                    _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2,
+                                                    _BinaryPredicate __pred, random_access_iterator_tag,
+                                                    random_access_iterator_tag) {
+  if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
+    return false;
+  return _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2,
+                               typename add_lvalue_reference<_BinaryPredicate>::type>(__first1, __last1, __first2,
+                                                                                      __pred);
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
+               _ForwardIterator2 __last2, _BinaryPredicate __pred) {
+  return _VSTD::__is_permutation<typename add_lvalue_reference<_BinaryPredicate>::type>(
+      __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_ForwardIterator1>::iterator_category(),
+      typename iterator_traits<_ForwardIterator2>::iterator_category());
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
+               _ForwardIterator2 __last2) {
+  typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
+  typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
+  return _VSTD::__is_permutation(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(),
+                                 typename iterator_traits<_ForwardIterator1>::iterator_category(),
+                                 typename iterator_traits<_ForwardIterator2>::iterator_category());
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_IS_PERMUTATION_H
diff --git a/include/__algorithm/is_sorted.h b/include/__algorithm/is_sorted.h
new file mode 100644
index 0000000..30d8da0
--- /dev/null
+++ b/include/__algorithm/is_sorted.h
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_IS_SORTED_H
+#define _LIBCPP___ALGORITHM_IS_SORTED_H
+
+#include <__algorithm/comp.h>
+#include <__algorithm/is_sorted_until.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+    return _VSTD::is_sorted_until(__first, __last, __comp) == __last;
+}
+
+template<class _ForwardIterator>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+is_sorted(_ForwardIterator __first, _ForwardIterator __last)
+{
+    return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_IS_SORTED_H
diff --git a/include/__algorithm/is_sorted_until.h b/include/__algorithm/is_sorted_until.h
new file mode 100644
index 0000000..a914b5a
--- /dev/null
+++ b/include/__algorithm/is_sorted_until.h
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H
+#define _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator, class _Compare>
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __i = __first;
+        while (++__i != __last)
+        {
+            if (__comp(*__i, *__first))
+                return __i;
+            __first = __i;
+        }
+    }
+    return __last;
+}
+
+template<class _ForwardIterator>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator
+is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
+{
+    return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H
diff --git a/include/__algorithm/iter_swap.h b/include/__algorithm/iter_swap.h
new file mode 100644
index 0000000..b63bce6
--- /dev/null
+++ b/include/__algorithm/iter_swap.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_ITER_SWAP_H
+#define _LIBCPP___ALGORITHM_ITER_SWAP_H
+
+#include <__config>
+#include <__utility/declval.h>
+#include <__utility/swap.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator1, class _ForwardIterator2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void iter_swap(_ForwardIterator1 __a,
+                                                                              _ForwardIterator2 __b)
+    //                                  _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b)))
+    _NOEXCEPT_(_NOEXCEPT_(swap(*declval<_ForwardIterator1>(), *declval<_ForwardIterator2>()))) {
+  swap(*__a, *__b);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_ITER_SWAP_H
diff --git a/include/__algorithm/lexicographical_compare.h b/include/__algorithm/lexicographical_compare.h
new file mode 100644
index 0000000..6e4a90b
--- /dev/null
+++ b/include/__algorithm/lexicographical_compare.h
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H
+#define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _InputIterator1, class _InputIterator2>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
+                          _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
+{
+    for (; __first2 != __last2; ++__first1, (void) ++__first2)
+    {
+        if (__first1 == __last1 || __comp(*__first1, *__first2))
+            return true;
+        if (__comp(*__first2, *__first1))
+            return false;
+    }
+    return false;
+}
+
+template <class _InputIterator1, class _InputIterator2, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
+                        _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    return _VSTD::__lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);
+}
+
+template <class _InputIterator1, class _InputIterator2>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
+                        _InputIterator2 __first2, _InputIterator2 __last2)
+{
+    return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2,
+                                         __less<typename iterator_traits<_InputIterator1>::value_type,
+                                                typename iterator_traits<_InputIterator2>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H
diff --git a/include/__algorithm/lower_bound.h b/include/__algorithm/lower_bound.h
new file mode 100644
index 0000000..1448c89
--- /dev/null
+++ b/include/__algorithm/lower_bound.h
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_LOWER_BOUND_H
+#define _LIBCPP___ALGORITHM_LOWER_BOUND_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/half_positive.h>
+#include <iterator>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _ForwardIterator, class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+__lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
+    difference_type __len = _VSTD::distance(__first, __last);
+    while (__len != 0)
+    {
+        difference_type __l2 = _VSTD::__half_positive(__len);
+        _ForwardIterator __m = __first;
+        _VSTD::advance(__m, __l2);
+        if (__comp(*__m, __value_))
+        {
+            __first = ++__m;
+            __len -= __l2 + 1;
+        }
+        else
+            __len = __l2;
+    }
+    return __first;
+}
+
+template <class _ForwardIterator, class _Tp, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator
+lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return _VSTD::__lower_bound<_Comp_ref>(__first, __last, __value_, __comp);
+}
+
+template <class _ForwardIterator, class _Tp>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator
+lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+{
+    return _VSTD::lower_bound(__first, __last, __value_,
+                             __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_LOWER_BOUND_H
diff --git a/include/__algorithm/make_heap.h b/include/__algorithm/make_heap.h
new file mode 100644
index 0000000..eca4013
--- /dev/null
+++ b/include/__algorithm/make_heap.h
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_MAKE_HEAP_H
+#define _LIBCPP___ALGORITHM_MAKE_HEAP_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/sift_down.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _RandomAccessIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 void
+__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    difference_type __n = __last - __first;
+    if (__n > 1)
+    {
+        // start from the first parent, there is no need to consider children
+        for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start)
+        {
+            _VSTD::__sift_down<_Compare>(__first, __last, __comp, __n, __first + __start);
+        }
+    }
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    _VSTD::__make_heap<_Comp_ref>(__first, __last, __comp);
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    _VSTD::make_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_MAKE_HEAP_H
diff --git a/include/__algorithm/max.h b/include/__algorithm/max.h
new file mode 100644
index 0000000..2fa97ca
--- /dev/null
+++ b/include/__algorithm/max.h
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_MAX_H
+#define _LIBCPP___ALGORITHM_MAX_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/max_element.h>
+#include <initializer_list>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Tp&
+max(const _Tp& __a, const _Tp& __b, _Compare __comp)
+{
+    return __comp(__a, __b) ? __b : __a;
+}
+
+template <class _Tp>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Tp&
+max(const _Tp& __a, const _Tp& __b)
+{
+    return _VSTD::max(__a, __b, __less<_Tp>());
+}
+
+#ifndef _LIBCPP_CXX03_LANG
+
+template<class _Tp, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp
+max(initializer_list<_Tp> __t, _Compare __comp)
+{
+    return *_VSTD::max_element(__t.begin(), __t.end(), __comp);
+}
+
+template<class _Tp>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp
+max(initializer_list<_Tp> __t)
+{
+    return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>());
+}
+
+#endif // _LIBCPP_CXX03_LANG
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_MAX_H
diff --git a/include/__algorithm/max_element.h b/include/__algorithm/max_element.h
new file mode 100644
index 0000000..b93b67e
--- /dev/null
+++ b/include/__algorithm/max_element.h
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_MAX_ELEMENT_H
+#define _LIBCPP___ALGORITHM_MAX_ELEMENT_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_ForwardIterator
+max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+    static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
+        "std::max_element requires a ForwardIterator");
+    if (__first != __last)
+    {
+        _ForwardIterator __i = __first;
+        while (++__i != __last)
+            if (__comp(*__first, *__i))
+                __first = __i;
+    }
+    return __first;
+}
+
+
+template <class _ForwardIterator>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_ForwardIterator
+max_element(_ForwardIterator __first, _ForwardIterator __last)
+{
+    return _VSTD::max_element(__first, __last,
+              __less<typename iterator_traits<_ForwardIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_MAX_ELEMENT_H
diff --git a/include/__algorithm/merge.h b/include/__algorithm/merge.h
new file mode 100644
index 0000000..ea53ad6
--- /dev/null
+++ b/include/__algorithm/merge.h
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_MERGE_H
+#define _LIBCPP___ALGORITHM_MERGE_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/copy.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+__merge(_InputIterator1 __first1, _InputIterator1 __last1,
+        _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    for (; __first1 != __last1; ++__result)
+    {
+        if (__first2 == __last2)
+            return _VSTD::copy(__first1, __last1, __result);
+        if (__comp(*__first2, *__first1))
+        {
+            *__result = *__first2;
+            ++__first2;
+        }
+        else
+        {
+            *__result = *__first1;
+            ++__first1;
+        }
+    }
+    return _VSTD::copy(__first2, __last2, __result);
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+merge(_InputIterator1 __first1, _InputIterator1 __last1,
+      _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+merge(_InputIterator1 __first1, _InputIterator1 __last1,
+      _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
+{
+    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
+    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
+    return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_MERGE_H
diff --git a/include/__algorithm/min.h b/include/__algorithm/min.h
new file mode 100644
index 0000000..9fea7f7
--- /dev/null
+++ b/include/__algorithm/min.h
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_MIN_H
+#define _LIBCPP___ALGORITHM_MIN_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/min_element.h>
+#include <initializer_list>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Tp&
+min(const _Tp& __a, const _Tp& __b, _Compare __comp)
+{
+    return __comp(__b, __a) ? __b : __a;
+}
+
+template <class _Tp>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Tp&
+min(const _Tp& __a, const _Tp& __b)
+{
+    return _VSTD::min(__a, __b, __less<_Tp>());
+}
+
+#ifndef _LIBCPP_CXX03_LANG
+
+template<class _Tp, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp
+min(initializer_list<_Tp> __t, _Compare __comp)
+{
+    return *_VSTD::min_element(__t.begin(), __t.end(), __comp);
+}
+
+template<class _Tp>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp
+min(initializer_list<_Tp> __t)
+{
+    return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>());
+}
+
+#endif // _LIBCPP_CXX03_LANG
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_MIN_H
diff --git a/include/__algorithm/min_element.h b/include/__algorithm/min_element.h
new file mode 100644
index 0000000..6bff140
--- /dev/null
+++ b/include/__algorithm/min_element.h
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_MIN_ELEMENT_H
+#define _LIBCPP___ALGORITHM_MIN_ELEMENT_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_ForwardIterator
+min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+    static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
+        "std::min_element requires a ForwardIterator");
+    if (__first != __last)
+    {
+        _ForwardIterator __i = __first;
+        while (++__i != __last)
+            if (__comp(*__i, *__first))
+                __first = __i;
+    }
+    return __first;
+}
+
+template <class _ForwardIterator>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_ForwardIterator
+min_element(_ForwardIterator __first, _ForwardIterator __last)
+{
+    return _VSTD::min_element(__first, __last,
+              __less<typename iterator_traits<_ForwardIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_MIN_ELEMENT_H
diff --git a/include/__algorithm/minmax.h b/include/__algorithm/minmax.h
new file mode 100644
index 0000000..63753f2
--- /dev/null
+++ b/include/__algorithm/minmax.h
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_MINMAX_H
+#define _LIBCPP___ALGORITHM_MINMAX_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <initializer_list>
+#include <utility>
+
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template<class _Tp, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<const _Tp&, const _Tp&>
+minmax(const _Tp& __a, const _Tp& __b, _Compare __comp)
+{
+    return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) :
+                              pair<const _Tp&, const _Tp&>(__a, __b);
+}
+
+template<class _Tp>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<const _Tp&, const _Tp&>
+minmax(const _Tp& __a, const _Tp& __b)
+{
+    return _VSTD::minmax(__a, __b, __less<_Tp>());
+}
+
+#ifndef _LIBCPP_CXX03_LANG
+
+template<class _Tp, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Tp, _Tp>
+minmax(initializer_list<_Tp> __t, _Compare __comp)
+{
+    typedef typename initializer_list<_Tp>::const_iterator _Iter;
+    _Iter __first = __t.begin();
+    _Iter __last  = __t.end();
+    pair<_Tp, _Tp> __result(*__first, *__first);
+
+    ++__first;
+    if (__t.size() % 2 == 0)
+    {
+        if (__comp(*__first,  __result.first))
+            __result.first  = *__first;
+        else
+            __result.second = *__first;
+        ++__first;
+    }
+
+    while (__first != __last)
+    {
+        _Tp __prev = *__first++;
+        if (__comp(*__first, __prev)) {
+            if ( __comp(*__first, __result.first)) __result.first  = *__first;
+            if (!__comp(__prev, __result.second))  __result.second = __prev;
+            }
+        else {
+            if ( __comp(__prev, __result.first))    __result.first  = __prev;
+            if (!__comp(*__first, __result.second)) __result.second = *__first;
+            }
+
+        __first++;
+    }
+    return __result;
+}
+
+template<class _Tp>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Tp, _Tp>
+minmax(initializer_list<_Tp> __t)
+{
+    return _VSTD::minmax(__t, __less<_Tp>());
+}
+
+#endif // _LIBCPP_CXX03_LANG
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_MINMAX_H
diff --git a/include/__algorithm/minmax_element.h b/include/__algorithm/minmax_element.h
new file mode 100644
index 0000000..1eba006
--- /dev/null
+++ b/include/__algorithm/minmax_element.h
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H
+#define _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__iterator/iterator_traits.h>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator, class _Compare>
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_ForwardIterator, _ForwardIterator>
+minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+  static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
+        "std::minmax_element requires a ForwardIterator");
+  pair<_ForwardIterator, _ForwardIterator> __result(__first, __first);
+  if (__first != __last)
+  {
+      if (++__first != __last)
+      {
+          if (__comp(*__first, *__result.first))
+              __result.first = __first;
+          else
+              __result.second = __first;
+          while (++__first != __last)
+          {
+              _ForwardIterator __i = __first;
+              if (++__first == __last)
+              {
+                  if (__comp(*__i, *__result.first))
+                      __result.first = __i;
+                  else if (!__comp(*__i, *__result.second))
+                      __result.second = __i;
+                  break;
+              }
+              else
+              {
+                  if (__comp(*__first, *__i))
+                  {
+                      if (__comp(*__first, *__result.first))
+                          __result.first = __first;
+                      if (!__comp(*__i, *__result.second))
+                          __result.second = __i;
+                  }
+                  else
+                  {
+                      if (__comp(*__i, *__result.first))
+                          __result.first = __i;
+                      if (!__comp(*__first, *__result.second))
+                          __result.second = __first;
+                  }
+              }
+          }
+      }
+  }
+  return __result;
+}
+
+template <class _ForwardIterator>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_ForwardIterator, _ForwardIterator>
+minmax_element(_ForwardIterator __first, _ForwardIterator __last)
+{
+    return _VSTD::minmax_element(__first, __last,
+              __less<typename iterator_traits<_ForwardIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H
diff --git a/include/__algorithm/mismatch.h b/include/__algorithm/mismatch.h
new file mode 100644
index 0000000..fdd2bc8
--- /dev/null
+++ b/include/__algorithm/mismatch.h
@@ -0,0 +1,72 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_MISMATCH_H
+#define _LIBCPP___ALGORITHM_MISMATCH_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__iterator/iterator_traits.h>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2>
+    mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
+  for (; __first1 != __last1; ++__first1, (void)++__first2)
+    if (!__pred(*__first1, *__first2))
+      break;
+  return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
+}
+
+template <class _InputIterator1, class _InputIterator2>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2>
+    mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
+  typedef typename iterator_traits<_InputIterator1>::value_type __v1;
+  typedef typename iterator_traits<_InputIterator2>::value_type __v2;
+  return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>());
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2>
+    mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
+             _BinaryPredicate __pred) {
+  for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
+    if (!__pred(*__first1, *__first2))
+      break;
+  return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
+}
+
+template <class _InputIterator1, class _InputIterator2>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2>
+    mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
+  typedef typename iterator_traits<_InputIterator1>::value_type __v1;
+  typedef typename iterator_traits<_InputIterator2>::value_type __v2;
+  return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_MISMATCH_H
diff --git a/include/__algorithm/move.h b/include/__algorithm/move.h
new file mode 100644
index 0000000..f5fc748
--- /dev/null
+++ b/include/__algorithm/move.h
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_MOVE_H
+#define _LIBCPP___ALGORITHM_MOVE_H
+
+#include <__config>
+#include <__algorithm/unwrap_iter.h>
+#include <__utility/move.h>
+#include <cstring>
+#include <utility>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// move
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+_OutputIterator
+__move_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    for (; __first != __last; ++__first, (void) ++__result)
+        *__result = _VSTD::move(*__first);
+    return __result;
+}
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+_OutputIterator
+__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    return _VSTD::__move_constexpr(__first, __last, __result);
+}
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+typename enable_if
+<
+    is_same<typename remove_const<_Tp>::type, _Up>::value &&
+    is_trivially_move_assignable<_Up>::value,
+    _Up*
+>::type
+__move(_Tp* __first, _Tp* __last, _Up* __result)
+{
+    const size_t __n = static_cast<size_t>(__last - __first);
+    if (__n > 0)
+        _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+    return __result + __n;
+}
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    if (__libcpp_is_constant_evaluated()) {
+        return _VSTD::__move_constexpr(__first, __last, __result);
+    } else {
+        return _VSTD::__rewrap_iter(__result,
+            _VSTD::__move(_VSTD::__unwrap_iter(__first),
+                          _VSTD::__unwrap_iter(__last),
+                          _VSTD::__unwrap_iter(__result)));
+    }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_MOVE_H
diff --git a/include/__algorithm/move_backward.h b/include/__algorithm/move_backward.h
new file mode 100644
index 0000000..1c93b98
--- /dev/null
+++ b/include/__algorithm/move_backward.h
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
+#define _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
+
+#include <__config>
+#include <__algorithm/unwrap_iter.h>
+#include <cstring>
+#include <utility>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+_OutputIterator
+__move_backward_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    while (__first != __last)
+        *--__result = _VSTD::move(*--__last);
+    return __result;
+}
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+_OutputIterator
+__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    return _VSTD::__move_backward_constexpr(__first, __last, __result);
+}
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+typename enable_if
+<
+    is_same<typename remove_const<_Tp>::type, _Up>::value &&
+    is_trivially_move_assignable<_Up>::value,
+    _Up*
+>::type
+__move_backward(_Tp* __first, _Tp* __last, _Up* __result)
+{
+    const size_t __n = static_cast<size_t>(__last - __first);
+    if (__n > 0)
+    {
+        __result -= __n;
+        _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+    }
+    return __result;
+}
+
+template <class _BidirectionalIterator1, class _BidirectionalIterator2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_BidirectionalIterator2
+move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
+              _BidirectionalIterator2 __result)
+{
+    if (__libcpp_is_constant_evaluated()) {
+        return _VSTD::__move_backward_constexpr(__first, __last, __result);
+    } else {
+        return _VSTD::__rewrap_iter(__result,
+            _VSTD::__move_backward(_VSTD::__unwrap_iter(__first),
+                                   _VSTD::__unwrap_iter(__last),
+                                   _VSTD::__unwrap_iter(__result)));
+    }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
diff --git a/include/__algorithm/next_permutation.h b/include/__algorithm/next_permutation.h
new file mode 100644
index 0000000..a337e5e
--- /dev/null
+++ b/include/__algorithm/next_permutation.h
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H
+#define _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/reverse.h>
+#include <__iterator/iterator_traits.h>
+#include <__utility/swap.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _BidirectionalIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+__next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
+{
+    _BidirectionalIterator __i = __last;
+    if (__first == __last || __first == --__i)
+        return false;
+    while (true)
+    {
+        _BidirectionalIterator __ip1 = __i;
+        if (__comp(*--__i, *__ip1))
+        {
+            _BidirectionalIterator __j = __last;
+            while (!__comp(*__i, *--__j))
+                ;
+            swap(*__i, *__j);
+            _VSTD::reverse(__ip1, __last);
+            return true;
+        }
+        if (__i == __first)
+        {
+            _VSTD::reverse(__first, __last);
+            return false;
+        }
+    }
+}
+
+template <class _BidirectionalIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    return _VSTD::__next_permutation<_Comp_ref>(__first, __last, __comp);
+}
+
+template <class _BidirectionalIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
+{
+    return _VSTD::next_permutation(__first, __last,
+                                  __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H
diff --git a/include/__algorithm/none_of.h b/include/__algorithm/none_of.h
new file mode 100644
index 0000000..2856915
--- /dev/null
+++ b/include/__algorithm/none_of.h
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_NONE_OF_H
+#define _LIBCPP___ALGORITHM_NONE_OF_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _Predicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
+  for (; __first != __last; ++__first)
+    if (__pred(*__first))
+      return false;
+  return true;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_NONE_OF_H
diff --git a/include/__algorithm/nth_element.h b/include/__algorithm/nth_element.h
new file mode 100644
index 0000000..67a03cf
--- /dev/null
+++ b/include/__algorithm/nth_element.h
@@ -0,0 +1,244 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_NTH_ELEMENT_H
+#define _LIBCPP___ALGORITHM_NTH_ELEMENT_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/sort.h>
+#include <__iterator/iterator_traits.h>
+#include <__utility/swap.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template<class _Compare, class _RandomAccessIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 bool
+__nth_element_find_guard(_RandomAccessIterator& __i, _RandomAccessIterator& __j,
+                         _RandomAccessIterator __m, _Compare __comp)
+{
+    // manually guard downward moving __j against __i
+    while (true) {
+        if (__i == --__j) {
+            return false;
+        }
+        if (__comp(*__j, *__m)) {
+            return true;  // found guard for downward moving __j, now use unguarded partition
+        }
+    }
+}
+
+template <class _Compare, class _RandomAccessIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 void
+__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
+{
+    // _Compare is known to be a reference type
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    const difference_type __limit = 7;
+    while (true)
+    {
+        if (__nth == __last)
+            return;
+        difference_type __len = __last - __first;
+        switch (__len)
+        {
+        case 0:
+        case 1:
+            return;
+        case 2:
+            if (__comp(*--__last, *__first))
+                swap(*__first, *__last);
+            return;
+        case 3:
+            {
+            _RandomAccessIterator __m = __first;
+            _VSTD::__sort3<_Compare>(__first, ++__m, --__last, __comp);
+            return;
+            }
+        }
+        if (__len <= __limit)
+        {
+            _VSTD::__selection_sort<_Compare>(__first, __last, __comp);
+            return;
+        }
+        // __len > __limit >= 3
+        _RandomAccessIterator __m = __first + __len/2;
+        _RandomAccessIterator __lm1 = __last;
+        unsigned __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, --__lm1, __comp);
+        // *__m is median
+        // partition [__first, __m) < *__m and *__m <= [__m, __last)
+        // (this inhibits tossing elements equivalent to __m around unnecessarily)
+        _RandomAccessIterator __i = __first;
+        _RandomAccessIterator __j = __lm1;
+        // j points beyond range to be tested, *__lm1 is known to be <= *__m
+        // The search going up is known to be guarded but the search coming down isn't.
+        // Prime the downward search with a guard.
+        if (!__comp(*__i, *__m))  // if *__first == *__m
+        {
+            // *__first == *__m, *__first doesn't go in first part
+            if (_VSTD::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) {
+                swap(*__i, *__j);
+                ++__n_swaps;
+            } else {
+                // *__first == *__m, *__m <= all other elements
+                // Partition instead into [__first, __i) == *__first and *__first < [__i, __last)
+                ++__i;  // __first + 1
+                __j = __last;
+                if (!__comp(*__first, *--__j)) {  // we need a guard if *__first == *(__last-1)
+                    while (true) {
+                        if (__i == __j) {
+                            return;  // [__first, __last) all equivalent elements
+                        } else if (__comp(*__first, *__i)) {
+                            swap(*__i, *__j);
+                            ++__n_swaps;
+                            ++__i;
+                            break;
+                        }
+                        ++__i;
+                    }
+                }
+                // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
+                if (__i == __j) {
+                    return;
+                }
+                while (true) {
+                    while (!__comp(*__first, *__i))
+                        ++__i;
+                    while (__comp(*__first, *--__j))
+                        ;
+                    if (__i >= __j)
+                        break;
+                    swap(*__i, *__j);
+                    ++__n_swaps;
+                    ++__i;
+                }
+                // [__first, __i) == *__first and *__first < [__i, __last)
+                // The first part is sorted,
+                if (__nth < __i) {
+                    return;
+                }
+                // __nth_element the second part
+                // _VSTD::__nth_element<_Compare>(__i, __nth, __last, __comp);
+                __first = __i;
+                continue;
+            }
+        }
+        ++__i;
+        // j points beyond range to be tested, *__lm1 is known to be <= *__m
+        // if not yet partitioned...
+        if (__i < __j)
+        {
+            // known that *(__i - 1) < *__m
+            while (true)
+            {
+                // __m still guards upward moving __i
+                while (__comp(*__i, *__m))
+                    ++__i;
+                // It is now known that a guard exists for downward moving __j
+                while (!__comp(*--__j, *__m))
+                    ;
+                if (__i >= __j)
+                    break;
+                swap(*__i, *__j);
+                ++__n_swaps;
+                // It is known that __m != __j
+                // If __m just moved, follow it
+                if (__m == __i)
+                    __m = __j;
+                ++__i;
+            }
+        }
+        // [__first, __i) < *__m and *__m <= [__i, __last)
+        if (__i != __m && __comp(*__m, *__i))
+        {
+            swap(*__i, *__m);
+            ++__n_swaps;
+        }
+        // [__first, __i) < *__i and *__i <= [__i+1, __last)
+        if (__nth == __i)
+            return;
+        if (__n_swaps == 0)
+        {
+            // We were given a perfectly partitioned sequence.  Coincidence?
+            if (__nth < __i)
+            {
+                // Check for [__first, __i) already sorted
+                __j = __m = __first;
+                while (true) {
+                    if (++__j == __i) {
+                        // [__first, __i) sorted
+                        return;
+                    }
+                    if (__comp(*__j, *__m)) {
+                        // not yet sorted, so sort
+                        break;
+                    }
+                    __m = __j;
+                }
+            }
+            else
+            {
+                // Check for [__i, __last) already sorted
+                __j = __m = __i;
+                while (true) {
+                    if (++__j == __last) {
+                        // [__i, __last) sorted
+                        return;
+                    }
+                    if (__comp(*__j, *__m)) {
+                        // not yet sorted, so sort
+                        break;
+                    }
+                    __m = __j;
+                }
+            }
+        }
+        // __nth_element on range containing __nth
+        if (__nth < __i)
+        {
+            // _VSTD::__nth_element<_Compare>(__first, __nth, __i, __comp);
+            __last = __i;
+        }
+        else
+        {
+            // _VSTD::__nth_element<_Compare>(__i+1, __nth, __last, __comp);
+            __first = ++__i;
+        }
+    }
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    _VSTD::__nth_element<_Comp_ref>(__first, __nth, __last, __comp);
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last)
+{
+    _VSTD::nth_element(__first, __nth, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_NTH_ELEMENT_H
diff --git a/include/__algorithm/partial_sort.h b/include/__algorithm/partial_sort.h
new file mode 100644
index 0000000..4f9872c
--- /dev/null
+++ b/include/__algorithm/partial_sort.h
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_H
+#define _LIBCPP___ALGORITHM_PARTIAL_SORT_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/make_heap.h>
+#include <__algorithm/sift_down.h>
+#include <__algorithm/sort_heap.h>
+#include <__iterator/iterator_traits.h>
+#include <__utility/swap.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _RandomAccessIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 void
+__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
+             _Compare __comp)
+{
+    _VSTD::__make_heap<_Compare>(__first, __middle, __comp);
+    typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;
+    for (_RandomAccessIterator __i = __middle; __i != __last; ++__i)
+    {
+        if (__comp(*__i, *__first))
+        {
+            swap(*__i, *__first);
+            _VSTD::__sift_down<_Compare>(__first, __middle, __comp, __len, __first);
+        }
+    }
+    _VSTD::__sort_heap<_Compare>(__first, __middle, __comp);
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
+             _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    _VSTD::__partial_sort<_Comp_ref>(__first, __middle, __last, __comp);
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
+{
+    _VSTD::partial_sort(__first, __middle, __last,
+                       __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_H
diff --git a/include/__algorithm/partial_sort_copy.h b/include/__algorithm/partial_sort_copy.h
new file mode 100644
index 0000000..31a1261
--- /dev/null
+++ b/include/__algorithm/partial_sort_copy.h
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H
+#define _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/make_heap.h>
+#include <__algorithm/sift_down.h>
+#include <__algorithm/sort_heap.h>
+#include <__iterator/iterator_traits.h>
+#include <type_traits> // swap
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _InputIterator, class _RandomAccessIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
+__partial_sort_copy(_InputIterator __first, _InputIterator __last,
+                    _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
+{
+    _RandomAccessIterator __r = __result_first;
+    if (__r != __result_last)
+    {
+        for (; __first != __last && __r != __result_last; ++__first, (void) ++__r)
+            *__r = *__first;
+        _VSTD::__make_heap<_Compare>(__result_first, __r, __comp);
+        typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first;
+        for (; __first != __last; ++__first)
+            if (__comp(*__first, *__result_first))
+            {
+                *__result_first = *__first;
+                _VSTD::__sift_down<_Compare>(__result_first, __r, __comp, __len, __result_first);
+            }
+        _VSTD::__sort_heap<_Compare>(__result_first, __r, __comp);
+    }
+    return __r;
+}
+
+template <class _InputIterator, class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_RandomAccessIterator
+partial_sort_copy(_InputIterator __first, _InputIterator __last,
+                  _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    return _VSTD::__partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp);
+}
+
+template <class _InputIterator, class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_RandomAccessIterator
+partial_sort_copy(_InputIterator __first, _InputIterator __last,
+                  _RandomAccessIterator __result_first, _RandomAccessIterator __result_last)
+{
+    return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last,
+                                   __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H
diff --git a/include/__algorithm/partition.h b/include/__algorithm/partition.h
new file mode 100644
index 0000000..c859eac
--- /dev/null
+++ b/include/__algorithm/partition.h
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PARTITION_H
+#define _LIBCPP___ALGORITHM_PARTITION_H
+
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__utility/swap.h>
+#include <utility> // pair
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Predicate, class _ForwardIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+__partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag)
+{
+    while (true)
+    {
+        if (__first == __last)
+            return __first;
+        if (!__pred(*__first))
+            break;
+        ++__first;
+    }
+    for (_ForwardIterator __p = __first; ++__p != __last;)
+    {
+        if (__pred(*__p))
+        {
+            swap(*__first, *__p);
+            ++__first;
+        }
+    }
+    return __first;
+}
+
+template <class _Predicate, class _BidirectionalIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator
+__partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
+            bidirectional_iterator_tag)
+{
+    while (true)
+    {
+        while (true)
+        {
+            if (__first == __last)
+                return __first;
+            if (!__pred(*__first))
+                break;
+            ++__first;
+        }
+        do
+        {
+            if (__first == --__last)
+                return __first;
+        } while (!__pred(*__last));
+        swap(*__first, *__last);
+        ++__first;
+    }
+}
+
+template <class _ForwardIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator
+partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
+{
+    return _VSTD::__partition<typename add_lvalue_reference<_Predicate>::type>
+                            (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PARTITION_H
diff --git a/include/__algorithm/partition_copy.h b/include/__algorithm/partition_copy.h
new file mode 100644
index 0000000..445eacd
--- /dev/null
+++ b/include/__algorithm/partition_copy.h
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PARTITION_COPY_H
+#define _LIBCPP___ALGORITHM_PARTITION_COPY_H
+
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <utility> // pair
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _OutputIterator1,
+          class _OutputIterator2, class _Predicate>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_OutputIterator1, _OutputIterator2>
+partition_copy(_InputIterator __first, _InputIterator __last,
+               _OutputIterator1 __out_true, _OutputIterator2 __out_false,
+               _Predicate __pred)
+{
+    for (; __first != __last; ++__first)
+    {
+        if (__pred(*__first))
+        {
+            *__out_true = *__first;
+            ++__out_true;
+        }
+        else
+        {
+            *__out_false = *__first;
+            ++__out_false;
+        }
+    }
+    return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PARTITION_COPY_H
diff --git a/include/__algorithm/partition_point.h b/include/__algorithm/partition_point.h
new file mode 100644
index 0000000..12ddacf
--- /dev/null
+++ b/include/__algorithm/partition_point.h
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PARTITION_POINT_H
+#define _LIBCPP___ALGORITHM_PARTITION_POINT_H
+
+#include <__config>
+#include <__algorithm/half_positive.h>
+#include <iterator>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template<class _ForwardIterator, class _Predicate>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
+{
+    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
+    difference_type __len = _VSTD::distance(__first, __last);
+    while (__len != 0)
+    {
+        difference_type __l2 = _VSTD::__half_positive(__len);
+        _ForwardIterator __m = __first;
+        _VSTD::advance(__m, __l2);
+        if (__pred(*__m))
+        {
+            __first = ++__m;
+            __len -= __l2 + 1;
+        }
+        else
+            __len = __l2;
+    }
+    return __first;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PARTITION_POINT_H
diff --git a/include/__algorithm/pop_heap.h b/include/__algorithm/pop_heap.h
new file mode 100644
index 0000000..7ebbef2
--- /dev/null
+++ b/include/__algorithm/pop_heap.h
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_POP_HEAP_H
+#define _LIBCPP___ALGORITHM_POP_HEAP_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/sift_down.h>
+#include <__iterator/iterator_traits.h>
+#include <__utility/swap.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
+           typename iterator_traits<_RandomAccessIterator>::difference_type __len)
+{
+    if (__len > 1)
+    {
+        swap(*__first, *--__last);
+        _VSTD::__sift_down<_Compare>(__first, __last, __comp, __len - 1, __first);
+    }
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    _VSTD::__pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first);
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    _VSTD::pop_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_POP_HEAP_H
diff --git a/include/__algorithm/prev_permutation.h b/include/__algorithm/prev_permutation.h
new file mode 100644
index 0000000..d6daa73
--- /dev/null
+++ b/include/__algorithm/prev_permutation.h
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
+#define _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/reverse.h>
+#include <__iterator/iterator_traits.h>
+#include <__utility/swap.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _BidirectionalIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+__prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
+{
+    _BidirectionalIterator __i = __last;
+    if (__first == __last || __first == --__i)
+        return false;
+    while (true)
+    {
+        _BidirectionalIterator __ip1 = __i;
+        if (__comp(*__ip1, *--__i))
+        {
+            _BidirectionalIterator __j = __last;
+            while (!__comp(*--__j, *__i))
+                ;
+            swap(*__i, *__j);
+            _VSTD::reverse(__ip1, __last);
+            return true;
+        }
+        if (__i == __first)
+        {
+            _VSTD::reverse(__first, __last);
+            return false;
+        }
+    }
+}
+
+template <class _BidirectionalIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    return _VSTD::__prev_permutation<_Comp_ref>(__first, __last, __comp);
+}
+
+template <class _BidirectionalIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool
+prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
+{
+    return _VSTD::prev_permutation(__first, __last,
+                                  __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
diff --git a/include/__algorithm/push_heap.h b/include/__algorithm/push_heap.h
new file mode 100644
index 0000000..82a7c12
--- /dev/null
+++ b/include/__algorithm/push_heap.h
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PUSH_HEAP_H
+#define _LIBCPP___ALGORITHM_PUSH_HEAP_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__iterator/iterator_traits.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _RandomAccessIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 void
+__sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
+          typename iterator_traits<_RandomAccessIterator>::difference_type __len)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    if (__len > 1)
+    {
+        __len = (__len - 2) / 2;
+        _RandomAccessIterator __ptr = __first + __len;
+        if (__comp(*__ptr, *--__last))
+        {
+            value_type __t(_VSTD::move(*__last));
+            do
+            {
+                *__last = _VSTD::move(*__ptr);
+                __last = __ptr;
+                if (__len == 0)
+                    break;
+                __len = (__len - 1) / 2;
+                __ptr = __first + __len;
+            } while (__comp(*__ptr, __t));
+            *__last = _VSTD::move(__t);
+        }
+    }
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    _VSTD::__sift_up<_Comp_ref>(__first, __last, __comp, __last - __first);
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    _VSTD::push_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H
diff --git a/include/__algorithm/remove.h b/include/__algorithm/remove.h
new file mode 100644
index 0000000..4717d7d
--- /dev/null
+++ b/include/__algorithm/remove.h
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_REMOVE_H
+#define _LIBCPP___ALGORITHM_REMOVE_H
+
+#include <__config>
+#include <__algorithm/find.h>
+#include <__algorithm/find_if.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator, class _Tp>
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+{
+    __first = _VSTD::find(__first, __last, __value_);
+    if (__first != __last)
+    {
+        _ForwardIterator __i = __first;
+        while (++__i != __last)
+        {
+            if (!(*__i == __value_))
+            {
+                *__first = _VSTD::move(*__i);
+                ++__first;
+            }
+        }
+    }
+    return __first;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_REMOVE_H
diff --git a/include/__algorithm/remove_copy.h b/include/__algorithm/remove_copy.h
new file mode 100644
index 0000000..5d2b640
--- /dev/null
+++ b/include/__algorithm/remove_copy.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_REMOVE_COPY_H
+#define _LIBCPP___ALGORITHM_REMOVE_COPY_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _OutputIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_)
+{
+    for (; __first != __last; ++__first)
+    {
+        if (!(*__first == __value_))
+        {
+            *__result = *__first;
+            ++__result;
+        }
+    }
+    return __result;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_REMOVE_COPY_H
diff --git a/include/__algorithm/remove_copy_if.h b/include/__algorithm/remove_copy_if.h
new file mode 100644
index 0000000..4482256
--- /dev/null
+++ b/include/__algorithm/remove_copy_if.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H
+#define _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _OutputIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred)
+{
+    for (; __first != __last; ++__first)
+    {
+        if (!__pred(*__first))
+        {
+            *__result = *__first;
+            ++__result;
+        }
+    }
+    return __result;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H
diff --git a/include/__algorithm/remove_if.h b/include/__algorithm/remove_if.h
new file mode 100644
index 0000000..e506b4c
--- /dev/null
+++ b/include/__algorithm/remove_if.h
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_REMOVE_IF_H
+#define _LIBCPP___ALGORITHM_REMOVE_IF_H
+
+#include <__config>
+#include <__algorithm/find_if.h>
+#include <utility>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator, class _Predicate>
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
+{
+    __first = _VSTD::find_if<_ForwardIterator, typename add_lvalue_reference<_Predicate>::type>
+                           (__first, __last, __pred);
+    if (__first != __last)
+    {
+        _ForwardIterator __i = __first;
+        while (++__i != __last)
+        {
+            if (!__pred(*__i))
+            {
+                *__first = _VSTD::move(*__i);
+                ++__first;
+            }
+        }
+    }
+    return __first;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_REMOVE_IF_H
diff --git a/include/__algorithm/replace.h b/include/__algorithm/replace.h
new file mode 100644
index 0000000..b723ffe
--- /dev/null
+++ b/include/__algorithm/replace.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_REPLACE_H
+#define _LIBCPP___ALGORITHM_REPLACE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value)
+{
+    for (; __first != __last; ++__first)
+        if (*__first == __old_value)
+            *__first = __new_value;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_REPLACE_H
diff --git a/include/__algorithm/replace_copy.h b/include/__algorithm/replace_copy.h
new file mode 100644
index 0000000..1923a57
--- /dev/null
+++ b/include/__algorithm/replace_copy.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_REPLACE_COPY_H
+#define _LIBCPP___ALGORITHM_REPLACE_COPY_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _OutputIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
+             const _Tp& __old_value, const _Tp& __new_value)
+{
+    for (; __first != __last; ++__first, (void) ++__result)
+        if (*__first == __old_value)
+            *__result = __new_value;
+        else
+            *__result = *__first;
+    return __result;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_REPLACE_COPY_H
diff --git a/include/__algorithm/replace_copy_if.h b/include/__algorithm/replace_copy_if.h
new file mode 100644
index 0000000..72b6f73
--- /dev/null
+++ b/include/__algorithm/replace_copy_if.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H
+#define _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _OutputIterator, class _Predicate, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
+                _Predicate __pred, const _Tp& __new_value)
+{
+    for (; __first != __last; ++__first, (void) ++__result)
+        if (__pred(*__first))
+            *__result = __new_value;
+        else
+            *__result = *__first;
+    return __result;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H
diff --git a/include/__algorithm/replace_if.h b/include/__algorithm/replace_if.h
new file mode 100644
index 0000000..49101a5
--- /dev/null
+++ b/include/__algorithm/replace_if.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_REPLACE_IF_H
+#define _LIBCPP___ALGORITHM_REPLACE_IF_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator, class _Predicate, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value)
+{
+    for (; __first != __last; ++__first)
+        if (__pred(*__first))
+            *__first = __new_value;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_REPLACE_IF_H
diff --git a/include/__algorithm/reverse.h b/include/__algorithm/reverse.h
new file mode 100644
index 0000000..e538de1
--- /dev/null
+++ b/include/__algorithm/reverse.h
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_REVERSE_H
+#define _LIBCPP___ALGORITHM_REVERSE_H
+
+#include <__config>
+#include <__algorithm/iter_swap.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _BidirectionalIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag)
+{
+    while (__first != __last)
+    {
+        if (__first == --__last)
+            break;
+        _VSTD::iter_swap(__first, __last);
+        ++__first;
+    }
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag)
+{
+    if (__first != __last)
+        for (; __first < --__last; ++__first)
+            _VSTD::iter_swap(__first, __last);
+}
+
+template <class _BidirectionalIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
+{
+    _VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_REVERSE_H
diff --git a/include/__algorithm/reverse_copy.h b/include/__algorithm/reverse_copy.h
new file mode 100644
index 0000000..48ce60c
--- /dev/null
+++ b/include/__algorithm/reverse_copy.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_REVERSE_COPY_H
+#define _LIBCPP___ALGORITHM_REVERSE_COPY_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _BidirectionalIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
+{
+    for (; __first != __last; ++__result)
+        *__result = *--__last;
+    return __result;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_REVERSE_COPY_H
diff --git a/include/__algorithm/rotate.h b/include/__algorithm/rotate.h
new file mode 100644
index 0000000..0c9ccd7
--- /dev/null
+++ b/include/__algorithm/rotate.h
@@ -0,0 +1,205 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_ROTATE_H
+#define _LIBCPP___ALGORITHM_ROTATE_H
+
+#include <__algorithm/move.h>
+#include <__algorithm/move_backward.h>
+#include <__algorithm/swap_ranges.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__iterator/prev.h>
+#include <__utility/swap.h>
+#include <iterator>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
+__rotate_left(_ForwardIterator __first, _ForwardIterator __last)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+    value_type __tmp = _VSTD::move(*__first);
+    _ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first);
+    *__lm1 = _VSTD::move(__tmp);
+    return __lm1;
+}
+
+template <class _BidirectionalIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator
+__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last)
+{
+    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+    _BidirectionalIterator __lm1 = _VSTD::prev(__last);
+    value_type __tmp = _VSTD::move(*__lm1);
+    _BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last);
+    *__first = _VSTD::move(__tmp);
+    return __fp1;
+}
+
+template <class _ForwardIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX14 _ForwardIterator
+__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
+{
+    _ForwardIterator __i = __middle;
+    while (true)
+    {
+        swap(*__first, *__i);
+        ++__first;
+        if (++__i == __last)
+            break;
+        if (__first == __middle)
+            __middle = __i;
+    }
+    _ForwardIterator __r = __first;
+    if (__first != __middle)
+    {
+        __i = __middle;
+        while (true)
+        {
+            swap(*__first, *__i);
+            ++__first;
+            if (++__i == __last)
+            {
+                if (__first == __middle)
+                    break;
+                __i = __middle;
+            }
+            else if (__first == __middle)
+                __middle = __i;
+        }
+    }
+    return __r;
+}
+
+template<typename _Integral>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR_AFTER_CXX14 _Integral
+__algo_gcd(_Integral __x, _Integral __y)
+{
+    do
+    {
+        _Integral __t = __x % __y;
+        __x = __y;
+        __y = __t;
+    } while (__y);
+    return __x;
+}
+
+template<typename _RandomAccessIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX14 _RandomAccessIterator
+__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+
+    const difference_type __m1 = __middle - __first;
+    const difference_type __m2 = __last - __middle;
+    if (__m1 == __m2)
+    {
+        _VSTD::swap_ranges(__first, __middle, __middle);
+        return __middle;
+    }
+    const difference_type __g = _VSTD::__algo_gcd(__m1, __m2);
+    for (_RandomAccessIterator __p = __first + __g; __p != __first;)
+    {
+        value_type __t(_VSTD::move(*--__p));
+        _RandomAccessIterator __p1 = __p;
+        _RandomAccessIterator __p2 = __p1 + __m1;
+        do
+        {
+            *__p1 = _VSTD::move(*__p2);
+            __p1 = __p2;
+            const difference_type __d = __last - __p2;
+            if (__m1 < __d)
+                __p2 += __m1;
+            else
+                __p2 = __first + (__m1 - __d);
+        } while (__p2 != __p);
+        *__p1 = _VSTD::move(__t);
+    }
+    return __first + __m2;
+}
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
+__rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
+         _VSTD::forward_iterator_tag)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+    if (is_trivially_move_assignable<value_type>::value)
+    {
+        if (_VSTD::next(__first) == __middle)
+            return _VSTD::__rotate_left(__first, __last);
+    }
+    return _VSTD::__rotate_forward(__first, __middle, __last);
+}
+
+template <class _BidirectionalIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator
+__rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
+         bidirectional_iterator_tag)
+{
+    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+    if (is_trivially_move_assignable<value_type>::value)
+    {
+        if (_VSTD::next(__first) == __middle)
+            return _VSTD::__rotate_left(__first, __last);
+        if (_VSTD::next(__middle) == __last)
+            return _VSTD::__rotate_right(__first, __last);
+    }
+    return _VSTD::__rotate_forward(__first, __middle, __last);
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator
+__rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
+         random_access_iterator_tag)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    if (is_trivially_move_assignable<value_type>::value)
+    {
+        if (_VSTD::next(__first) == __middle)
+            return _VSTD::__rotate_left(__first, __last);
+        if (_VSTD::next(__middle) == __last)
+            return _VSTD::__rotate_right(__first, __last);
+        return _VSTD::__rotate_gcd(__first, __middle, __last);
+    }
+    return _VSTD::__rotate_forward(__first, __middle, __last);
+}
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
+{
+    if (__first == __middle)
+        return __last;
+    if (__middle == __last)
+        return __first;
+    return _VSTD::__rotate(__first, __middle, __last,
+                           typename iterator_traits<_ForwardIterator>::iterator_category());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_ROTATE_H
diff --git a/include/__algorithm/rotate_copy.h b/include/__algorithm/rotate_copy.h
new file mode 100644
index 0000000..d5ab7d3
--- /dev/null
+++ b/include/__algorithm/rotate_copy.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_ROTATE_COPY_H
+#define _LIBCPP___ALGORITHM_ROTATE_COPY_H
+
+#include <__config>
+#include <__algorithm/copy.h>
+#include <iterator>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result)
+{
+    return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_ROTATE_COPY_H
diff --git a/include/__algorithm/sample.h b/include/__algorithm/sample.h
new file mode 100644
index 0000000..2aac6ff
--- /dev/null
+++ b/include/__algorithm/sample.h
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SAMPLE_H
+#define _LIBCPP___ALGORITHM_SAMPLE_H
+
+#include <__config>
+#include <__algorithm/min.h>
+#include <__random/uniform_int_distribution.h>
+#include <iterator>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _PopulationIterator, class _SampleIterator, class _Distance,
+          class _UniformRandomNumberGenerator>
+_LIBCPP_INLINE_VISIBILITY
+_SampleIterator __sample(_PopulationIterator __first,
+                         _PopulationIterator __last, _SampleIterator __output_iter,
+                         _Distance __n,
+                         _UniformRandomNumberGenerator & __g,
+                         input_iterator_tag) {
+
+  _Distance __k = 0;
+  for (; __first != __last && __k < __n; ++__first, (void) ++__k)
+    __output_iter[__k] = *__first;
+  _Distance __sz = __k;
+  for (; __first != __last; ++__first, (void) ++__k) {
+    _Distance __r = uniform_int_distribution<_Distance>(0, __k)(__g);
+    if (__r < __sz)
+      __output_iter[__r] = *__first;
+  }
+  return __output_iter + _VSTD::min(__n, __k);
+}
+
+template <class _PopulationIterator, class _SampleIterator, class _Distance,
+          class _UniformRandomNumberGenerator>
+_LIBCPP_INLINE_VISIBILITY
+_SampleIterator __sample(_PopulationIterator __first,
+                         _PopulationIterator __last, _SampleIterator __output_iter,
+                         _Distance __n,
+                         _UniformRandomNumberGenerator& __g,
+                         forward_iterator_tag) {
+  _Distance __unsampled_sz = _VSTD::distance(__first, __last);
+  for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) {
+    _Distance __r = uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g);
+    if (__r < __n) {
+      *__output_iter++ = *__first;
+      --__n;
+    }
+  }
+  return __output_iter;
+}
+
+template <class _PopulationIterator, class _SampleIterator, class _Distance,
+          class _UniformRandomNumberGenerator>
+_LIBCPP_INLINE_VISIBILITY
+_SampleIterator __sample(_PopulationIterator __first,
+                         _PopulationIterator __last, _SampleIterator __output_iter,
+                         _Distance __n, _UniformRandomNumberGenerator& __g) {
+  typedef typename iterator_traits<_PopulationIterator>::iterator_category
+        _PopCategory;
+  typedef typename iterator_traits<_PopulationIterator>::difference_type
+        _Difference;
+  static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value ||
+                __is_cpp17_random_access_iterator<_SampleIterator>::value,
+                "SampleIterator must meet the requirements of RandomAccessIterator");
+  typedef typename common_type<_Distance, _Difference>::type _CommonType;
+  _LIBCPP_ASSERT(__n >= 0, "N must be a positive number.");
+  return _VSTD::__sample(
+      __first, __last, __output_iter, _CommonType(__n),
+      __g, _PopCategory());
+}
+
+#if _LIBCPP_STD_VER > 14
+template <class _PopulationIterator, class _SampleIterator, class _Distance,
+          class _UniformRandomNumberGenerator>
+inline _LIBCPP_INLINE_VISIBILITY
+_SampleIterator sample(_PopulationIterator __first,
+                       _PopulationIterator __last, _SampleIterator __output_iter,
+                       _Distance __n, _UniformRandomNumberGenerator&& __g) {
+    return _VSTD::__sample(__first, __last, __output_iter, __n, __g);
+}
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SAMPLE_H
diff --git a/include/__algorithm/search.h b/include/__algorithm/search.h
new file mode 100644
index 0000000..008b8eb
--- /dev/null
+++ b/include/__algorithm/search.h
@@ -0,0 +1,131 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SEARCH_H
+#define _LIBCPP___ALGORITHM_SEARCH_H
+
+#include <__algorithm/comp.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <type_traits>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
+pair<_ForwardIterator1, _ForwardIterator1>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+                                           _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+                                           _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) {
+  if (__first2 == __last2)
+    return _VSTD::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 _VSTD::make_pair(__last1, __last1);
+      if (__pred(*__first1, *__first2))
+        break;
+      ++__first1;
+    }
+    // *__first1 matches *__first2, now match elements after here
+    _ForwardIterator1 __m1 = __first1;
+    _ForwardIterator2 __m2 = __first2;
+    while (true) {
+      if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern)
+        return _VSTD::make_pair(__first1, __m1);
+      if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found
+        return _VSTD::make_pair(__last1, __last1);
+      if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1
+      {
+        ++__first1;
+        break;
+      } // else there is a match, check next elements
+    }
+  }
+}
+
+template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 pair<_RandomAccessIterator1, _RandomAccessIterator1>
+__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
+         _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag,
+         random_access_iterator_tag) {
+  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
+  const _D2 __len2 = __last2 - __first2;
+  if (__len2 == 0)
+    return _VSTD::make_pair(__first1, __first1);
+  const _D1 __len1 = __last1 - __first1;
+  if (__len1 < __len2)
+    return _VSTD::make_pair(__last1, __last1);
+  const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here
+
+  while (true) {
+    while (true) {
+      if (__first1 == __s)
+        return _VSTD::make_pair(__last1, __last1);
+      if (__pred(*__first1, *__first2))
+        break;
+      ++__first1;
+    }
+
+    _RandomAccessIterator1 __m1 = __first1;
+    _RandomAccessIterator2 __m2 = __first2;
+    while (true) {
+      if (++__m2 == __last2)
+        return _VSTD::make_pair(__first1, __first1 + __len2);
+      ++__m1; // no need to check range on __m1 because __s guarantees we have enough source
+      if (!__pred(*__m1, *__m2)) {
+        ++__first1;
+        break;
+      }
+    }
+  }
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
+search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+       _BinaryPredicate __pred) {
+  return _VSTD::__search<typename add_lvalue_reference<_BinaryPredicate>::type>(
+             __first1, __last1, __first2, __last2, __pred,
+             typename iterator_traits<_ForwardIterator1>::iterator_category(),
+             typename iterator_traits<_ForwardIterator2>::iterator_category()).first;
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
+search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
+  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>());
+}
+
+#if _LIBCPP_STD_VER > 14
+template <class _ForwardIterator, class _Searcher>
+_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher& __s) {
+  return __s(__f, __l).first;
+}
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SEARCH_H
diff --git a/include/__algorithm/search_n.h b/include/__algorithm/search_n.h
new file mode 100644
index 0000000..1584e8e
--- /dev/null
+++ b/include/__algorithm/search_n.h
@@ -0,0 +1,116 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SEARCH_N_H
+#define _LIBCPP___ALGORITHM_SEARCH_N_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__iterator/iterator_traits.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _BinaryPredicate, class _ForwardIterator, class _Size, class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator __search_n(_ForwardIterator __first, _ForwardIterator __last,
+                                                          _Size __count, const _Tp& __value_, _BinaryPredicate __pred,
+                                                          forward_iterator_tag) {
+  if (__count <= 0)
+    return __first;
+  while (true) {
+    // Find first element in sequence that matchs __value_, with a mininum of loop checks
+    while (true) {
+      if (__first == __last) // return __last if no element matches __value_
+        return __last;
+      if (__pred(*__first, __value_))
+        break;
+      ++__first;
+    }
+    // *__first matches __value_, now match elements after here
+    _ForwardIterator __m = __first;
+    _Size __c(0);
+    while (true) {
+      if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern)
+        return __first;
+      if (++__m == __last) // Otherwise if source exhaused, pattern not found
+        return __last;
+      if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first
+      {
+        __first = __m;
+        ++__first;
+        break;
+      } // else there is a match, check next elements
+    }
+  }
+}
+
+template <class _BinaryPredicate, class _RandomAccessIterator, class _Size, class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator __search_n(_RandomAccessIterator __first,
+                                                               _RandomAccessIterator __last, _Size __count,
+                                                               const _Tp& __value_, _BinaryPredicate __pred,
+                                                               random_access_iterator_tag) {
+  if (__count <= 0)
+    return __first;
+  _Size __len = static_cast<_Size>(__last - __first);
+  if (__len < __count)
+    return __last;
+  const _RandomAccessIterator __s = __last - (__count - 1); // Start of pattern match can't go beyond here
+  while (true) {
+    // Find first element in sequence that matchs __value_, with a mininum of loop checks
+    while (true) {
+      if (__first >= __s) // return __last if no element matches __value_
+        return __last;
+      if (__pred(*__first, __value_))
+        break;
+      ++__first;
+    }
+    // *__first matches __value_, now match elements after here
+    _RandomAccessIterator __m = __first;
+    _Size __c(0);
+    while (true) {
+      if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern)
+        return __first;
+      ++__m;                       // no need to check range on __m because __s guarantees we have enough source
+      if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first
+      {
+        __first = __m;
+        ++__first;
+        break;
+      } // else there is a match, check next elements
+    }
+  }
+}
+
+template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator search_n(
+    _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_, _BinaryPredicate __pred) {
+  return _VSTD::__search_n<typename add_lvalue_reference<_BinaryPredicate>::type>(
+      __first, __last, _VSTD::__convert_to_integral(__count), __value_, __pred,
+      typename iterator_traits<_ForwardIterator>::iterator_category());
+}
+
+template <class _ForwardIterator, class _Size, class _Tp>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_) {
+  typedef typename iterator_traits<_ForwardIterator>::value_type __v;
+  return _VSTD::search_n(__first, __last, _VSTD::__convert_to_integral(__count), __value_, __equal_to<__v, _Tp>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SEARCH_N_H
diff --git a/include/__algorithm/set_difference.h b/include/__algorithm/set_difference.h
new file mode 100644
index 0000000..f4c985d
--- /dev/null
+++ b/include/__algorithm/set_difference.h
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SET_DIFFERENCE_H
+#define _LIBCPP___ALGORITHM_SET_DIFFERENCE_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/copy.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
+__set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
+                 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    while (__first1 != __last1)
+    {
+        if (__first2 == __last2)
+            return _VSTD::copy(__first1, __last1, __result);
+        if (__comp(*__first1, *__first2))
+        {
+            *__result = *__first1;
+            ++__result;
+            ++__first1;
+        }
+        else
+        {
+            if (!__comp(*__first2, *__first1))
+                ++__first1;
+            ++__first2;
+        }
+    }
+    return __result;
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
+               _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    return _VSTD::__set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
+               _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
+{
+    return _VSTD::set_difference(__first1, __last1, __first2, __last2, __result,
+                                __less<typename iterator_traits<_InputIterator1>::value_type,
+                                       typename iterator_traits<_InputIterator2>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SET_DIFFERENCE_H
diff --git a/include/__algorithm/set_intersection.h b/include/__algorithm/set_intersection.h
new file mode 100644
index 0000000..9d34b66
--- /dev/null
+++ b/include/__algorithm/set_intersection.h
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SET_INTERSECTION_H
+#define _LIBCPP___ALGORITHM_SET_INTERSECTION_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
+__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
+                   _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    while (__first1 != __last1 && __first2 != __last2)
+    {
+        if (__comp(*__first1, *__first2))
+            ++__first1;
+        else
+        {
+            if (!__comp(*__first2, *__first1))
+            {
+                *__result = *__first1;
+                ++__result;
+                ++__first1;
+            }
+            ++__first2;
+        }
+    }
+    return __result;
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
+                 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    return _VSTD::__set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
+                 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
+{
+    return _VSTD::set_intersection(__first1, __last1, __first2, __last2, __result,
+                                  __less<typename iterator_traits<_InputIterator1>::value_type,
+                                         typename iterator_traits<_InputIterator2>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SET_INTERSECTION_H
diff --git a/include/__algorithm/set_symmetric_difference.h b/include/__algorithm/set_symmetric_difference.h
new file mode 100644
index 0000000..5650b83
--- /dev/null
+++ b/include/__algorithm/set_symmetric_difference.h
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H
+#define _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/copy.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
+__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
+                           _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    while (__first1 != __last1)
+    {
+        if (__first2 == __last2)
+            return _VSTD::copy(__first1, __last1, __result);
+        if (__comp(*__first1, *__first2))
+        {
+            *__result = *__first1;
+            ++__result;
+            ++__first1;
+        }
+        else
+        {
+            if (__comp(*__first2, *__first1))
+            {
+                *__result = *__first2;
+                ++__result;
+            }
+            else
+                ++__first1;
+            ++__first2;
+        }
+    }
+    return _VSTD::copy(__first2, __last2, __result);
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
+                         _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    return _VSTD::__set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
+                         _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
+{
+    return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result,
+                                          __less<typename iterator_traits<_InputIterator1>::value_type,
+                                                 typename iterator_traits<_InputIterator2>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H
diff --git a/include/__algorithm/set_union.h b/include/__algorithm/set_union.h
new file mode 100644
index 0000000..c0874e9
--- /dev/null
+++ b/include/__algorithm/set_union.h
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SET_UNION_H
+#define _LIBCPP___ALGORITHM_SET_UNION_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/copy.h>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
+__set_union(_InputIterator1 __first1, _InputIterator1 __last1,
+            _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    for (; __first1 != __last1; ++__result)
+    {
+        if (__first2 == __last2)
+            return _VSTD::copy(__first1, __last1, __result);
+        if (__comp(*__first2, *__first1))
+        {
+            *__result = *__first2;
+            ++__first2;
+        }
+        else
+        {
+            if (!__comp(*__first1, *__first2))
+                ++__first2;
+            *__result = *__first1;
+            ++__first1;
+        }
+    }
+    return _VSTD::copy(__first2, __last2, __result);
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+set_union(_InputIterator1 __first1, _InputIterator1 __last1,
+          _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    return _VSTD::__set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+set_union(_InputIterator1 __first1, _InputIterator1 __last1,
+          _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
+{
+    return _VSTD::set_union(__first1, __last1, __first2, __last2, __result,
+                          __less<typename iterator_traits<_InputIterator1>::value_type,
+                                 typename iterator_traits<_InputIterator2>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SET_UNION_H
diff --git a/include/__algorithm/shift_left.h b/include/__algorithm/shift_left.h
new file mode 100644
index 0000000..961b89c
--- /dev/null
+++ b/include/__algorithm/shift_left.h
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SHIFT_LEFT_H
+#define _LIBCPP___ALGORITHM_SHIFT_LEFT_H
+
+#include <__config>
+#include <__algorithm/move.h>
+#include <__iterator/iterator_traits.h>
+#include <type_traits> // swap
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY constexpr
+_ForwardIterator
+shift_left(_ForwardIterator __first, _ForwardIterator __last,
+           typename iterator_traits<_ForwardIterator>::difference_type __n)
+{
+    if (__n == 0) {
+        return __last;
+    }
+
+    _ForwardIterator __m = __first;
+    if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) {
+        if (__n >= __last - __first) {
+            return __first;
+        }
+        __m += __n;
+    } else {
+        for (; __n > 0; --__n) {
+            if (__m == __last) {
+                return __first;
+            }
+            ++__m;
+        }
+    }
+    return _VSTD::move(__m, __last, __first);
+}
+
+#endif // _LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SHIFT_LEFT_H
diff --git a/include/__algorithm/shift_right.h b/include/__algorithm/shift_right.h
new file mode 100644
index 0000000..5cb4195
--- /dev/null
+++ b/include/__algorithm/shift_right.h
@@ -0,0 +1,106 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SHIFT_RIGHT_H
+#define _LIBCPP___ALGORITHM_SHIFT_RIGHT_H
+
+#include <__config>
+#include <__algorithm/move.h>
+#include <__algorithm/move_backward.h>
+#include <__algorithm/swap_ranges.h>
+#include <__iterator/iterator_traits.h>
+#include <type_traits> // swap
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY constexpr
+_ForwardIterator
+shift_right(_ForwardIterator __first, _ForwardIterator __last,
+            typename iterator_traits<_ForwardIterator>::difference_type __n)
+{
+    if (__n == 0) {
+        return __first;
+    }
+
+    if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) {
+        decltype(__n) __d = __last - __first;
+        if (__n >= __d) {
+            return __last;
+        }
+        _ForwardIterator __m = __first + (__d - __n);
+        return _VSTD::move_backward(__first, __m, __last);
+    } else if constexpr (__is_cpp17_bidirectional_iterator<_ForwardIterator>::value) {
+        _ForwardIterator __m = __last;
+        for (; __n > 0; --__n) {
+            if (__m == __first) {
+                return __last;
+            }
+            --__m;
+        }
+        return _VSTD::move_backward(__first, __m, __last);
+    } else {
+        _ForwardIterator __ret = __first;
+        for (; __n > 0; --__n) {
+            if (__ret == __last) {
+                return __last;
+            }
+            ++__ret;
+        }
+
+        // We have an __n-element scratch space from __first to __ret.
+        // Slide an __n-element window [__trail, __lead) from left to right.
+        // We're essentially doing swap_ranges(__first, __ret, __trail, __lead)
+        // over and over; but once __lead reaches __last we needn't bother
+        // to save the values of elements [__trail, __last).
+
+        auto __trail = __first;
+        auto __lead = __ret;
+        while (__trail != __ret) {
+            if (__lead == __last) {
+                _VSTD::move(__first, __trail, __ret);
+                return __ret;
+            }
+            ++__trail;
+            ++__lead;
+        }
+
+        _ForwardIterator __mid = __first;
+        while (true) {
+            if (__lead == __last) {
+                __trail = _VSTD::move(__mid, __ret, __trail);
+                _VSTD::move(__first, __mid, __trail);
+                return __ret;
+            }
+            swap(*__mid, *__trail);
+            ++__mid;
+            ++__trail;
+            ++__lead;
+            if (__mid == __ret) {
+                __mid = __first;
+            }
+        }
+    }
+}
+
+#endif // _LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SHIFT_RIGHT_H
diff --git a/include/__algorithm/shuffle.h b/include/__algorithm/shuffle.h
new file mode 100644
index 0000000..637fca5
--- /dev/null
+++ b/include/__algorithm/shuffle.h
@@ -0,0 +1,127 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SHUFFLE_H
+#define _LIBCPP___ALGORITHM_SHUFFLE_H
+
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__random/uniform_int_distribution.h>
+#include <__utility/swap.h>
+#include <cstddef>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \
+  || defined(_LIBCPP_BUILDING_LIBRARY)
+class _LIBCPP_TYPE_VIS __rs_default;
+
+_LIBCPP_FUNC_VIS __rs_default __rs_get();
+
+class _LIBCPP_TYPE_VIS __rs_default
+{
+    static unsigned __c_;
+
+    __rs_default();
+public:
+    typedef uint_fast32_t result_type;
+
+    static const result_type _Min = 0;
+    static const result_type _Max = 0xFFFFFFFF;
+
+    __rs_default(const __rs_default&);
+    ~__rs_default();
+
+    result_type operator()();
+
+    static _LIBCPP_CONSTEXPR result_type min() {return _Min;}
+    static _LIBCPP_CONSTEXPR result_type max() {return _Max;}
+
+    friend _LIBCPP_FUNC_VIS __rs_default __rs_get();
+};
+
+_LIBCPP_FUNC_VIS __rs_default __rs_get();
+
+template <class _RandomAccessIterator>
+_LIBCPP_DEPRECATED_IN_CXX14 void
+random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    typedef uniform_int_distribution<ptrdiff_t> _Dp;
+    typedef typename _Dp::param_type _Pp;
+    difference_type __d = __last - __first;
+    if (__d > 1)
+    {
+        _Dp __uid;
+        __rs_default __g = __rs_get();
+        for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d)
+        {
+            difference_type __i = __uid(__g, _Pp(0, __d));
+            if (__i != difference_type(0))
+                swap(*__first, *(__first + __i));
+        }
+    }
+}
+
+template <class _RandomAccessIterator, class _RandomNumberGenerator>
+_LIBCPP_DEPRECATED_IN_CXX14 void
+random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
+#ifndef _LIBCPP_CXX03_LANG
+               _RandomNumberGenerator&& __rand)
+#else
+               _RandomNumberGenerator& __rand)
+#endif
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    difference_type __d = __last - __first;
+    if (__d > 1)
+    {
+        for (--__last; __first < __last; ++__first, (void) --__d)
+        {
+            difference_type __i = __rand(__d);
+            if (__i != difference_type(0))
+              swap(*__first, *(__first + __i));
+        }
+    }
+}
+#endif
+
+template<class _RandomAccessIterator, class _UniformRandomNumberGenerator>
+    void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
+                 _UniformRandomNumberGenerator&& __g)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    typedef uniform_int_distribution<ptrdiff_t> _Dp;
+    typedef typename _Dp::param_type _Pp;
+    difference_type __d = __last - __first;
+    if (__d > 1)
+    {
+        _Dp __uid;
+        for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d)
+        {
+            difference_type __i = __uid(__g, _Pp(0, __d));
+            if (__i != difference_type(0))
+                swap(*__first, *(__first + __i));
+        }
+    }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SHUFFLE_H
diff --git a/include/__algorithm/sift_down.h b/include/__algorithm/sift_down.h
new file mode 100644
index 0000000..dd4b54e
--- /dev/null
+++ b/include/__algorithm/sift_down.h
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SIFT_DOWN_H
+#define _LIBCPP___ALGORITHM_SIFT_DOWN_H
+
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _RandomAccessIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 void
+__sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/,
+            _Compare __comp,
+            typename iterator_traits<_RandomAccessIterator>::difference_type __len,
+            _RandomAccessIterator __start)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    // left-child of __start is at 2 * __start + 1
+    // right-child of __start is at 2 * __start + 2
+    difference_type __child = __start - __first;
+
+    if (__len < 2 || (__len - 2) / 2 < __child)
+        return;
+
+    __child = 2 * __child + 1;
+    _RandomAccessIterator __child_i = __first + __child;
+
+    if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) {
+        // right-child exists and is greater than left-child
+        ++__child_i;
+        ++__child;
+    }
+
+    // check if we are in heap-order
+    if (__comp(*__child_i, *__start))
+        // we are, __start is larger than it's largest child
+        return;
+
+    value_type __top(_VSTD::move(*__start));
+    do
+    {
+        // we are not in heap-order, swap the parent with its largest child
+        *__start = _VSTD::move(*__child_i);
+        __start = __child_i;
+
+        if ((__len - 2) / 2 < __child)
+            break;
+
+        // recompute the child based off of the updated parent
+        __child = 2 * __child + 1;
+        __child_i = __first + __child;
+
+        if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) {
+            // right-child exists and is greater than left-child
+            ++__child_i;
+            ++__child;
+        }
+
+        // check if we are in heap-order
+    } while (!__comp(*__child_i, __top));
+    *__start = _VSTD::move(__top);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SIFT_DOWN_H
diff --git a/include/__algorithm/sort.h b/include/__algorithm/sort.h
new file mode 100644
index 0000000..39ec213
--- /dev/null
+++ b/include/__algorithm/sort.h
@@ -0,0 +1,530 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SORT_H
+#define _LIBCPP___ALGORITHM_SORT_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/min_element.h>
+#include <__algorithm/partial_sort.h>
+#include <__algorithm/unwrap_iter.h>
+#include <__utility/swap.h>
+#include <memory>
+#include <type_traits> // swap
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// stable, 2-3 compares, 0-2 swaps
+
+template <class _Compare, class _ForwardIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 unsigned
+__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c)
+{
+    unsigned __r = 0;
+    if (!__c(*__y, *__x))          // if x <= y
+    {
+        if (!__c(*__z, *__y))      // if y <= z
+            return __r;            // x <= y && y <= z
+                                   // x <= y && y > z
+        swap(*__y, *__z);          // x <= z && y < z
+        __r = 1;
+        if (__c(*__y, *__x))       // if x > y
+        {
+            swap(*__x, *__y);      // x < y && y <= z
+            __r = 2;
+        }
+        return __r;                // x <= y && y < z
+    }
+    if (__c(*__z, *__y))           // x > y, if y > z
+    {
+        swap(*__x, *__z);          // x < y && y < z
+        __r = 1;
+        return __r;
+    }
+    swap(*__x, *__y);              // x > y && y <= z
+    __r = 1;                       // x < y && x <= z
+    if (__c(*__z, *__y))           // if y > z
+    {
+        swap(*__y, *__z);          // x <= y && y < z
+        __r = 2;
+    }
+    return __r;
+}                                  // x <= y && y <= z
+
+// stable, 3-6 compares, 0-5 swaps
+
+template <class _Compare, class _ForwardIterator>
+unsigned
+__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
+            _ForwardIterator __x4, _Compare __c)
+{
+    unsigned __r = _VSTD::__sort3<_Compare>(__x1, __x2, __x3, __c);
+    if (__c(*__x4, *__x3))
+    {
+        swap(*__x3, *__x4);
+        ++__r;
+        if (__c(*__x3, *__x2))
+        {
+            swap(*__x2, *__x3);
+            ++__r;
+            if (__c(*__x2, *__x1))
+            {
+                swap(*__x1, *__x2);
+                ++__r;
+            }
+        }
+    }
+    return __r;
+}
+
+// stable, 4-10 compares, 0-9 swaps
+
+template <class _Compare, class _ForwardIterator>
+_LIBCPP_HIDDEN
+unsigned
+__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
+            _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c)
+{
+    unsigned __r = _VSTD::__sort4<_Compare>(__x1, __x2, __x3, __x4, __c);
+    if (__c(*__x5, *__x4))
+    {
+        swap(*__x4, *__x5);
+        ++__r;
+        if (__c(*__x4, *__x3))
+        {
+            swap(*__x3, *__x4);
+            ++__r;
+            if (__c(*__x3, *__x2))
+            {
+                swap(*__x2, *__x3);
+                ++__r;
+                if (__c(*__x2, *__x1))
+                {
+                    swap(*__x1, *__x2);
+                    ++__r;
+                }
+            }
+        }
+    }
+    return __r;
+}
+
+// Assumes size > 0
+template <class _Compare, class _BidirectionalIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 void
+__selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
+{
+    _BidirectionalIterator __lm1 = __last;
+    for (--__lm1; __first != __lm1; ++__first)
+    {
+        _BidirectionalIterator __i = _VSTD::min_element<_BidirectionalIterator,
+                                                        typename add_lvalue_reference<_Compare>::type>
+                                                       (__first, __last, __comp);
+        if (__i != __first)
+            swap(*__first, *__i);
+    }
+}
+
+template <class _Compare, class _BidirectionalIterator>
+void
+__insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
+{
+    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+    if (__first != __last)
+    {
+        _BidirectionalIterator __i = __first;
+        for (++__i; __i != __last; ++__i)
+        {
+            _BidirectionalIterator __j = __i;
+            value_type __t(_VSTD::move(*__j));
+            for (_BidirectionalIterator __k = __i; __k != __first && __comp(__t,  *--__k); --__j)
+                *__j = _VSTD::move(*__k);
+            *__j = _VSTD::move(__t);
+        }
+    }
+}
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    _RandomAccessIterator __j = __first+2;
+    _VSTD::__sort3<_Compare>(__first, __first+1, __j, __comp);
+    for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i)
+    {
+        if (__comp(*__i, *__j))
+        {
+            value_type __t(_VSTD::move(*__i));
+            _RandomAccessIterator __k = __j;
+            __j = __i;
+            do
+            {
+                *__j = _VSTD::move(*__k);
+                __j = __k;
+            } while (__j != __first && __comp(__t, *--__k));
+            *__j = _VSTD::move(__t);
+        }
+        __j = __i;
+    }
+}
+
+template <class _Compare, class _RandomAccessIterator>
+bool
+__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    switch (__last - __first)
+    {
+    case 0:
+    case 1:
+        return true;
+    case 2:
+        if (__comp(*--__last, *__first))
+            swap(*__first, *__last);
+        return true;
+    case 3:
+        _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp);
+        return true;
+    case 4:
+        _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);
+        return true;
+    case 5:
+        _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp);
+        return true;
+    }
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    _RandomAccessIterator __j = __first+2;
+    _VSTD::__sort3<_Compare>(__first, __first+1, __j, __comp);
+    const unsigned __limit = 8;
+    unsigned __count = 0;
+    for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i)
+    {
+        if (__comp(*__i, *__j))
+        {
+            value_type __t(_VSTD::move(*__i));
+            _RandomAccessIterator __k = __j;
+            __j = __i;
+            do
+            {
+                *__j = _VSTD::move(*__k);
+                __j = __k;
+            } while (__j != __first && __comp(__t, *--__k));
+            *__j = _VSTD::move(__t);
+            if (++__count == __limit)
+                return ++__i == __last;
+        }
+        __j = __i;
+    }
+    return true;
+}
+
+template <class _Compare, class _BidirectionalIterator>
+void
+__insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1,
+                      typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp)
+{
+    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+    if (__first1 != __last1)
+    {
+        __destruct_n __d(0);
+        unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
+        value_type* __last2 = __first2;
+        ::new ((void*)__last2) value_type(_VSTD::move(*__first1));
+        __d.template __incr<value_type>();
+        for (++__last2; ++__first1 != __last1; ++__last2)
+        {
+            value_type* __j2 = __last2;
+            value_type* __i2 = __j2;
+            if (__comp(*__first1, *--__i2))
+            {
+                ::new ((void*)__j2) value_type(_VSTD::move(*__i2));
+                __d.template __incr<value_type>();
+                for (--__j2; __i2 != __first2 && __comp(*__first1,  *--__i2); --__j2)
+                    *__j2 = _VSTD::move(*__i2);
+                *__j2 = _VSTD::move(*__first1);
+            }
+            else
+            {
+                ::new ((void*)__j2) value_type(_VSTD::move(*__first1));
+                __d.template __incr<value_type>();
+            }
+        }
+        __h.release();
+    }
+}
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    const difference_type __limit = is_trivially_copy_constructible<value_type>::value &&
+                                    is_trivially_copy_assignable<value_type>::value ? 30 : 6;
+    while (true)
+    {
+    __restart:
+        difference_type __len = __last - __first;
+        switch (__len)
+        {
+        case 0:
+        case 1:
+            return;
+        case 2:
+            if (__comp(*--__last, *__first))
+                swap(*__first, *__last);
+            return;
+        case 3:
+            _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp);
+            return;
+        case 4:
+            _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);
+            return;
+        case 5:
+            _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp);
+            return;
+        }
+        if (__len <= __limit)
+        {
+            _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp);
+            return;
+        }
+        // __len > 5
+        _RandomAccessIterator __m = __first;
+        _RandomAccessIterator __lm1 = __last;
+        --__lm1;
+        unsigned __n_swaps;
+        {
+        difference_type __delta;
+        if (__len >= 1000)
+        {
+            __delta = __len/2;
+            __m += __delta;
+            __delta /= 2;
+            __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m+__delta, __lm1, __comp);
+        }
+        else
+        {
+            __delta = __len/2;
+            __m += __delta;
+            __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp);
+        }
+        }
+        // *__m is median
+        // partition [__first, __m) < *__m and *__m <= [__m, __last)
+        // (this inhibits tossing elements equivalent to __m around unnecessarily)
+        _RandomAccessIterator __i = __first;
+        _RandomAccessIterator __j = __lm1;
+        // j points beyond range to be tested, *__m is known to be <= *__lm1
+        // The search going up is known to be guarded but the search coming down isn't.
+        // Prime the downward search with a guard.
+        if (!__comp(*__i, *__m))  // if *__first == *__m
+        {
+            // *__first == *__m, *__first doesn't go in first part
+            // manually guard downward moving __j against __i
+            while (true)
+            {
+                if (__i == --__j)
+                {
+                    // *__first == *__m, *__m <= all other elements
+                    // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)
+                    ++__i;  // __first + 1
+                    __j = __last;
+                    if (!__comp(*__first, *--__j))  // we need a guard if *__first == *(__last-1)
+                    {
+                        while (true)
+                        {
+                            if (__i == __j)
+                                return;  // [__first, __last) all equivalent elements
+                            if (__comp(*__first, *__i))
+                            {
+                                swap(*__i, *__j);
+                                ++__n_swaps;
+                                ++__i;
+                                break;
+                            }
+                            ++__i;
+                        }
+                    }
+                    // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
+                    if (__i == __j)
+                        return;
+                    while (true)
+                    {
+                        while (!__comp(*__first, *__i))
+                            ++__i;
+                        while (__comp(*__first, *--__j))
+                            ;
+                        if (__i >= __j)
+                            break;
+                        swap(*__i, *__j);
+                        ++__n_swaps;
+                        ++__i;
+                    }
+                    // [__first, __i) == *__first and *__first < [__i, __last)
+                    // The first part is sorted, sort the second part
+                    // _VSTD::__sort<_Compare>(__i, __last, __comp);
+                    __first = __i;
+                    goto __restart;
+                }
+                if (__comp(*__j, *__m))
+                {
+                    swap(*__i, *__j);
+                    ++__n_swaps;
+                    break;  // found guard for downward moving __j, now use unguarded partition
+                }
+            }
+        }
+        // It is known that *__i < *__m
+        ++__i;
+        // j points beyond range to be tested, *__m is known to be <= *__lm1
+        // if not yet partitioned...
+        if (__i < __j)
+        {
+            // known that *(__i - 1) < *__m
+            // known that __i <= __m
+            while (true)
+            {
+                // __m still guards upward moving __i
+                while (__comp(*__i, *__m))
+                    ++__i;
+                // It is now known that a guard exists for downward moving __j
+                while (!__comp(*--__j, *__m))
+                    ;
+                if (__i > __j)
+                    break;
+                swap(*__i, *__j);
+                ++__n_swaps;
+                // It is known that __m != __j
+                // If __m just moved, follow it
+                if (__m == __i)
+                    __m = __j;
+                ++__i;
+            }
+        }
+        // [__first, __i) < *__m and *__m <= [__i, __last)
+        if (__i != __m && __comp(*__m, *__i))
+        {
+            swap(*__i, *__m);
+            ++__n_swaps;
+        }
+        // [__first, __i) < *__i and *__i <= [__i+1, __last)
+        // If we were given a perfect partition, see if insertion sort is quick...
+        if (__n_swaps == 0)
+        {
+            bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp);
+            if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+1, __last, __comp))
+            {
+                if (__fs)
+                    return;
+                __last = __i;
+                continue;
+            }
+            else
+            {
+                if (__fs)
+                {
+                    __first = ++__i;
+                    continue;
+                }
+            }
+        }
+        // sort smaller range with recursive call and larger with tail recursion elimination
+        if (__i - __first < __last - __i)
+        {
+            _VSTD::__sort<_Compare>(__first, __i, __comp);
+            // _VSTD::__sort<_Compare>(__i+1, __last, __comp);
+            __first = ++__i;
+        }
+        else
+        {
+            _VSTD::__sort<_Compare>(__i+1, __last, __comp);
+            // _VSTD::__sort<_Compare>(__first, __i, __comp);
+            __last = __i;
+        }
+    }
+}
+
+template <class _Compare, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__sort(_Tp** __first, _Tp** __last, __less<_Tp*>&)
+{
+    __less<uintptr_t> __comp;
+    _VSTD::__sort<__less<uintptr_t>&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp);
+}
+
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
+
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
+
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&))
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    if (__libcpp_is_constant_evaluated()) {
+        _VSTD::__partial_sort<_Comp_ref>(__first, __last, __last, _Comp_ref(__comp));
+    } else {
+        _VSTD::__sort<_Comp_ref>(_VSTD::__unwrap_iter(__first), _VSTD::__unwrap_iter(__last), _Comp_ref(__comp));
+    }
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    _VSTD::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SORT_H
diff --git a/include/__algorithm/sort_heap.h b/include/__algorithm/sort_heap.h
new file mode 100644
index 0000000..aa8ef76
--- /dev/null
+++ b/include/__algorithm/sort_heap.h
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SORT_HEAP_H
+#define _LIBCPP___ALGORITHM_SORT_HEAP_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/pop_heap.h>
+#include <__iterator/iterator_traits.h>
+#include <type_traits> // swap
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _RandomAccessIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 void
+__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n)
+        _VSTD::__pop_heap<_Compare>(__first, __last, __comp, __n);
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    _VSTD::__sort_heap<_Comp_ref>(__first, __last, __comp);
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    _VSTD::sort_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SORT_HEAP_H
diff --git a/include/__algorithm/stable_partition.h b/include/__algorithm/stable_partition.h
new file mode 100644
index 0000000..931335f
--- /dev/null
+++ b/include/__algorithm/stable_partition.h
@@ -0,0 +1,305 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_STABLE_PARTITION_H
+#define _LIBCPP___ALGORITHM_STABLE_PARTITION_H
+
+#include <__config>
+#include <__algorithm/rotate.h>
+#include <__iterator/iterator_traits.h>
+#include <__utility/swap.h>
+#include <memory>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Predicate, class _ForwardIterator, class _Distance, class _Pair>
+_ForwardIterator
+__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
+                   _Distance __len, _Pair __p, forward_iterator_tag __fit)
+{
+    // *__first is known to be false
+    // __len >= 1
+    if (__len == 1)
+        return __first;
+    if (__len == 2)
+    {
+        _ForwardIterator __m = __first;
+        if (__pred(*++__m))
+        {
+            swap(*__first, *__m);
+            return __m;
+        }
+        return __first;
+    }
+    if (__len <= __p.second)
+    {   // The buffer is big enough to use
+        typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+        __destruct_n __d(0);
+        unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);
+        // Move the falses into the temporary buffer, and the trues to the front of the line
+        // Update __first to always point to the end of the trues
+        value_type* __t = __p.first;
+        ::new ((void*)__t) value_type(_VSTD::move(*__first));
+        __d.template __incr<value_type>();
+        ++__t;
+        _ForwardIterator __i = __first;
+        while (++__i != __last)
+        {
+            if (__pred(*__i))
+            {
+                *__first = _VSTD::move(*__i);
+                ++__first;
+            }
+            else
+            {
+                ::new ((void*)__t) value_type(_VSTD::move(*__i));
+                __d.template __incr<value_type>();
+                ++__t;
+            }
+        }
+        // All trues now at start of range, all falses in buffer
+        // Move falses back into range, but don't mess up __first which points to first false
+        __i = __first;
+        for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i)
+            *__i = _VSTD::move(*__t2);
+        // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
+        return __first;
+    }
+    // Else not enough buffer, do in place
+    // __len >= 3
+    _ForwardIterator __m = __first;
+    _Distance __len2 = __len / 2;  // __len2 >= 2
+    _VSTD::advance(__m, __len2);
+    // recurse on [__first, __m), *__first know to be false
+    // F?????????????????
+    // f       m         l
+    typedef typename add_lvalue_reference<_Predicate>::type _PredRef;
+    _ForwardIterator __first_false = _VSTD::__stable_partition<_PredRef>(__first, __m, __pred, __len2, __p, __fit);
+    // TTTFFFFF??????????
+    // f  ff   m         l
+    // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true
+    _ForwardIterator __m1 = __m;
+    _ForwardIterator __second_false = __last;
+    _Distance __len_half = __len - __len2;
+    while (__pred(*__m1))
+    {
+        if (++__m1 == __last)
+            goto __second_half_done;
+        --__len_half;
+    }
+    // TTTFFFFFTTTF??????
+    // f  ff   m  m1     l
+    __second_false = _VSTD::__stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __fit);
+__second_half_done:
+    // TTTFFFFFTTTTTFFFFF
+    // f  ff   m    sf   l
+    return _VSTD::rotate(__first_false, __m, __second_false);
+    // TTTTTTTTFFFFFFFFFF
+    //         |
+}
+
+template <class _Predicate, class _ForwardIterator>
+_ForwardIterator
+__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
+                   forward_iterator_tag)
+{
+    const unsigned __alloc_limit = 3;  // might want to make this a function of trivial assignment
+    // Either prove all true and return __first or point to first false
+    while (true)
+    {
+        if (__first == __last)
+            return __first;
+        if (!__pred(*__first))
+            break;
+        ++__first;
+    }
+    // We now have a reduced range [__first, __last)
+    // *__first is known to be false
+    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+    difference_type __len = _VSTD::distance(__first, __last);
+    pair<value_type*, ptrdiff_t> __p(0, 0);
+    unique_ptr<value_type, __return_temporary_buffer> __h;
+    if (__len >= __alloc_limit)
+    {
+        __p = _VSTD::get_temporary_buffer<value_type>(__len);
+        __h.reset(__p.first);
+    }
+    return _VSTD::__stable_partition<typename add_lvalue_reference<_Predicate>::type>
+                             (__first, __last, __pred, __len, __p, forward_iterator_tag());
+}
+
+template <class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair>
+_BidirectionalIterator
+__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
+                   _Distance __len, _Pair __p, bidirectional_iterator_tag __bit)
+{
+    // *__first is known to be false
+    // *__last is known to be true
+    // __len >= 2
+    if (__len == 2)
+    {
+        swap(*__first, *__last);
+        return __last;
+    }
+    if (__len == 3)
+    {
+        _BidirectionalIterator __m = __first;
+        if (__pred(*++__m))
+        {
+            swap(*__first, *__m);
+            swap(*__m, *__last);
+            return __last;
+        }
+        swap(*__m, *__last);
+        swap(*__first, *__m);
+        return __m;
+    }
+    if (__len <= __p.second)
+    {   // The buffer is big enough to use
+        typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+        __destruct_n __d(0);
+        unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);
+        // Move the falses into the temporary buffer, and the trues to the front of the line
+        // Update __first to always point to the end of the trues
+        value_type* __t = __p.first;
+        ::new ((void*)__t) value_type(_VSTD::move(*__first));
+        __d.template __incr<value_type>();
+        ++__t;
+        _BidirectionalIterator __i = __first;
+        while (++__i != __last)
+        {
+            if (__pred(*__i))
+            {
+                *__first = _VSTD::move(*__i);
+                ++__first;
+            }
+            else
+            {
+                ::new ((void*)__t) value_type(_VSTD::move(*__i));
+                __d.template __incr<value_type>();
+                ++__t;
+            }
+        }
+        // move *__last, known to be true
+        *__first = _VSTD::move(*__i);
+        __i = ++__first;
+        // All trues now at start of range, all falses in buffer
+        // Move falses back into range, but don't mess up __first which points to first false
+        for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i)
+            *__i = _VSTD::move(*__t2);
+        // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
+        return __first;
+    }
+    // Else not enough buffer, do in place
+    // __len >= 4
+    _BidirectionalIterator __m = __first;
+    _Distance __len2 = __len / 2;  // __len2 >= 2
+    _VSTD::advance(__m, __len2);
+    // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false
+    // F????????????????T
+    // f       m        l
+    _BidirectionalIterator __m1 = __m;
+    _BidirectionalIterator __first_false = __first;
+    _Distance __len_half = __len2;
+    while (!__pred(*--__m1))
+    {
+        if (__m1 == __first)
+            goto __first_half_done;
+        --__len_half;
+    }
+    // F???TFFF?????????T
+    // f   m1  m        l
+    typedef typename add_lvalue_reference<_Predicate>::type _PredRef;
+    __first_false = _VSTD::__stable_partition<_PredRef>(__first, __m1, __pred, __len_half, __p, __bit);
+__first_half_done:
+    // TTTFFFFF?????????T
+    // f  ff   m        l
+    // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true
+    __m1 = __m;
+    _BidirectionalIterator __second_false = __last;
+    ++__second_false;
+    __len_half = __len - __len2;
+    while (__pred(*__m1))
+    {
+        if (++__m1 == __last)
+            goto __second_half_done;
+        --__len_half;
+    }
+    // TTTFFFFFTTTF?????T
+    // f  ff   m  m1    l
+    __second_false = _VSTD::__stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __bit);
+__second_half_done:
+    // TTTFFFFFTTTTTFFFFF
+    // f  ff   m    sf  l
+    return _VSTD::rotate(__first_false, __m, __second_false);
+    // TTTTTTTTFFFFFFFFFF
+    //         |
+}
+
+template <class _Predicate, class _BidirectionalIterator>
+_BidirectionalIterator
+__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
+                   bidirectional_iterator_tag)
+{
+    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
+    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+    const difference_type __alloc_limit = 4;  // might want to make this a function of trivial assignment
+    // Either prove all true and return __first or point to first false
+    while (true)
+    {
+        if (__first == __last)
+            return __first;
+        if (!__pred(*__first))
+            break;
+        ++__first;
+    }
+    // __first points to first false, everything prior to __first is already set.
+    // Either prove [__first, __last) is all false and return __first, or point __last to last true
+    do
+    {
+        if (__first == --__last)
+            return __first;
+    } while (!__pred(*__last));
+    // We now have a reduced range [__first, __last]
+    // *__first is known to be false
+    // *__last is known to be true
+    // __len >= 2
+    difference_type __len = _VSTD::distance(__first, __last) + 1;
+    pair<value_type*, ptrdiff_t> __p(0, 0);
+    unique_ptr<value_type, __return_temporary_buffer> __h;
+    if (__len >= __alloc_limit)
+    {
+        __p = _VSTD::get_temporary_buffer<value_type>(__len);
+        __h.reset(__p.first);
+    }
+    return _VSTD::__stable_partition<typename add_lvalue_reference<_Predicate>::type>
+                             (__first, __last, __pred, __len, __p, bidirectional_iterator_tag());
+}
+
+template <class _ForwardIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
+{
+    return _VSTD::__stable_partition<typename add_lvalue_reference<_Predicate>::type>
+                             (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_STABLE_PARTITION_H
diff --git a/include/__algorithm/stable_sort.h b/include/__algorithm/stable_sort.h
new file mode 100644
index 0000000..32b239a
--- /dev/null
+++ b/include/__algorithm/stable_sort.h
@@ -0,0 +1,235 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_STABLE_SORT_H
+#define _LIBCPP___ALGORITHM_STABLE_SORT_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/inplace_merge.h>
+#include <__algorithm/sort.h>
+#include <__iterator/iterator_traits.h>
+#include <__utility/swap.h>
+#include <memory>
+#include <type_traits> // swap
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _InputIterator1, class _InputIterator2>
+void
+__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1,
+        _InputIterator2 __first2, _InputIterator2 __last2,
+        typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp)
+{
+    typedef typename iterator_traits<_InputIterator1>::value_type value_type;
+    __destruct_n __d(0);
+    unique_ptr<value_type, __destruct_n&> __h(__result, __d);
+    for (; true; ++__result)
+    {
+        if (__first1 == __last1)
+        {
+            for (; __first2 != __last2; ++__first2, ++__result, (void)__d.template __incr<value_type>())
+                ::new ((void*)__result) value_type(_VSTD::move(*__first2));
+            __h.release();
+            return;
+        }
+        if (__first2 == __last2)
+        {
+            for (; __first1 != __last1; ++__first1, ++__result, (void)__d.template __incr<value_type>())
+                ::new ((void*)__result) value_type(_VSTD::move(*__first1));
+            __h.release();
+            return;
+        }
+        if (__comp(*__first2, *__first1))
+        {
+            ::new ((void*)__result) value_type(_VSTD::move(*__first2));
+            __d.template __incr<value_type>();
+            ++__first2;
+        }
+        else
+        {
+            ::new ((void*)__result) value_type(_VSTD::move(*__first1));
+            __d.template __incr<value_type>();
+            ++__first1;
+        }
+    }
+}
+
+template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
+void
+__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1,
+        _InputIterator2 __first2, _InputIterator2 __last2,
+        _OutputIterator __result, _Compare __comp)
+{
+    for (; __first1 != __last1; ++__result)
+    {
+        if (__first2 == __last2)
+        {
+            for (; __first1 != __last1; ++__first1, (void) ++__result)
+                *__result = _VSTD::move(*__first1);
+            return;
+        }
+        if (__comp(*__first2, *__first1))
+        {
+            *__result = _VSTD::move(*__first2);
+            ++__first2;
+        }
+        else
+        {
+            *__result = _VSTD::move(*__first1);
+            ++__first1;
+        }
+    }
+    for (; __first2 != __last2; ++__first2, (void) ++__result)
+        *__result = _VSTD::move(*__first2);
+}
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
+              typename iterator_traits<_RandomAccessIterator>::difference_type __len,
+              typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size);
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp,
+                   typename iterator_traits<_RandomAccessIterator>::difference_type __len,
+                   typename iterator_traits<_RandomAccessIterator>::value_type* __first2)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    switch (__len)
+    {
+    case 0:
+        return;
+    case 1:
+        ::new ((void*)__first2) value_type(_VSTD::move(*__first1));
+        return;
+    case 2:
+        __destruct_n __d(0);
+        unique_ptr<value_type, __destruct_n&> __h2(__first2, __d);
+        if (__comp(*--__last1, *__first1))
+        {
+            ::new ((void*)__first2) value_type(_VSTD::move(*__last1));
+            __d.template __incr<value_type>();
+            ++__first2;
+            ::new ((void*)__first2) value_type(_VSTD::move(*__first1));
+        }
+        else
+        {
+            ::new ((void*)__first2) value_type(_VSTD::move(*__first1));
+            __d.template __incr<value_type>();
+            ++__first2;
+            ::new ((void*)__first2) value_type(_VSTD::move(*__last1));
+        }
+        __h2.release();
+        return;
+    }
+    if (__len <= 8)
+    {
+        _VSTD::__insertion_sort_move<_Compare>(__first1, __last1, __first2, __comp);
+        return;
+    }
+    typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;
+    _RandomAccessIterator __m = __first1 + __l2;
+    _VSTD::__stable_sort<_Compare>(__first1, __m, __comp, __l2, __first2, __l2);
+    _VSTD::__stable_sort<_Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2);
+    _VSTD::__merge_move_construct<_Compare>(__first1, __m, __m, __last1, __first2, __comp);
+}
+
+template <class _Tp>
+struct __stable_sort_switch
+{
+    static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value;
+};
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
+              typename iterator_traits<_RandomAccessIterator>::difference_type __len,
+              typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    switch (__len)
+    {
+    case 0:
+    case 1:
+        return;
+    case 2:
+        if (__comp(*--__last, *__first))
+            swap(*__first, *__last);
+        return;
+    }
+    if (__len <= static_cast<difference_type>(__stable_sort_switch<value_type>::value))
+    {
+        _VSTD::__insertion_sort<_Compare>(__first, __last, __comp);
+        return;
+    }
+    typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;
+    _RandomAccessIterator __m = __first + __l2;
+    if (__len <= __buff_size)
+    {
+        __destruct_n __d(0);
+        unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
+        _VSTD::__stable_sort_move<_Compare>(__first, __m, __comp, __l2, __buff);
+        __d.__set(__l2, (value_type*)nullptr);
+        _VSTD::__stable_sort_move<_Compare>(__m, __last, __comp, __len - __l2, __buff + __l2);
+        __d.__set(__len, (value_type*)nullptr);
+        _VSTD::__merge_move_assign<_Compare>(__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp);
+//         _VSTD::__merge<_Compare>(move_iterator<value_type*>(__buff),
+//                                  move_iterator<value_type*>(__buff + __l2),
+//                                  move_iterator<_RandomAccessIterator>(__buff + __l2),
+//                                  move_iterator<_RandomAccessIterator>(__buff + __len),
+//                                  __first, __comp);
+        return;
+    }
+    _VSTD::__stable_sort<_Compare>(__first, __m, __comp, __l2, __buff, __buff_size);
+    _VSTD::__stable_sort<_Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size);
+    _VSTD::__inplace_merge<_Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size);
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    difference_type __len = __last - __first;
+    pair<value_type*, ptrdiff_t> __buf(0, 0);
+    unique_ptr<value_type, __return_temporary_buffer> __h;
+    if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value))
+    {
+        __buf = _VSTD::get_temporary_buffer<value_type>(__len);
+        __h.reset(__buf.first);
+    }
+    typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+    _VSTD::__stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second);
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    _VSTD::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_STABLE_SORT_H
diff --git a/include/__algorithm/swap_ranges.h b/include/__algorithm/swap_ranges.h
new file mode 100644
index 0000000..3c72dbd
--- /dev/null
+++ b/include/__algorithm/swap_ranges.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_SWAP_RANGES_H
+#define _LIBCPP___ALGORITHM_SWAP_RANGES_H
+
+#include <__config>
+#include <__utility/swap.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ForwardIterator1, class _ForwardIterator2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator2
+swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
+  for (; __first1 != __last1; ++__first1, (void)++__first2)
+    swap(*__first1, *__first2);
+  return __first2;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_SWAP_RANGES_H
diff --git a/include/__algorithm/transform.h b/include/__algorithm/transform.h
new file mode 100644
index 0000000..218f0f1
--- /dev/null
+++ b/include/__algorithm/transform.h
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_TRANSFORM_H
+#define _LIBCPP___ALGORITHM_TRANSFORM_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _OutputIterator, class _UnaryOperation>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op)
+{
+    for (; __first != __last; ++__first, (void) ++__result)
+        *__result = __op(*__first);
+    return __result;
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _BinaryOperation>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
+          _OutputIterator __result, _BinaryOperation __binary_op)
+{
+    for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result)
+        *__result = __binary_op(*__first1, *__first2);
+    return __result;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_TRANSFORM_H
diff --git a/include/__algorithm/unique.h b/include/__algorithm/unique.h
new file mode 100644
index 0000000..fb6251a
--- /dev/null
+++ b/include/__algorithm/unique.h
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_UNIQUE_H
+#define _LIBCPP___ALGORITHM_UNIQUE_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/adjacent_find.h>
+#include <__iterator/iterator_traits.h>
+#include <__utility/move.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// unique
+
+template <class _ForwardIterator, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
+{
+    __first = _VSTD::adjacent_find<_ForwardIterator, typename add_lvalue_reference<_BinaryPredicate>::type>
+                                 (__first, __last, __pred);
+    if (__first != __last)
+    {
+        // ...  a  a  ?  ...
+        //      f     i
+        _ForwardIterator __i = __first;
+        for (++__i; ++__i != __last;)
+            if (!__pred(*__first, *__i))
+                *++__first = _VSTD::move(*__i);
+        ++__first;
+    }
+    return __first;
+}
+
+template <class _ForwardIterator>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator
+unique(_ForwardIterator __first, _ForwardIterator __last)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type __v;
+    return _VSTD::unique(__first, __last, __equal_to<__v>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_UNIQUE_H
diff --git a/include/__algorithm/unique_copy.h b/include/__algorithm/unique_copy.h
new file mode 100644
index 0000000..974a7c4
--- /dev/null
+++ b/include/__algorithm/unique_copy.h
@@ -0,0 +1,114 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_UNIQUE_COPY_H
+#define _LIBCPP___ALGORITHM_UNIQUE_COPY_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__iterator/iterator_traits.h>
+#include <utility>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _BinaryPredicate, class _InputIterator, class _OutputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
+__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred,
+              input_iterator_tag, output_iterator_tag)
+{
+    if (__first != __last)
+    {
+        typename iterator_traits<_InputIterator>::value_type __t(*__first);
+        *__result = __t;
+        ++__result;
+        while (++__first != __last)
+        {
+            if (!__pred(__t, *__first))
+            {
+                __t = *__first;
+                *__result = __t;
+                ++__result;
+            }
+        }
+    }
+    return __result;
+}
+
+template <class _BinaryPredicate, class _ForwardIterator, class _OutputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
+__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred,
+              forward_iterator_tag, output_iterator_tag)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __i = __first;
+        *__result = *__i;
+        ++__result;
+        while (++__first != __last)
+        {
+            if (!__pred(*__i, *__first))
+            {
+                *__result = *__first;
+                ++__result;
+                __i = __first;
+            }
+        }
+    }
+    return __result;
+}
+
+template <class _BinaryPredicate, class _InputIterator, class _ForwardIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred,
+              input_iterator_tag, forward_iterator_tag)
+{
+    if (__first != __last)
+    {
+        *__result = *__first;
+        while (++__first != __last)
+            if (!__pred(*__result, *__first))
+                *++__result = *__first;
+        ++__result;
+    }
+    return __result;
+}
+
+template <class _InputIterator, class _OutputIterator, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred)
+{
+    return _VSTD::__unique_copy<typename add_lvalue_reference<_BinaryPredicate>::type>
+                              (__first, __last, __result, __pred,
+                               typename iterator_traits<_InputIterator>::iterator_category(),
+                               typename iterator_traits<_OutputIterator>::iterator_category());
+}
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    typedef typename iterator_traits<_InputIterator>::value_type __v;
+    return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>());
+}
+
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_UNIQUE_COPY_H
diff --git a/include/__algorithm/unwrap_iter.h b/include/__algorithm/unwrap_iter.h
new file mode 100644
index 0000000..a45d45c
--- /dev/null
+++ b/include/__algorithm/unwrap_iter.h
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_UNWRAP_ITER_H
+#define _LIBCPP___ALGORITHM_UNWRAP_ITER_H
+
+#include <__config>
+#include <iterator>
+#include <__memory/pointer_traits.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// The job of __unwrap_iter is to lower contiguous iterators (such as
+// vector<T>::iterator) into pointers, to reduce the number of template
+// instantiations and to enable pointer-based optimizations e.g. in std::copy.
+// For iterators that are not contiguous, it must be a no-op.
+// In debug mode, we don't do this.
+//
+// __unwrap_iter is non-constexpr for user-defined iterators whose
+// `to_address` and/or `operator->` is non-constexpr. This is okay; but we
+// try to avoid doing __unwrap_iter in constant-evaluated contexts anyway.
+//
+// Some algorithms (e.g. std::copy, but not std::sort) need to convert an
+// "unwrapped" result back into a contiguous iterator. Since contiguous iterators
+// are random-access, we can do this portably using iterator arithmetic; this
+// is the job of __rewrap_iter.
+
+template <class _Iter, bool = __is_cpp17_contiguous_iterator<_Iter>::value>
+struct __unwrap_iter_impl {
+    static _LIBCPP_CONSTEXPR _Iter
+    __apply(_Iter __i) _NOEXCEPT {
+        return __i;
+    }
+};
+
+#if _LIBCPP_DEBUG_LEVEL < 2
+
+template <class _Iter>
+struct __unwrap_iter_impl<_Iter, true> {
+    static _LIBCPP_CONSTEXPR decltype(_VSTD::__to_address(declval<_Iter>()))
+    __apply(_Iter __i) _NOEXCEPT {
+        return _VSTD::__to_address(__i);
+    }
+};
+
+#endif // _LIBCPP_DEBUG_LEVEL < 2
+
+template<class _Iter, class _Impl = __unwrap_iter_impl<_Iter> >
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+decltype(_Impl::__apply(declval<_Iter>()))
+__unwrap_iter(_Iter __i) _NOEXCEPT
+{
+    return _Impl::__apply(__i);
+}
+
+template<class _OrigIter>
+_OrigIter __rewrap_iter(_OrigIter, _OrigIter __result)
+{
+    return __result;
+}
+
+template<class _OrigIter, class _UnwrappedIter>
+_OrigIter __rewrap_iter(_OrigIter __first, _UnwrappedIter __result)
+{
+    // Precondition: __result is reachable from __first
+    // Precondition: _OrigIter is a contiguous iterator
+    return __first + (__result - _VSTD::__unwrap_iter(__first));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_UNWRAP_ITER_H
diff --git a/include/__algorithm/upper_bound.h b/include/__algorithm/upper_bound.h
new file mode 100644
index 0000000..7be607f
--- /dev/null
+++ b/include/__algorithm/upper_bound.h
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_UPPER_BOUND_H
+#define _LIBCPP___ALGORITHM_UPPER_BOUND_H
+
+#include <__config>
+#include <__algorithm/comp.h>
+#include <__algorithm/half_positive.h>
+#include <iterator>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Compare, class _ForwardIterator, class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
+__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
+    difference_type __len = _VSTD::distance(__first, __last);
+    while (__len != 0)
+    {
+        difference_type __l2 = _VSTD::__half_positive(__len);
+        _ForwardIterator __m = __first;
+        _VSTD::advance(__m, __l2);
+        if (__comp(__value_, *__m))
+            __len = __l2;
+        else
+        {
+            __first = ++__m;
+            __len -= __l2 + 1;
+        }
+    }
+    return __first;
+}
+
+template <class _ForwardIterator, class _Tp, class _Compare>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator
+upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return _VSTD::__upper_bound<_Comp_ref>(__first, __last, __value_, __comp);
+}
+
+template <class _ForwardIterator, class _Tp>
+_LIBCPP_NODISCARD_EXT inline
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator
+upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+{
+    return _VSTD::upper_bound(__first, __last, __value_,
+                             __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_UPPER_BOUND_H
diff --git a/include/__availability b/include/__availability
new file mode 100644
index 0000000..13d1195
--- /dev/null
+++ b/include/__availability
@@ -0,0 +1,270 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___AVAILABILITY
+#define _LIBCPP___AVAILABILITY
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#   pragma GCC system_header
+#endif
+
+// Libc++ is shipped by various vendors. In particular, it is used as a system
+// library on macOS, iOS and other Apple platforms. In order for users to be
+// able to compile a binary that is intended to be deployed to an older version
+// of a platform, Clang provides availability attributes [1]. These attributes
+// can be placed on declarations and are used to describe the life cycle of a
+// symbol in the library.
+//
+// The main goal is to ensure a compile-time error if a symbol that hasn't been
+// introduced in a previously released library is used in a program that targets
+// that previously released library. Normally, this would be a load-time error
+// when one tries to launch the program against the older library.
+//
+// For example, the filesystem library was introduced in the dylib in macOS 10.15.
+// If a user compiles on a macOS 10.15 host but targets macOS 10.13 with their
+// program, the compiler would normally not complain (because the required
+// declarations are in the headers), but the dynamic loader would fail to find
+// the symbols when actually trying to launch the program on macOS 10.13. To
+// turn this into a compile-time issue instead, declarations are annotated with
+// when they were introduced, and the compiler can produce a diagnostic if the
+// program references something that isn't available on the deployment target.
+//
+// This mechanism is general in nature, and any vendor can add their markup to
+// the library (see below). Whenever a new feature is added that requires support
+// in the shared library, a macro should be added below to mark this feature
+// as unavailable. When vendors decide to ship the feature as part of their
+// shared library, they can update the markup appropriately.
+//
+// Furthermore, many features in the standard library have corresponding
+// feature-test macros. When a feature is made unavailable on some deployment
+// target, a macro should be defined to signal that it is unavailable. That
+// macro can then be picked up when feature-test macros are generated (see
+// generate_feature_test_macro_components.py) to make sure that feature-test
+// macros don't announce a feature as being implemented if it has been marked
+// as unavailable.
+//
+// Note that this mechanism is disabled by default in the "upstream" libc++.
+// Availability annotations are only meaningful when shipping libc++ inside
+// a platform (i.e. as a system library), and so vendors that want them should
+// turn those annotations on at CMake configuration time.
+//
+// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability
+
+
+// For backwards compatibility, allow users to define _LIBCPP_DISABLE_AVAILABILITY
+// for a while.
+#if defined(_LIBCPP_DISABLE_AVAILABILITY)
+#   if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
+#       define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS
+#   endif
+#endif
+
+// Availability markup is disabled when building the library, or when the compiler
+// doesn't support the proper attributes.
+#if defined(_LIBCPP_BUILDING_LIBRARY) ||                                        \
+    defined(_LIBCXXABI_BUILDING_LIBRARY) ||                                     \
+    !__has_feature(attribute_availability_with_strict) ||                       \
+    !__has_feature(attribute_availability_in_templates) ||                      \
+    !__has_extension(pragma_clang_attribute_external_declaration)
+#   if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
+#       define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS
+#   endif
+#endif
+
+#if defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
+
+    // This controls the availability of std::shared_mutex and std::shared_timed_mutex,
+    // which were added to the dylib later.
+#   define _LIBCPP_AVAILABILITY_SHARED_MUTEX
+// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex
+// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex
+
+    // These macros control the availability of std::bad_optional_access and
+    // other exception types. These were put in the shared library to prevent
+    // code bloat from every user program defining the vtable for these exception
+    // types.
+#   define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
+#   define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
+#   define _LIBCPP_AVAILABILITY_BAD_ANY_CAST
+
+    // This controls the availability of std::uncaught_exceptions().
+#   define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS
+
+    // This controls the availability of the sized version of ::operator delete,
+    // which was added to the dylib later.
+#   define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE
+
+    // This controls the availability of the std::future_error exception.
+#   define _LIBCPP_AVAILABILITY_FUTURE_ERROR
+
+    // This controls the availability of std::type_info's vtable.
+    // I can't imagine how using std::type_info can work at all if
+    // this isn't supported.
+#   define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE
+
+    // This controls the availability of std::locale::category members
+    // (e.g. std::locale::collate), which are defined in the dylib.
+#   define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
+
+    // This controls the availability of atomic operations on std::shared_ptr
+    // (e.g. `std::atomic_store(std::shared_ptr)`), which require a shared
+    // lock table located in the dylib.
+#   define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+
+    // These macros control the availability of all parts of <filesystem> that
+    // depend on something in the dylib.
+#   define _LIBCPP_AVAILABILITY_FILESYSTEM
+#   define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
+#   define _LIBCPP_AVAILABILITY_FILESYSTEM_POP
+// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
+
+    // This controls the availability of std::to_chars.
+#   define _LIBCPP_AVAILABILITY_TO_CHARS
+
+    // This controls the availability of the C++20 synchronization library,
+    // which requires shared library support for various operations
+    // (see libcxx/src/atomic.cpp).
+#   define _LIBCPP_AVAILABILITY_SYNC
+// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait
+// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier
+// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch
+// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore
+
+    // This controls the availability of the C++20 format library.
+    // The library is in development and not ABI stable yet. Currently
+    // P2216 is aiming to be retroactively accepted in C++20. This paper
+    // contains ABI breaking changes.
+#   define _LIBCPP_AVAILABILITY_FORMAT
+// #   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
+
+#elif defined(__APPLE__)
+
+#   define _LIBCPP_AVAILABILITY_SHARED_MUTEX                                    \
+        __attribute__((availability(macosx,strict,introduced=10.12)))           \
+        __attribute__((availability(ios,strict,introduced=10.0)))               \
+        __attribute__((availability(tvos,strict,introduced=10.0)))              \
+        __attribute__((availability(watchos,strict,introduced=3.0)))
+#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) ||    \
+        (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
+        (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) ||         \
+        (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
+#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex
+#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex
+#   endif
+
+#   define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS                             \
+        __attribute__((availability(macosx,strict,introduced=10.13)))           \
+        __attribute__((availability(ios,strict,introduced=11.0)))               \
+        __attribute__((availability(tvos,strict,introduced=11.0)))              \
+        __attribute__((availability(watchos,strict,introduced=4.0)))
+#   define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS                              \
+        _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
+#   define _LIBCPP_AVAILABILITY_BAD_ANY_CAST                                    \
+        _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
+
+#   define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS                             \
+        __attribute__((availability(macosx,strict,introduced=10.12)))           \
+        __attribute__((availability(ios,strict,introduced=10.0)))               \
+        __attribute__((availability(tvos,strict,introduced=10.0)))              \
+        __attribute__((availability(watchos,strict,introduced=3.0)))
+
+#   define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE                                \
+        __attribute__((availability(macosx,strict,introduced=10.12)))           \
+        __attribute__((availability(ios,strict,introduced=10.0)))               \
+        __attribute__((availability(tvos,strict,introduced=10.0)))              \
+        __attribute__((availability(watchos,strict,introduced=3.0)))
+
+#   define _LIBCPP_AVAILABILITY_FUTURE_ERROR                                    \
+        __attribute__((availability(ios,strict,introduced=6.0)))
+
+#   define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE                                 \
+        __attribute__((availability(macosx,strict,introduced=10.9)))            \
+        __attribute__((availability(ios,strict,introduced=7.0)))
+
+#   define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY                                 \
+        __attribute__((availability(macosx,strict,introduced=10.9)))            \
+        __attribute__((availability(ios,strict,introduced=7.0)))
+
+#   define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR                               \
+        __attribute__((availability(macosx,strict,introduced=10.9)))            \
+        __attribute__((availability(ios,strict,introduced=7.0)))
+
+#   define _LIBCPP_AVAILABILITY_FILESYSTEM                                      \
+        __attribute__((availability(macosx,strict,introduced=10.15)))           \
+        __attribute__((availability(ios,strict,introduced=13.0)))               \
+        __attribute__((availability(tvos,strict,introduced=13.0)))              \
+        __attribute__((availability(watchos,strict,introduced=6.0)))
+#   define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH                                 \
+        _Pragma("clang attribute push(__attribute__((availability(macosx,strict,introduced=10.15))), apply_to=any(function,record))") \
+        _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))")     \
+        _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))")    \
+        _Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))")
+#   define _LIBCPP_AVAILABILITY_FILESYSTEM_POP                                  \
+        _Pragma("clang attribute pop")                                          \
+        _Pragma("clang attribute pop")                                          \
+        _Pragma("clang attribute pop")                                          \
+        _Pragma("clang attribute pop")
+#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) ||    \
+        (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
+        (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) ||         \
+        (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000)
+#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
+#   endif
+
+#   define _LIBCPP_AVAILABILITY_TO_CHARS                                        \
+        _LIBCPP_AVAILABILITY_FILESYSTEM
+
+#   define _LIBCPP_AVAILABILITY_SYNC                                            \
+        __attribute__((availability(macosx,strict,introduced=11.0)))            \
+        __attribute__((availability(ios,strict,introduced=14.0)))               \
+        __attribute__((availability(tvos,strict,introduced=14.0)))              \
+        __attribute__((availability(watchos,strict,introduced=7.0)))
+#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) ||    \
+        (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \
+        (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 140000) ||         \
+        (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 70000)
+#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait
+#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier
+#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch
+#       define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore
+#   endif
+
+    // This controls the availability of the C++20 format library.
+    // The library is in development and not ABI stable yet. Currently
+    // P2216 is aiming to be retroactively accepted in C++20. This paper
+    // contains ABI breaking changes.
+#   define _LIBCPP_AVAILABILITY_FORMAT                                          \
+        __attribute__((unavailable))
+#   define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
+#else
+
+// ...New vendors can add availability markup here...
+
+#   error "It looks like you're trying to enable vendor availability markup, but you haven't defined the corresponding macros yet!"
+
+#endif
+
+// Define availability attributes that depend on _LIBCPP_NO_EXCEPTIONS.
+// Those are defined in terms of the availability attributes above, and
+// should not be vendor-specific.
+#if defined(_LIBCPP_NO_EXCEPTIONS)
+#   define _LIBCPP_AVAILABILITY_FUTURE
+#   define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
+#   define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
+#   define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
+#else
+#   define _LIBCPP_AVAILABILITY_FUTURE                    _LIBCPP_AVAILABILITY_FUTURE_ERROR
+#   define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST        _LIBCPP_AVAILABILITY_BAD_ANY_CAST
+#   define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
+#   define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS  _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
+#endif
+
+#endif // _LIBCPP___AVAILABILITY
diff --git a/include/__bit_reference b/include/__bit_reference
index d9ebfbe..a02492c 100644
--- a/include/__bit_reference
+++ b/include/__bit_reference
@@ -1,10 +1,9 @@
 // -*- 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.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,14 +11,17 @@
 #define _LIBCPP___BIT_REFERENCE
 
 #include <__config>
+#include <__bits>
 #include <algorithm>
 
-#include <__undef_min_max>
-
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> class __bit_iterator;
@@ -40,14 +42,14 @@
     __storage_pointer __seg_;
     __storage_type    __mask_;
 
-#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)
     friend typename _Cp::__self;
-#else
-    friend class _Cp::__self;
-#endif
+
     friend class __bit_const_reference<_Cp>;
     friend class __bit_iterator<_Cp, false>;
 public:
+    _LIBCPP_INLINE_VISIBILITY
+    __bit_reference(const __bit_reference&) = default;
+
     _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT
         {return static_cast<bool>(*__seg_ & __mask_);}
     _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT
@@ -69,7 +71,7 @@
 
     _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;}
     _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, false> operator&() const _NOEXCEPT
-        {return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(__ctz(__mask_)));}
+        {return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(__libcpp_ctz(__mask_)));}
 private:
     _LIBCPP_INLINE_VISIBILITY
     __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
@@ -130,14 +132,13 @@
     __storage_pointer        __seg_;
     __storage_type __mask_;
 
-#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)
     friend typename _Cp::__self;
-#else
-    friend class _Cp::__self;
-#endif
     friend class __bit_iterator<_Cp, true>;
 public:
     _LIBCPP_INLINE_VISIBILITY
+    __bit_const_reference(const __bit_const_reference&) = default;
+
+    _LIBCPP_INLINE_VISIBILITY
     __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT
         : __seg_(__x.__seg_), __mask_(__x.__mask_) {}
 
@@ -145,14 +146,14 @@
         {return static_cast<bool>(*__seg_ & __mask_);}
 
     _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT
-        {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(__ctz(__mask_)));}
+        {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(__libcpp_ctz(__mask_)));}
 private:
     _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR
     __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
         : __seg_(__s), __mask_(__m) {}
 
-    __bit_const_reference& operator=(const __bit_const_reference& __x);
+    __bit_const_reference& operator=(const __bit_const_reference&) = delete;
 };
 
 // find
@@ -163,7 +164,7 @@
 {
     typedef __bit_iterator<_Cp, _IsConst> _It;
     typedef typename _It::__storage_type __storage_type;
-    static const unsigned __bits_per_word = _It::__bits_per_word;
+    static const int __bits_per_word = _It::__bits_per_word;
     // do first partial word
     if (__first.__ctz_ != 0)
     {
@@ -172,7 +173,7 @@
         __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
         __storage_type __b = *__first.__seg_ & __m;
         if (__b)
-            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
+            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
         if (__n == __dn)
             return __first + __n;
         __n -= __dn;
@@ -181,14 +182,14 @@
     // do middle whole words
     for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
         if (*__first.__seg_)
-            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(*__first.__seg_)));
+            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(*__first.__seg_)));
     // do last partial word
     if (__n > 0)
     {
         __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
         __storage_type __b = *__first.__seg_ & __m;
         if (__b)
-            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
+            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
     }
     return _It(__first.__seg_, static_cast<unsigned>(__n));
 }
@@ -199,7 +200,7 @@
 {
     typedef __bit_iterator<_Cp, _IsConst> _It;
     typedef typename _It::__storage_type __storage_type;
-    static const unsigned __bits_per_word = _It::__bits_per_word;
+    const int __bits_per_word = _It::__bits_per_word;
     // do first partial word
     if (__first.__ctz_ != 0)
     {
@@ -208,7 +209,7 @@
         __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
         __storage_type __b = ~*__first.__seg_ & __m;
         if (__b)
-            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
+            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
         if (__n == __dn)
             return __first + __n;
         __n -= __dn;
@@ -219,7 +220,7 @@
     {
         __storage_type __b = ~*__first.__seg_;
         if (__b)
-            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
+            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
     }
     // do last partial word
     if (__n > 0)
@@ -227,7 +228,7 @@
         __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
         __storage_type __b = ~*__first.__seg_ & __m;
         if (__b)
-            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
+            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
     }
     return _It(__first.__seg_, static_cast<unsigned>(__n));
 }
@@ -238,8 +239,8 @@
 find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
 {
     if (static_cast<bool>(__value_))
-        return __find_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
-    return __find_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
+        return _VSTD::__find_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
+    return _VSTD::__find_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
 }
 
 // count
@@ -251,7 +252,7 @@
     typedef __bit_iterator<_Cp, _IsConst> _It;
     typedef typename _It::__storage_type __storage_type;
     typedef typename _It::difference_type difference_type;
-    static const unsigned __bits_per_word = _It::__bits_per_word;
+    const int __bits_per_word = _It::__bits_per_word;
     difference_type __r = 0;
     // do first partial word
     if (__first.__ctz_ != 0)
@@ -259,18 +260,18 @@
         __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
         __storage_type __dn = _VSTD::min(__clz_f, __n);
         __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
-        __r = _VSTD::__pop_count(*__first.__seg_ & __m);
+        __r = _VSTD::__libcpp_popcount(*__first.__seg_ & __m);
         __n -= __dn;
         ++__first.__seg_;
     }
     // do middle whole words
     for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
-        __r += _VSTD::__pop_count(*__first.__seg_);
+        __r += _VSTD::__libcpp_popcount(*__first.__seg_);
     // do last partial word
     if (__n > 0)
     {
         __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
-        __r += _VSTD::__pop_count(*__first.__seg_ & __m);
+        __r += _VSTD::__libcpp_popcount(*__first.__seg_ & __m);
     }
     return __r;
 }
@@ -282,7 +283,7 @@
     typedef __bit_iterator<_Cp, _IsConst> _It;
     typedef typename _It::__storage_type __storage_type;
     typedef typename _It::difference_type difference_type;
-    static const unsigned __bits_per_word = _It::__bits_per_word;
+    const int __bits_per_word = _It::__bits_per_word;
     difference_type __r = 0;
     // do first partial word
     if (__first.__ctz_ != 0)
@@ -290,18 +291,18 @@
         __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
         __storage_type __dn = _VSTD::min(__clz_f, __n);
         __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
-        __r = _VSTD::__pop_count(~*__first.__seg_ & __m);
+        __r = _VSTD::__libcpp_popcount(~*__first.__seg_ & __m);
         __n -= __dn;
         ++__first.__seg_;
     }
     // do middle whole words
     for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
-        __r += _VSTD::__pop_count(~*__first.__seg_);
+        __r += _VSTD::__libcpp_popcount(~*__first.__seg_);
     // do last partial word
     if (__n > 0)
     {
         __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
-        __r += _VSTD::__pop_count(~*__first.__seg_ & __m);
+        __r += _VSTD::__libcpp_popcount(~*__first.__seg_ & __m);
     }
     return __r;
 }
@@ -312,8 +313,8 @@
 count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
 {
     if (static_cast<bool>(__value_))
-        return __count_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
-    return __count_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
+        return _VSTD::__count_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
+    return _VSTD::__count_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
 }
 
 // fill_n
@@ -324,7 +325,7 @@
 {
     typedef __bit_iterator<_Cp, false> _It;
     typedef typename _It::__storage_type __storage_type;
-    static const unsigned __bits_per_word = _It::__bits_per_word;
+    const int __bits_per_word = _It::__bits_per_word;
     // do first partial word
     if (__first.__ctz_ != 0)
     {
@@ -337,7 +338,7 @@
     }
     // do middle whole words
     __storage_type __nw = __n / __bits_per_word;
-    _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type));
+    _VSTD::memset(_VSTD::__to_address(__first.__seg_), 0, __nw * sizeof(__storage_type));
     __n -= __nw * __bits_per_word;
     // do last partial word
     if (__n > 0)
@@ -354,7 +355,7 @@
 {
     typedef __bit_iterator<_Cp, false> _It;
     typedef typename _It::__storage_type __storage_type;
-    static const unsigned __bits_per_word = _It::__bits_per_word;
+    const int __bits_per_word = _It::__bits_per_word;
     // do first partial word
     if (__first.__ctz_ != 0)
     {
@@ -367,7 +368,7 @@
     }
     // do middle whole words
     __storage_type __nw = __n / __bits_per_word;
-    _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type));
+    _VSTD::memset(_VSTD::__to_address(__first.__seg_), -1, __nw * sizeof(__storage_type));
     __n -= __nw * __bits_per_word;
     // do last partial word
     if (__n > 0)
@@ -386,9 +387,9 @@
     if (__n > 0)
     {
         if (__value_)
-            __fill_n_true(__first, __n);
+            _VSTD::__fill_n_true(__first, __n);
         else
-            __fill_n_false(__first, __n);
+            _VSTD::__fill_n_false(__first, __n);
     }
 }
 
@@ -412,7 +413,7 @@
     typedef __bit_iterator<_Cp, _IsConst> _In;
     typedef  typename _In::difference_type difference_type;
     typedef typename _In::__storage_type __storage_type;
-    static const unsigned __bits_per_word = _In::__bits_per_word;
+    const int __bits_per_word = _In::__bits_per_word;
     difference_type __n = __last - __first;
     if (__n > 0)
     {
@@ -434,8 +435,8 @@
         // __first.__ctz_ == 0;
         // do middle words
         __storage_type __nw = __n / __bits_per_word;
-        _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
-                       _VSTD::__to_raw_pointer(__first.__seg_),
+        _VSTD::memmove(_VSTD::__to_address(__result.__seg_),
+                       _VSTD::__to_address(__first.__seg_),
                        __nw * sizeof(__storage_type));
         __n -= __nw * __bits_per_word;
         __result.__seg_ += __nw;
@@ -461,7 +462,7 @@
     typedef __bit_iterator<_Cp, _IsConst> _In;
     typedef  typename _In::difference_type difference_type;
     typedef typename _In::__storage_type __storage_type;
-    static const unsigned __bits_per_word = _In::__bits_per_word;
+    static const int __bits_per_word = _In::__bits_per_word;
     difference_type __n = __last - __first;
     if (__n > 0)
     {
@@ -537,8 +538,8 @@
 copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
 {
     if (__first.__ctz_ == __result.__ctz_)
-        return __copy_aligned(__first, __last, __result);
-    return __copy_unaligned(__first, __last, __result);
+        return _VSTD::__copy_aligned(__first, __last, __result);
+    return _VSTD::__copy_unaligned(__first, __last, __result);
 }
 
 // copy_backward
@@ -551,7 +552,7 @@
     typedef __bit_iterator<_Cp, _IsConst> _In;
     typedef  typename _In::difference_type difference_type;
     typedef typename _In::__storage_type __storage_type;
-    static const unsigned __bits_per_word = _In::__bits_per_word;
+    const int __bits_per_word = _In::__bits_per_word;
     difference_type __n = __last - __first;
     if (__n > 0)
     {
@@ -575,8 +576,8 @@
         __storage_type __nw = __n / __bits_per_word;
         __result.__seg_ -= __nw;
         __last.__seg_ -= __nw;
-        _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
-                       _VSTD::__to_raw_pointer(__last.__seg_),
+        _VSTD::memmove(_VSTD::__to_address(__result.__seg_),
+                       _VSTD::__to_address(__last.__seg_),
                        __nw * sizeof(__storage_type));
         __n -= __nw * __bits_per_word;
         // do last word
@@ -600,7 +601,7 @@
     typedef __bit_iterator<_Cp, _IsConst> _In;
     typedef  typename _In::difference_type difference_type;
     typedef typename _In::__storage_type __storage_type;
-    static const unsigned __bits_per_word = _In::__bits_per_word;
+    const int __bits_per_word = _In::__bits_per_word;
     difference_type __n = __last - __first;
     if (__n > 0)
     {
@@ -684,8 +685,8 @@
 copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
 {
     if (__last.__ctz_ == __result.__ctz_)
-        return __copy_backward_aligned(__first, __last, __result);
-    return __copy_backward_unaligned(__first, __last, __result);
+        return _VSTD::__copy_backward_aligned(__first, __last, __result);
+    return _VSTD::__copy_backward_unaligned(__first, __last, __result);
 }
 
 // move
@@ -705,7 +706,7 @@
 __bit_iterator<_Cp, false>
 move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
 {
-    return _VSTD::copy(__first, __last, __result);
+    return _VSTD::copy_backward(__first, __last, __result);
 }
 
 // swap_ranges
@@ -718,7 +719,7 @@
     typedef __bit_iterator<__C1, false> _I1;
     typedef  typename _I1::difference_type difference_type;
     typedef typename _I1::__storage_type __storage_type;
-    static const unsigned __bits_per_word = _I1::__bits_per_word;
+    const int __bits_per_word = _I1::__bits_per_word;
     difference_type __n = __last - __first;
     if (__n > 0)
     {
@@ -768,7 +769,7 @@
     typedef __bit_iterator<__C1, false> _I1;
     typedef  typename _I1::difference_type difference_type;
     typedef typename _I1::__storage_type __storage_type;
-    static const unsigned __bits_per_word = _I1::__bits_per_word;
+    const int __bits_per_word = _I1::__bits_per_word;
     difference_type __n = __last - __first;
     if (__n > 0)
     {
@@ -867,8 +868,8 @@
             __bit_iterator<__C2, false> __first2)
 {
     if (__first1.__ctz_ == __first2.__ctz_)
-        return __swap_ranges_aligned(__first1, __last1, __first2);
-    return __swap_ranges_unaligned(__first1, __last1, __first2);
+        return _VSTD::__swap_ranges_aligned(__first1, __last1, __first2);
+    return _VSTD::__swap_ranges_unaligned(__first1, __last1, __first2);
 }
 
 // rotate
@@ -906,7 +907,6 @@
 {
     typedef __bit_iterator<_Cp, false> _I1;
     typedef  typename _I1::difference_type difference_type;
-    typedef typename _I1::__storage_type __storage_type;
     difference_type __d1 = __middle - __first;
     difference_type __d2 = __last - __middle;
     _I1 __r = __first + __d2;
@@ -960,7 +960,7 @@
     typedef __bit_iterator<_Cp, _IC1> _It;
     typedef  typename _It::difference_type difference_type;
     typedef typename _It::__storage_type __storage_type;
-    static const unsigned __bits_per_word = _It::__bits_per_word;
+    static const int __bits_per_word = _It::__bits_per_word;
     difference_type __n = __last1 - __first1;
     if (__n > 0)
     {
@@ -1042,7 +1042,7 @@
     typedef __bit_iterator<_Cp, _IC1> _It;
     typedef  typename _It::difference_type difference_type;
     typedef typename _It::__storage_type __storage_type;
-    static const unsigned __bits_per_word = _It::__bits_per_word;
+    static const int __bits_per_word = _It::__bits_per_word;
     difference_type __n = __last1 - __first1;
     if (__n > 0)
     {
@@ -1083,8 +1083,8 @@
 equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2)
 {
     if (__first1.__ctz_ == __first2.__ctz_)
-        return __equal_aligned(__first1, __last1, __first2);
-    return __equal_unaligned(__first1, __last1, __first2);
+        return _VSTD::__equal_aligned(__first1, __last1, __first2);
+    return _VSTD::__equal_unaligned(__first1, __last1, __first2);
 }
 
 template <class _Cp, bool _IsConst,
@@ -1114,10 +1114,27 @@
 #endif
     {}
 
+    // When _IsConst=false, this is the copy constructor.
+    // It is non-trivial. Making it trivial would break ABI.
+    // When _IsConst=true, this is a converting constructor;
+    // the copy and move constructors are implicitly generated
+    // and trivial.
     _LIBCPP_INLINE_VISIBILITY
     __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
         : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
 
+    // When _IsConst=false, we have a user-provided copy constructor,
+    // so we must also provide a copy assignment operator because
+    // the implicit generation of a defaulted one is deprecated.
+    // When _IsConst=true, the assignment operators are
+    // implicitly generated and trivial.
+    _LIBCPP_INLINE_VISIBILITY
+    __bit_iterator& operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) {
+        __seg_ = __it.__seg_;
+        __ctz_ = __it.__ctz_;
+        return *this;
+    }
+
     _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
         {return reference(__seg_, __storage_type(1) << __ctz_);}
 
@@ -1222,11 +1239,8 @@
     __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
         : __seg_(__s), __ctz_(__ctz) {}
 
-#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)
     friend typename _Cp::__self;
-#else
-    friend class _Cp::__self;
-#endif
+
     friend class __bit_reference<_Cp>;
     friend class __bit_const_reference<_Cp>;
     friend class __bit_iterator<_Cp, true>;
@@ -1284,4 +1298,6 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif  // _LIBCPP___BIT_REFERENCE
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___BIT_REFERENCE
diff --git a/include/__bits b/include/__bits
new file mode 100644
index 0000000..b565a78
--- /dev/null
+++ b/include/__bits
@@ -0,0 +1,145 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BITS
+#define _LIBCPP___BITS
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_COMPILER_MSVC
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_ctz(unsigned __x)           _NOEXCEPT { return __builtin_ctz(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_ctz(unsigned long __x)      _NOEXCEPT { return __builtin_ctzl(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); }
+
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_clz(unsigned __x)           _NOEXCEPT { return __builtin_clz(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_clz(unsigned long __x)      _NOEXCEPT { return __builtin_clzl(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); }
+
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_popcount(unsigned __x)           _NOEXCEPT { return __builtin_popcount(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_popcount(unsigned long __x)      _NOEXCEPT { return __builtin_popcountl(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); }
+
+#else  // _LIBCPP_COMPILER_MSVC
+
+// Precondition:  __x != 0
+inline _LIBCPP_INLINE_VISIBILITY
+int __libcpp_ctz(unsigned __x) {
+  static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
+  static_assert(sizeof(unsigned long) == 4, "");
+  unsigned long __where;
+  if (_BitScanForward(&__where, __x))
+    return static_cast<int>(__where);
+  return 32;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __libcpp_ctz(unsigned long __x) {
+    static_assert(sizeof(unsigned long) == sizeof(unsigned), "");
+    return __ctz(static_cast<unsigned>(__x));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __libcpp_ctz(unsigned long long __x) {
+    unsigned long __where;
+#if defined(_LIBCPP_HAS_BITSCAN64)
+  if (_BitScanForward64(&__where, __x))
+    return static_cast<int>(__where);
+#else
+  // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
+  if (_BitScanForward(&__where, static_cast<unsigned long>(__x)))
+    return static_cast<int>(__where);
+  if (_BitScanForward(&__where, static_cast<unsigned long>(__x >> 32)))
+    return static_cast<int>(__where + 32);
+#endif
+  return 64;
+}
+
+// Precondition:  __x != 0
+inline _LIBCPP_INLINE_VISIBILITY
+int __libcpp_clz(unsigned __x) {
+  static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
+  static_assert(sizeof(unsigned long) == 4, "");
+  unsigned long __where;
+  if (_BitScanReverse(&__where, __x))
+    return static_cast<int>(31 - __where);
+  return 32; // Undefined Behavior.
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __libcpp_clz(unsigned long __x) {
+    static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
+    return __libcpp_clz(static_cast<unsigned>(__x));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __libcpp_clz(unsigned long long __x) {
+  unsigned long __where;
+#if defined(_LIBCPP_HAS_BITSCAN64)
+  if (_BitScanReverse64(&__where, __x))
+    return static_cast<int>(63 - __where);
+#else
+  // Win32 doesn't have _BitScanReverse64 so emulate it with two 32 bit calls.
+  if (_BitScanReverse(&__where, static_cast<unsigned long>(__x >> 32)))
+    return static_cast<int>(63 - (__where + 32));
+  if (_BitScanReverse(&__where, static_cast<unsigned long>(__x)))
+    return static_cast<int>(63 - __where);
+#endif
+  return 64; // Undefined Behavior.
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned __x) {
+  static_assert(sizeof(unsigned) == 4, "");
+  return __popcnt(__x);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long __x) {
+  static_assert(sizeof(unsigned long) == 4, "");
+  return __popcnt(__x);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long long __x) {
+  static_assert(sizeof(unsigned long long) == 8, "");
+  return __popcnt64(__x);
+}
+
+#endif // _LIBCPP_COMPILER_MSVC
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___BITS
diff --git a/include/__bsd_locale_defaults.h b/include/__bsd_locale_defaults.h
new file mode 100644
index 0000000..2ace2a2
--- /dev/null
+++ b/include/__bsd_locale_defaults.h
@@ -0,0 +1,36 @@
+// -*- C++ -*-
+//===---------------------- __bsd_locale_defaults.h -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// 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
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#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..ed0eabf
--- /dev/null
+++ b/include/__bsd_locale_fallbacks.h
@@ -0,0 +1,139 @@
+// -*- C++ -*-
+//===---------------------- __bsd_locale_fallbacks.h ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// 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 <memory>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+inline _LIBCPP_INLINE_VISIBILITY
+decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l)
+{
+    __libcpp_locale_guard __current(__l);
+    return MB_CUR_MAX;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+wint_t __libcpp_btowc_l(int __c, locale_t __l)
+{
+    __libcpp_locale_guard __current(__l);
+    return btowc(__c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __libcpp_wctob_l(wint_t __c, locale_t __l)
+{
+    __libcpp_locale_guard __current(__l);
+    return wctob(__c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+size_t __libcpp_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
+                         size_t __len, mbstate_t *__ps, locale_t __l)
+{
+    __libcpp_locale_guard __current(__l);
+    return wcsnrtombs(__dest, __src, __nwc, __len, __ps);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+size_t __libcpp_wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)
+{
+    __libcpp_locale_guard __current(__l);
+    return wcrtomb(__s, __wc, __ps);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+size_t __libcpp_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
+                      size_t __len, mbstate_t *__ps, locale_t __l)
+{
+    __libcpp_locale_guard __current(__l);
+    return mbsnrtowcs(__dest, __src, __nms, __len, __ps);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+size_t __libcpp_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
+                   mbstate_t *__ps, locale_t __l)
+{
+    __libcpp_locale_guard __current(__l);
+    return mbrtowc(__pwc, __s, __n, __ps);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __libcpp_mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)
+{
+    __libcpp_locale_guard __current(__l);
+    return mbtowc(__pwc, __pmb, __max);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)
+{
+    __libcpp_locale_guard __current(__l);
+    return mbrlen(__s, __n, __ps);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+lconv *__libcpp_localeconv_l(locale_t __l)
+{
+    __libcpp_locale_guard __current(__l);
+    return localeconv();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
+                     mbstate_t *__ps, locale_t __l)
+{
+    __libcpp_locale_guard __current(__l);
+    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);
+    __libcpp_locale_guard __current(__l);
+    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);
+    __libcpp_locale_guard __current(__l);
+    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);
+    __libcpp_locale_guard __current(__l);
+    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 ce235af..97e33f3 100644
--- a/include/__config
+++ b/include/__config
@@ -1,302 +1,478 @@
 // -*- 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.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef _LIBCPP_CONFIG
 #define _LIBCPP_CONFIG
 
-#if !defined(_MSC_VER) || defined(__clang__)
+#include <__config_site>
+
+#if defined(_MSC_VER) && !defined(__clang__)
+#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#    define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
+#  endif
+#endif
+
+#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
 #pragma GCC system_header
 #endif
 
+#ifdef __cplusplus
+
 #ifdef __GNUC__
-#define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__)
+#  define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__)
+// The _GNUC_VER_NEW macro better represents the new GCC versioning scheme
+// introduced in GCC 5.0.
+#  define _GNUC_VER_NEW (_GNUC_VER * 10 + __GNUC_PATCHLEVEL__)
+#else
+#  define _GNUC_VER 0
+#  define _GNUC_VER_NEW 0
 #endif
 
-#define _LIBCPP_VERSION 1101
+#define _LIBCPP_VERSION 13000
 
-#define _LIBCPP_ABI_VERSION 1
+#ifndef _LIBCPP_ABI_VERSION
+#  define _LIBCPP_ABI_VERSION 1
+#endif
+
+#if __STDC_HOSTED__ == 0
+#  define _LIBCPP_FREESTANDING
+#endif
+
+#ifndef _LIBCPP_STD_VER
+#  if  __cplusplus <= 201103L
+#    define _LIBCPP_STD_VER 11
+#  elif __cplusplus <= 201402L
+#    define _LIBCPP_STD_VER 14
+#  elif __cplusplus <= 201703L
+#    define _LIBCPP_STD_VER 17
+#  elif __cplusplus <= 202002L
+#    define _LIBCPP_STD_VER 20
+#  else
+#    define _LIBCPP_STD_VER 21  // current year, or date of c++2b ratification
+#  endif
+#endif // _LIBCPP_STD_VER
+
+#if defined(__ELF__)
+#  define _LIBCPP_OBJECT_FORMAT_ELF   1
+#elif defined(__MACH__)
+#  define _LIBCPP_OBJECT_FORMAT_MACHO 1
+#elif defined(_WIN32)
+#  define _LIBCPP_OBJECT_FORMAT_COFF  1
+#elif defined(__wasm__)
+#  define _LIBCPP_OBJECT_FORMAT_WASM  1
+#else
+   // ... add new file formats here ...
+#endif
+
+#if defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2
+// Change short string representation 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 its linked nodes.
+#  define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB
+// Fix undefined behavior in  how __tree stores its end and parent nodes.
+#  define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB
+// Fix undefined behavior in how __hash_table stores its pointer types.
+#  define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB
+#  define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB
+#  define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
+// Don't use a nullptr_t simulation type in C++03 instead using C++11 nullptr
+// provided under the alternate keyword __nullptr, which changes the mangling
+// of nullptr_t. This option is ABI incompatible with GCC in C++03 mode.
+#  define _LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR
+// Define a key function for `bad_function_call` in the library, to centralize
+// its vtable and typeinfo to libc++ rather than having all other libraries
+// using that class define their own copies.
+#  define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
+// Enable optimized version of __do_get_(un)signed which avoids redundant copies.
+#  define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
+// In C++20 and later, don't derive std::plus from std::binary_function,
+// nor std::negate from std::unary_function.
+#  define _LIBCPP_ABI_NO_BINDER_BASES
+// Give reverse_iterator<T> one data member of type T, not two.
+// Also, in C++17 and later, don't derive iterator types from std::iterator.
+#  define _LIBCPP_ABI_NO_ITERATOR_BASES
+// Use the smallest possible integer type to represent the index of the variant.
+// Previously libc++ used "unsigned int" exclusively.
+#  define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
+// Unstable attempt to provide a more optimized std::function
+#  define _LIBCPP_ABI_OPTIMIZED_FUNCTION
+// All the regex constants must be distinct and nonzero.
+#  define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
+// Use raw pointers, not wrapped ones, for std::span's iterator type.
+#  define _LIBCPP_ABI_SPAN_POINTER_ITERATORS
+// Re-worked external template instantiations for std::string with a focus on
+// performance and fast-path inlining.
+#  define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
+// Enable clang::trivial_abi on std::unique_ptr.
+#  define _LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI
+// Enable clang::trivial_abi on std::shared_ptr and std::weak_ptr
+#  define _LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI
+#elif _LIBCPP_ABI_VERSION == 1
+#  if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
+// Enable compiling copies of now inline methods into the dylib to support
+// applications compiled against older libraries. This is unnecessary with
+// COFF dllexport semantics, since dllexport forces a non-inline definition
+// of inline functions to be emitted anyway. Our own non-inline copy would
+// conflict with the dllexport-emitted copy, so we disable it.
+#    define _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS
+#  endif
+// Feature macros for disabling pre ABI v1 features. All of these options
+// are deprecated.
+#  if defined(__FreeBSD__)
+#    define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
+#  endif
+#endif
+
+#if defined(_LIBCPP_BUILDING_LIBRARY) || defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2
+// Enable additional explicit instantiations of iostreams components. This
+// reduces the number of weak definitions generated in programs that use
+// iostreams by providing a single strong definition in the shared library.
+# define _LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
+#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)
 
-#define _LIBCPP_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION)
-
-#ifdef __LITTLE_ENDIAN__
-#if __LITTLE_ENDIAN__
-#define _LIBCPP_LITTLE_ENDIAN 1
-#define _LIBCPP_BIG_ENDIAN    0
-#endif  // __LITTLE_ENDIAN__
-#endif  // __LITTLE_ENDIAN__
-
-#ifdef __BIG_ENDIAN__
-#if __BIG_ENDIAN__
-#define _LIBCPP_LITTLE_ENDIAN 0
-#define _LIBCPP_BIG_ENDIAN    1
-#endif  // __BIG_ENDIAN__
-#endif  // __BIG_ENDIAN__
-
-#ifdef __FreeBSD__
-# include <sys/endian.h>
-#  if _BYTE_ORDER == _LITTLE_ENDIAN
-#   define _LIBCPP_LITTLE_ENDIAN 1
-#   define _LIBCPP_BIG_ENDIAN    0
-# else  // _BYTE_ORDER == _LITTLE_ENDIAN
-#   define _LIBCPP_LITTLE_ENDIAN 0
-#   define _LIBCPP_BIG_ENDIAN    1
-# endif  // _BYTE_ORDER == _LITTLE_ENDIAN
-# ifndef __LONG_LONG_SUPPORTED
-#  define _LIBCPP_HAS_NO_LONG_LONG
-# endif  // __LONG_LONG_SUPPORTED
-#endif  // __FreeBSD__
-
-#ifdef __NetBSD__
-# include <sys/endian.h>
-#  if _BYTE_ORDER == _LITTLE_ENDIAN
-#   define _LIBCPP_LITTLE_ENDIAN 1
-#   define _LIBCPP_BIG_ENDIAN    0
-# else  // _BYTE_ORDER == _LITTLE_ENDIAN
-#   define _LIBCPP_LITTLE_ENDIAN 0
-#   define _LIBCPP_BIG_ENDIAN    1
-# endif  // _BYTE_ORDER == _LITTLE_ENDIAN
-# define _LIBCPP_HAS_QUICK_EXIT
-#endif  // __NetBSD__
-
-#ifdef _WIN32
-#  define _LIBCPP_LITTLE_ENDIAN 1
-#  define _LIBCPP_BIG_ENDIAN    0
-// Compiler intrinsics (GCC or MSVC)
-#  if defined(__clang__) \
-   || (defined(_MSC_VER) && _MSC_VER >= 1400) \
-   || (defined(__GNUC__) && _GNUC_VER > 403)
-#    define _LIBCPP_HAS_IS_BASE_OF
-#  endif
-#  if defined(_MSC_VER) && !defined(__clang__)
-#    define _LIBCPP_MSVC // Using Microsoft Visual C++ compiler
-#    define _LIBCPP_TOSTRING2(x) #x
-#    define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
-#    define _LIBCPP_WARNING(x) __pragma(message(__FILE__ "(" _LIBCPP_TOSTRING(__LINE__) ") : warning note: " x))
-#  endif
-#  // If mingw not explicitly detected, assume using MS C runtime only.
-#  ifndef __MINGW32__
-#    define _LIBCPP_MSVCRT // Using Microsoft's C Runtime library
-#  endif
-#endif  // _WIN32
-
-#ifdef __linux__
-#  if defined(__GNUC__) && _GNUC_VER >= 403
-#    define _LIBCPP_HAS_IS_BASE_OF
-#  endif
+#ifndef _LIBCPP_ABI_NAMESPACE
+# define _LIBCPP_ABI_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION)
 #endif
 
-#ifdef __sun__
-# include <sys/isa_defs.h>
-# ifdef _LITTLE_ENDIAN
-#   define _LIBCPP_LITTLE_ENDIAN 1
-#   define _LIBCPP_BIG_ENDIAN    0
-# else
-#   define _LIBCPP_LITTLE_ENDIAN 0
-#   define _LIBCPP_BIG_ENDIAN    1
-# endif
-#endif // __sun__
-
-#if !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN)
-# include <endian.h>
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-#  define _LIBCPP_LITTLE_ENDIAN 1
-#  define _LIBCPP_BIG_ENDIAN    0
-# elif __BYTE_ORDER == __BIG_ENDIAN
-#  define _LIBCPP_LITTLE_ENDIAN 0
-#  define _LIBCPP_BIG_ENDIAN    1
-# else  // __BYTE_ORDER == __BIG_ENDIAN
-#  error unable to determine endian
-# endif
-#endif  // !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN)
-
-#ifdef _WIN32
-
-// only really useful for a DLL
-#ifdef _LIBCPP_DLL // this should be a compiler builtin define ideally...
-# ifdef cxx_EXPORTS
-#  define _LIBCPP_HIDDEN
-#  define _LIBCPP_FUNC_VIS __declspec(dllexport)
-#  define _LIBCPP_TYPE_VIS __declspec(dllexport)
-# else
-#  define _LIBCPP_HIDDEN
-#  define _LIBCPP_FUNC_VIS __declspec(dllimport)
-#  define _LIBCPP_TYPE_VIS __declspec(dllimport)
-# endif
-#else
-# define _LIBCPP_HIDDEN
-# define _LIBCPP_FUNC_VIS
-# define _LIBCPP_TYPE_VIS
+#if __cplusplus < 201103L
+#define _LIBCPP_CXX03_LANG
 #endif
 
-#define _LIBCPP_TYPE_VIS_ONLY
-#define _LIBCPP_FUNC_VIS_ONLY
-
-#ifndef _LIBCPP_INLINE_VISIBILITY
-# ifdef _LIBCPP_MSVC
-#  define _LIBCPP_INLINE_VISIBILITY __forceinline
-# else // MinGW GCC and Clang
-#  define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__))
-# endif
-#endif
-
-#ifndef _LIBCPP_EXCEPTION_ABI
-#define _LIBCPP_EXCEPTION_ABI _LIBCPP_TYPE_VIS
-#endif
-
-#ifndef _LIBCPP_ALWAYS_INLINE
-# ifdef _LIBCPP_MSVC
-#  define _LIBCPP_ALWAYS_INLINE __forceinline
-# endif
-#endif
-
-#endif // _WIN32
-
 #ifndef __has_attribute
 #define __has_attribute(__x) 0
 #endif
 
-#ifndef _LIBCPP_HIDDEN
-#define _LIBCPP_HIDDEN __attribute__ ((__visibility__("hidden")))
+#ifndef __has_builtin
+#define __has_builtin(__x) 0
 #endif
 
-#ifndef _LIBCPP_FUNC_VIS
-#define _LIBCPP_FUNC_VIS __attribute__ ((__visibility__("default")))
+#ifndef __has_extension
+#define __has_extension(__x) 0
 #endif
 
-#ifndef _LIBCPP_TYPE_VIS
-#  if __has_attribute(__type_visibility__)
-#    define _LIBCPP_TYPE_VIS __attribute__ ((__type_visibility__("default")))
+#ifndef __has_feature
+#define __has_feature(__x) 0
+#endif
+
+#ifndef __has_cpp_attribute
+#define __has_cpp_attribute(__x) 0
+#endif
+
+// '__is_identifier' returns '0' if '__x' is a reserved identifier provided by
+// the compiler and '1' otherwise.
+#ifndef __is_identifier
+#define __is_identifier(__x) 1
+#endif
+
+#ifndef __has_declspec_attribute
+#define __has_declspec_attribute(__x) 0
+#endif
+
+#define __has_keyword(__x) !(__is_identifier(__x))
+
+#ifndef __has_include
+#define __has_include(...) 0
+#endif
+
+#if defined(__apple_build_version__)
+#  define _LIBCPP_COMPILER_CLANG_BASED
+#  define _LIBCPP_APPLE_CLANG_VER (__apple_build_version__ / 10000)
+#elif defined(__clang__)
+#  define _LIBCPP_COMPILER_CLANG_BASED
+#  define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__)
+#elif defined(__GNUC__)
+#  define _LIBCPP_COMPILER_GCC
+#elif defined(_MSC_VER)
+#  define _LIBCPP_COMPILER_MSVC
+#elif defined(__IBMCPP__)
+#  define _LIBCPP_COMPILER_IBM
+#endif
+
+#if defined(_LIBCPP_COMPILER_GCC) && __cplusplus < 201103L
+#error "libc++ does not support using GCC with C++03. Please enable C++11"
+#endif
+
+// FIXME: ABI detection should be done via compiler builtin macros. This
+// is just a placeholder until Clang implements such macros. For now assume
+// that Windows compilers pretending to be MSVC++ target the Microsoft ABI,
+// and allow the user to explicitly specify the ABI to handle cases where this
+// heuristic falls short.
+#if defined(_LIBCPP_ABI_FORCE_ITANIUM) && defined(_LIBCPP_ABI_FORCE_MICROSOFT)
+#  error "Only one of _LIBCPP_ABI_FORCE_ITANIUM and _LIBCPP_ABI_FORCE_MICROSOFT can be defined"
+#elif defined(_LIBCPP_ABI_FORCE_ITANIUM)
+#  define _LIBCPP_ABI_ITANIUM
+#elif defined(_LIBCPP_ABI_FORCE_MICROSOFT)
+#  define _LIBCPP_ABI_MICROSOFT
+#else
+#  if defined(_WIN32) && defined(_MSC_VER)
+#    define _LIBCPP_ABI_MICROSOFT
 #  else
-#    define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default")))
+#    define _LIBCPP_ABI_ITANIUM
 #  endif
 #endif
 
-#ifndef _LIBCPP_TYPE_VIS_ONLY
-# define _LIBCPP_TYPE_VIS_ONLY _LIBCPP_TYPE_VIS
+#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME)
+# define _LIBCPP_ABI_VCRUNTIME
 #endif
 
-#ifndef _LIBCPP_FUNC_VIS_ONLY
-# define _LIBCPP_FUNC_VIS_ONLY _LIBCPP_FUNC_VIS
+// Need to detect which libc we're using if we're on Linux.
+#if defined(__linux__)
+#  include <features.h>
+#  if defined(__GLIBC_PREREQ)
+#    define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b)
+#  else
+#    define _LIBCPP_GLIBC_PREREQ(a, b) 0
+#  endif // defined(__GLIBC_PREREQ)
+#endif // defined(__linux__)
+
+#ifdef __LITTLE_ENDIAN__
+#  if __LITTLE_ENDIAN__
+#    define _LIBCPP_LITTLE_ENDIAN
+#  endif  // __LITTLE_ENDIAN__
+#endif // __LITTLE_ENDIAN__
+
+#ifdef __BIG_ENDIAN__
+#  if __BIG_ENDIAN__
+#    define _LIBCPP_BIG_ENDIAN
+#  endif  // __BIG_ENDIAN__
+#endif // __BIG_ENDIAN__
+
+#ifdef __BYTE_ORDER__
+#  if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#    define _LIBCPP_LITTLE_ENDIAN
+#  elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#    define _LIBCPP_BIG_ENDIAN
+#  endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#endif // __BYTE_ORDER__
+
+#ifdef __FreeBSD__
+#  include <sys/endian.h>
+#  include <osreldate.h>
+#  if _BYTE_ORDER == _LITTLE_ENDIAN
+#    define _LIBCPP_LITTLE_ENDIAN
+#  else  // _BYTE_ORDER == _LITTLE_ENDIAN
+#    define _LIBCPP_BIG_ENDIAN
+#  endif  // _BYTE_ORDER == _LITTLE_ENDIAN
+#  ifndef __LONG_LONG_SUPPORTED
+#    define _LIBCPP_HAS_NO_LONG_LONG
+#  endif  // __LONG_LONG_SUPPORTED
+#endif // __FreeBSD__
+
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+#  include <sys/endian.h>
+#  if _BYTE_ORDER == _LITTLE_ENDIAN
+#    define _LIBCPP_LITTLE_ENDIAN
+#  else  // _BYTE_ORDER == _LITTLE_ENDIAN
+#    define _LIBCPP_BIG_ENDIAN
+#  endif  // _BYTE_ORDER == _LITTLE_ENDIAN
+#endif // defined(__NetBSD__) || defined(__OpenBSD__)
+
+#if defined(_WIN32)
+#  define _LIBCPP_WIN32API
+#  define _LIBCPP_LITTLE_ENDIAN
+#  define _LIBCPP_SHORT_WCHAR   1
+// Both MinGW and native MSVC provide a "MSVC"-like environment
+#  define _LIBCPP_MSVCRT_LIKE
+// If mingw not explicitly detected, assume using MS C runtime only if
+// a MS compatibility version is specified.
+#  if defined(_MSC_VER) && !defined(__MINGW32__)
+#    define _LIBCPP_MSVCRT // Using Microsoft's C Runtime library
+#  endif
+#  if (defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_ARM) || defined(__arm__))
+#    define _LIBCPP_HAS_BITSCAN64
+#  endif
+#  define _LIBCPP_HAS_OPEN_WITH_WCHAR
+#  if defined(_LIBCPP_MSVCRT)
+#    define _LIBCPP_HAS_QUICK_EXIT
+#  endif
+
+// Some CRT APIs are unavailable to store apps
+#  if defined(WINAPI_FAMILY)
+#    include <winapifamily.h>
+#    if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) &&                  \
+        (!defined(WINAPI_PARTITION_SYSTEM) ||                                  \
+         !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_SYSTEM))
+#      define _LIBCPP_WINDOWS_STORE_APP
+#    endif
+#  endif
+#endif // defined(_WIN32)
+
+#ifdef __sun__
+#  include <sys/isa_defs.h>
+#  ifdef _LITTLE_ENDIAN
+#    define _LIBCPP_LITTLE_ENDIAN
+#  else
+#    define _LIBCPP_BIG_ENDIAN
+#  endif
+#endif // __sun__
+
+#if defined(__OpenBSD__) || defined(__CloudABI__)
+   // Certain architectures provide arc4random(). Prefer using
+   // arc4random() over /dev/{u,}random to make it possible to obtain
+   // random data even when using sandboxing mechanisms such as chroots,
+   // Capsicum, etc.
+#  define _LIBCPP_USING_ARC4_RANDOM
+#elif defined(__Fuchsia__) || defined(__wasi__)
+#  define _LIBCPP_USING_GETENTROPY
+#elif defined(__native_client__)
+   // NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access,
+   // including accesses to the special files under /dev. C++11's
+   // std::random_device is instead exposed through a NaCl syscall.
+#  define _LIBCPP_USING_NACL_RANDOM
+#elif defined(_LIBCPP_WIN32API)
+#  define _LIBCPP_USING_WIN32_RANDOM
+#else
+#  define _LIBCPP_USING_DEV_RANDOM
 #endif
 
-#ifndef _LIBCPP_INLINE_VISIBILITY
-#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
+#if !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN)
+#  include <endian.h>
+#  if __BYTE_ORDER == __LITTLE_ENDIAN
+#    define _LIBCPP_LITTLE_ENDIAN
+#  elif __BYTE_ORDER == __BIG_ENDIAN
+#    define _LIBCPP_BIG_ENDIAN
+#  else  // __BYTE_ORDER == __BIG_ENDIAN
+#    error unable to determine endian
+#  endif
+#endif // !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN)
+
+#if __has_attribute(__no_sanitize__) && !defined(_LIBCPP_COMPILER_GCC)
+#  define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi")))
+#else
+#  define _LIBCPP_NO_CFI
 #endif
 
-#ifndef _LIBCPP_EXCEPTION_ABI
-#define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default")))
+// If the compiler supports using_if_exists, pretend we have those functions and they'll
+// be picked up if the C library provides them.
+//
+// TODO: Once we drop support for Clang 12, we can assume the compiler supports using_if_exists
+//       for platforms that don't have a conforming C11 library, so we can drop this whole thing.
+#if __has_attribute(using_if_exists)
+# define _LIBCPP_HAS_TIMESPEC_GET
+# define _LIBCPP_HAS_QUICK_EXIT
+# define _LIBCPP_HAS_ALIGNED_ALLOC
+#else
+#if (defined(__ISO_C_VISIBLE) && (__ISO_C_VISIBLE >= 2011)) || __cplusplus >= 201103L
+#  if defined(__FreeBSD__)
+#    define _LIBCPP_HAS_ALIGNED_ALLOC
+#    define _LIBCPP_HAS_QUICK_EXIT
+#    if __FreeBSD_version >= 1300064 || \
+       (__FreeBSD_version >= 1201504 && __FreeBSD_version < 1300000)
+#      define _LIBCPP_HAS_TIMESPEC_GET
+#    endif
+#  elif defined(__BIONIC__)
+#    if __ANDROID_API__ >= 21
+#      define _LIBCPP_HAS_QUICK_EXIT
+#    endif
+#    if __ANDROID_API__ >= 28
+#      define _LIBCPP_HAS_ALIGNED_ALLOC
+#    endif
+#    if __ANDROID_API__ >= 29
+#      define _LIBCPP_HAS_TIMESPEC_GET
+#    endif
+#  elif defined(__Fuchsia__) || defined(__wasi__) || defined(__NetBSD__)
+#    define _LIBCPP_HAS_ALIGNED_ALLOC
+#    define _LIBCPP_HAS_QUICK_EXIT
+#    define _LIBCPP_HAS_TIMESPEC_GET
+#  elif defined(__OpenBSD__)
+#    define _LIBCPP_HAS_ALIGNED_ALLOC
+#    define _LIBCPP_HAS_TIMESPEC_GET
+#  elif defined(__linux__)
+#    if !defined(_LIBCPP_HAS_MUSL_LIBC)
+#      if _LIBCPP_GLIBC_PREREQ(2, 15) || defined(__BIONIC__)
+#        define _LIBCPP_HAS_QUICK_EXIT
+#      endif
+#      if _LIBCPP_GLIBC_PREREQ(2, 17)
+#        define _LIBCPP_HAS_ALIGNED_ALLOC
+#        define _LIBCPP_HAS_TIMESPEC_GET
+#      endif
+#    else // defined(_LIBCPP_HAS_MUSL_LIBC)
+#      define _LIBCPP_HAS_ALIGNED_ALLOC
+#      define _LIBCPP_HAS_QUICK_EXIT
+#      define _LIBCPP_HAS_TIMESPEC_GET
+#    endif
+#  elif defined(_LIBCPP_MSVCRT)
+     // Using Microsoft's C Runtime library, not MinGW
+#    define _LIBCPP_HAS_TIMESPEC_GET
+#  elif defined(__APPLE__)
+     // timespec_get and aligned_alloc were introduced in macOS 10.15 and
+     // aligned releases
+#    if ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500) || \
+         (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 130000) || \
+         (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 130000) || \
+         (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 60000))
+#      define _LIBCPP_HAS_ALIGNED_ALLOC
+#      define _LIBCPP_HAS_TIMESPEC_GET
+#    endif
+#  endif // __APPLE__
+#endif
+#endif // __has_attribute(using_if_exists)
+
+#ifndef _LIBCPP_CXX03_LANG
+# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp)
+#elif defined(_LIBCPP_COMPILER_CLANG_BASED)
+# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp)
+#else
+# error "We don't know a correct way to implement alignof(T) in C++03 outside of Clang"
 #endif
 
-#ifndef _LIBCPP_ALWAYS_INLINE
-#define _LIBCPP_ALWAYS_INLINE  __attribute__ ((__visibility__("hidden"), __always_inline__))
+#define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp)
+
+#if defined(_LIBCPP_COMPILER_CLANG_BASED)
+
+#if defined(_LIBCPP_ALTERNATE_STRING_LAYOUT)
+#  error _LIBCPP_ALTERNATE_STRING_LAYOUT is deprecated, please use _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT instead
 #endif
-
-#if defined(__clang__)
-
-#if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) &&        \
-    !defined(__arm__)
-#define _LIBCPP_ALTERNATE_STRING_LAYOUT
+#if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) &&       \
+    (!defined(__arm__) || __ARM_ARCH_7K__ >= 2)
+#  define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
 #endif
 
 #if __has_feature(cxx_alignas)
 #  define _ALIGNAS_TYPE(x) alignas(x)
 #  define _ALIGNAS(x) alignas(x)
 #else
-#  define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
+#  define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
 #  define _ALIGNAS(x) __attribute__((__aligned__(x)))
 #endif
 
-#if !__has_feature(cxx_alias_templates)
-#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-#endif
-
 #if __cplusplus < 201103L
-#ifdef __linux__
-#define _LIBCPP_HAS_NO_UNICODE_CHARS
-#else
 typedef __char16_t char16_t;
 typedef __char32_t char32_t;
 #endif
-#endif
 
-#if !(__has_feature(cxx_exceptions))
-#define _LIBCPP_NO_EXCEPTIONS
-#endif
-
-#if !(__has_feature(cxx_rtti))
-#define _LIBCPP_NO_RTTI
+#if !__has_feature(cxx_exceptions)
+#  define _LIBCPP_NO_EXCEPTIONS
 #endif
 
 #if !(__has_feature(cxx_strong_enums))
 #define _LIBCPP_HAS_NO_STRONG_ENUMS
 #endif
 
-#if !(__has_feature(cxx_decltype))
-#define _LIBCPP_HAS_NO_DECLTYPE
-#endif
-
 #if __has_feature(cxx_attributes)
 #  define _LIBCPP_NORETURN [[noreturn]]
 #else
 #  define _LIBCPP_NORETURN __attribute__ ((noreturn))
 #endif
 
-#if !(__has_feature(cxx_defaulted_functions))
-#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
-#endif  // !(__has_feature(cxx_defaulted_functions))
-
-#if !(__has_feature(cxx_deleted_functions))
-#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS
-#endif  // !(__has_feature(cxx_deleted_functions))
-
-#if !(__has_feature(cxx_lambdas))
-#define _LIBCPP_HAS_NO_LAMBDAS
-#endif
-
 #if !(__has_feature(cxx_nullptr))
-#define _LIBCPP_HAS_NO_NULLPTR
-#endif
-
-#if !(__has_feature(cxx_rvalue_references))
-#define _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#endif
-
-#if !(__has_feature(cxx_static_assert))
-#define _LIBCPP_HAS_NO_STATIC_ASSERT
-#endif
-
-#if !(__has_feature(cxx_auto_type))
-#define _LIBCPP_HAS_NO_AUTO_TYPE
-#endif
-
-#if !(__has_feature(cxx_access_control_sfinae)) || !__has_feature(cxx_trailing_return)
-#define _LIBCPP_HAS_NO_ADVANCED_SFINAE
-#endif
-
-#if !(__has_feature(cxx_variadic_templates))
-#define _LIBCPP_HAS_NO_VARIADICS
-#endif
-
-#if !(__has_feature(cxx_trailing_return))
-#define _LIBCPP_HAS_NO_TRAILING_RETURN
-#endif
-
-#if !(__has_feature(cxx_generalized_initializers))
-#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-#endif
-
-#if __has_feature(is_base_of)
-#  define _LIBCPP_HAS_IS_BASE_OF
+#  if (__has_extension(cxx_nullptr) || __has_keyword(__nullptr)) && defined(_LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR)
+#    define nullptr __nullptr
+#  else
+#    define _LIBCPP_HAS_NO_NULLPTR
+#  endif
 #endif
 
 // Objective-C++ features (opt-in)
@@ -306,320 +482,465 @@
 
 #if __has_feature(objc_arc_weak)
 #define _LIBCPP_HAS_OBJC_ARC_WEAK
-#define _LIBCPP_HAS_NO_STRONG_ENUMS
 #endif
 
-#if !(__has_feature(cxx_constexpr))
-#define _LIBCPP_HAS_NO_CONSTEXPR
+#if __has_extension(blocks)
+#  define _LIBCPP_HAS_EXTENSION_BLOCKS
+#endif
+
+#if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) && defined(__APPLE__)
+#  define _LIBCPP_HAS_BLOCKS_RUNTIME
 #endif
 
 #if !(__has_feature(cxx_relaxed_constexpr))
 #define _LIBCPP_HAS_NO_CXX14_CONSTEXPR
 #endif
 
-#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L
-#if defined(__FreeBSD__)
-#define _LIBCPP_HAS_QUICK_EXIT
-#define _LIBCPP_HAS_C11_FEATURES
-#elif defined(__ANDROID__)
-#define _LIBCPP_HAS_QUICK_EXIT
-#elif defined(__linux__)
-#include <features.h>
-#if __GLIBC_PREREQ(2, 15)
-#define _LIBCPP_HAS_QUICK_EXIT
-#endif
-#if __GLIBC_PREREQ(2, 17)
-#define _LIBCPP_HAS_C11_FEATURES
-#endif
-#endif
+#if !(__has_feature(cxx_variable_templates))
+#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
 #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)
-#  define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T)
-#endif
-
-#if __has_feature(is_literal)
-#  define _LIBCPP_IS_LITERAL(T) __is_literal(T)
-#endif
-
-// Inline namespaces are available in Clang regardless of C++ dialect.
-#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {
-#define _LIBCPP_END_NAMESPACE_STD  } }
-#define _VSTD std::_LIBCPP_NAMESPACE
-
-namespace std {
-  inline namespace _LIBCPP_NAMESPACE {
-  }
-}
-
-#if !defined(_LIBCPP_HAS_NO_ASAN) && !__has_feature(address_sanitizer)
+#if !__has_feature(address_sanitizer)
 #define _LIBCPP_HAS_NO_ASAN
 #endif
 
-#elif defined(__GNUC__)
+// Allow for build-time disabling of unsigned integer sanitization
+#if __has_attribute(no_sanitize)
+#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow")))
+#endif
+
+#if __has_builtin(__builtin_launder)
+#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER
+#endif
+
+#if __has_builtin(__builtin_constant_p)
+#define _LIBCPP_COMPILER_HAS_BUILTIN_CONSTANT_P
+#endif
+
+#if !__is_identifier(__has_unique_object_representations)
+#define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS
+#endif
+
+#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
+
+// Literal operators ""d and ""y are supported starting with LLVM Clang 8 and AppleClang 10.0.1
+#if (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 800) ||                 \
+    (defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1001)
+#define _LIBCPP_HAS_NO_CXX20_CHRONO_LITERALS
+#endif
+
+#define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__
+
+#elif defined(_LIBCPP_COMPILER_GCC)
 
 #define _ALIGNAS(x) __attribute__((__aligned__(x)))
-#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
+#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
 
 #define _LIBCPP_NORETURN __attribute__((noreturn))
 
-#if _GNUC_VER >= 407
-#define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T)
-#define _LIBCPP_IS_LITERAL(T) __is_literal_type(T)
+#if !defined(__EXCEPTIONS)
+#  define _LIBCPP_NO_EXCEPTIONS
 #endif
 
-#if !__EXCEPTIONS
-#define _LIBCPP_NO_EXCEPTIONS
-#endif
-
-#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-
-// constexpr was added to GCC in 4.6.
-#if _GNUC_VER < 406
-#define _LIBCPP_HAS_NO_CONSTEXPR
-// Can only use constexpr in c++11 mode.
-#elif !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L
-#define _LIBCPP_HAS_NO_CONSTEXPR
-#endif
-
-// No version of GCC supports relaxed constexpr rules
+// Determine if GCC supports relaxed constexpr
+#if !defined(__cpp_constexpr) || __cpp_constexpr < 201304L
 #define _LIBCPP_HAS_NO_CXX14_CONSTEXPR
-
-#define _NOEXCEPT throw()
-#define _NOEXCEPT_(x)
-#define _NOEXCEPT_OR_FALSE(x) false
-
-#ifndef __GXX_EXPERIMENTAL_CXX0X__
-
-#define _LIBCPP_HAS_NO_ADVANCED_SFINAE
-#define _LIBCPP_HAS_NO_DECLTYPE
-#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
-#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS
-#define _LIBCPP_HAS_NO_NULLPTR
-#define _LIBCPP_HAS_NO_STATIC_ASSERT
-#define _LIBCPP_HAS_NO_UNICODE_CHARS
-#define _LIBCPP_HAS_NO_VARIADICS
-#define _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS
-#define _LIBCPP_HAS_NO_STRONG_ENUMS
-
-#else  // __GXX_EXPERIMENTAL_CXX0X__
-
-#define _LIBCPP_HAS_NO_TRAILING_RETURN
-#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS
-
-#if _GNUC_VER < 403
-#define _LIBCPP_HAS_NO_RVALUE_REFERENCES
 #endif
 
-#if _GNUC_VER < 403
-#define _LIBCPP_HAS_NO_STATIC_ASSERT
+// GCC 5 supports variable templates
+#if !defined(__cpp_variable_templates) || __cpp_variable_templates < 201304L
+#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
 #endif
 
-#if _GNUC_VER < 404
-#define _LIBCPP_HAS_NO_DECLTYPE
-#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS
-#define _LIBCPP_HAS_NO_UNICODE_CHARS
-#define _LIBCPP_HAS_NO_VARIADICS
-#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-#endif  // _GNUC_VER < 404
-
-#if _GNUC_VER < 406
-#define _LIBCPP_HAS_NO_NULLPTR
-#endif
-
-#if _GNUC_VER < 407
-#define _LIBCPP_HAS_NO_ADVANCED_SFINAE
-#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
-#endif
-
-#endif  // __GXX_EXPERIMENTAL_CXX0X__
-
-#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { namespace _LIBCPP_NAMESPACE {
-#define _LIBCPP_END_NAMESPACE_STD  } }
-#define _VSTD std::_LIBCPP_NAMESPACE
-
-namespace std {
-namespace _LIBCPP_NAMESPACE {
-}
-using namespace _LIBCPP_NAMESPACE __attribute__((__strong__));
-}
-
-#if !defined(_LIBCPP_HAS_NO_ASAN) && !defined(__SANITIZE_ADDRESS__)
+#if !defined(__SANITIZE_ADDRESS__)
 #define _LIBCPP_HAS_NO_ASAN
 #endif
 
-#elif defined(_LIBCPP_MSVC)
+#if _GNUC_VER >= 700
+#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER
+#define _LIBCPP_COMPILER_HAS_BUILTIN_CONSTANT_P
+#define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS
+#endif
 
-#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-#define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
-#define _LIBCPP_HAS_NO_CONSTEXPR
+#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
+
+#define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__
+
+#elif defined(_LIBCPP_COMPILER_MSVC)
+
+#define _LIBCPP_TOSTRING2(x) #x
+#define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
+#define _LIBCPP_WARNING(x) __pragma(message(__FILE__ "(" _LIBCPP_TOSTRING(__LINE__) ") : warning note: " x))
+
+#if _MSC_VER < 1900
+#error "MSVC versions prior to Visual Studio 2015 are not supported"
+#endif
+
 #define _LIBCPP_HAS_NO_CXX14_CONSTEXPR
-#define _LIBCPP_HAS_NO_UNICODE_CHARS
-#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS
-#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
 #define __alignof__ __alignof
 #define _LIBCPP_NORETURN __declspec(noreturn)
 #define _ALIGNAS(x) __declspec(align(x))
-#define _LIBCPP_HAS_NO_VARIADICS
+#define _ALIGNAS_TYPE(x) alignas(x)
 
-#define _NOEXCEPT throw ()
-#define _NOEXCEPT_(x)
-#define _NOEXCEPT_OR_FALSE(x) false
-
-#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {
-#define _LIBCPP_END_NAMESPACE_STD  }
-#define _VSTD std
-
-#  define _LIBCPP_WEAK
-namespace std {
-}
+#define _LIBCPP_WEAK
 
 #define _LIBCPP_HAS_NO_ASAN
 
-#elif defined(__IBMCPP__)
+#define _LIBCPP_ALWAYS_INLINE __forceinline
+
+#define _LIBCPP_HAS_NO_VECTOR_EXTENSION
+
+#define _LIBCPP_DISABLE_EXTENSION_WARNING
+
+#elif defined(_LIBCPP_COMPILER_IBM)
 
 #define _ALIGNAS(x) __attribute__((__aligned__(x)))
-#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
+#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
 #define _ATTRIBUTE(x) __attribute__((x))
 #define _LIBCPP_NORETURN __attribute__((noreturn))
 
-#define _NOEXCEPT throw()
-#define _NOEXCEPT_(x)
-#define _NOEXCEPT_OR_FALSE(x) false
-
-#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-#define _LIBCPP_HAS_NO_ADVANCED_SFINAE
-#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS
-#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-#define _LIBCPP_HAS_NO_NULLPTR
 #define _LIBCPP_HAS_NO_UNICODE_CHARS
-#define _LIBCPP_HAS_IS_BASE_OF
+#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
 
 #if defined(_AIX)
 #define __MULTILOCALE_API
 #endif
 
-#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {
-#define _LIBCPP_END_NAMESPACE_STD  } }
-#define _VSTD std::_LIBCPP_NAMESPACE
-
-namespace std {
-  inline namespace _LIBCPP_NAMESPACE {
-  }
-}
-
 #define _LIBCPP_HAS_NO_ASAN
 
-#endif // __clang__ || __GNUC__ || _MSC_VER || __IBMCPP__
+#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
+
+#define _LIBCPP_HAS_NO_VECTOR_EXTENSION
+
+#define _LIBCPP_DISABLE_EXTENSION_WARNING
+
+#endif // _LIBCPP_COMPILER_[CLANG|GCC|MSVC|IBM]
+
+#if defined(_LIBCPP_OBJECT_FORMAT_COFF)
+
+#ifdef _DLL
+#  define _LIBCPP_CRT_FUNC __declspec(dllimport)
+#else
+#  define _LIBCPP_CRT_FUNC
+#endif
+
+#if defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+#  define _LIBCPP_DLL_VIS
+#  define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
+#  define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
+#  define _LIBCPP_OVERRIDABLE_FUNC_VIS
+#  define _LIBCPP_EXPORTED_FROM_ABI
+#elif defined(_LIBCPP_BUILDING_LIBRARY)
+#  define _LIBCPP_DLL_VIS __declspec(dllexport)
+#  if defined(__MINGW32__)
+#    define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
+#    define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
+#  else
+#    define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
+#    define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS
+#  endif
+#  define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS
+#  define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllexport)
+#else
+#  define _LIBCPP_DLL_VIS __declspec(dllimport)
+#  define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
+#  define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
+#  define _LIBCPP_OVERRIDABLE_FUNC_VIS
+#  define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport)
+#endif
+
+#define _LIBCPP_TYPE_VIS            _LIBCPP_DLL_VIS
+#define _LIBCPP_FUNC_VIS            _LIBCPP_DLL_VIS
+#define _LIBCPP_EXCEPTION_ABI       _LIBCPP_DLL_VIS
+#define _LIBCPP_HIDDEN
+#define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+#define _LIBCPP_TEMPLATE_VIS
+#define _LIBCPP_TEMPLATE_DATA_VIS
+#define _LIBCPP_ENUM_VIS
+
+#endif // defined(_LIBCPP_OBJECT_FORMAT_COFF)
+
+#ifndef _LIBCPP_HIDDEN
+#  if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+#    define _LIBCPP_HIDDEN __attribute__ ((__visibility__("hidden")))
+#  else
+#    define _LIBCPP_HIDDEN
+#  endif
+#endif
+
+#ifndef _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+#  if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+// The inline should be removed once PR32114 is resolved
+#    define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS inline _LIBCPP_HIDDEN
+#  else
+#    define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+#  endif
+#endif
+
+#ifndef _LIBCPP_FUNC_VIS
+#  if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+#    define _LIBCPP_FUNC_VIS __attribute__ ((__visibility__("default")))
+#  else
+#    define _LIBCPP_FUNC_VIS
+#  endif
+#endif
+
+#ifndef _LIBCPP_TYPE_VIS
+#  if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+#    define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default")))
+#  else
+#    define _LIBCPP_TYPE_VIS
+#  endif
+#endif
+
+#ifndef _LIBCPP_TEMPLATE_VIS
+#  if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+#    if __has_attribute(__type_visibility__)
+#      define _LIBCPP_TEMPLATE_VIS __attribute__ ((__type_visibility__("default")))
+#    else
+#      define _LIBCPP_TEMPLATE_VIS __attribute__ ((__visibility__("default")))
+#    endif
+#  else
+#    define _LIBCPP_TEMPLATE_VIS
+#  endif
+#endif
+
+#ifndef _LIBCPP_TEMPLATE_DATA_VIS
+#  if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+#    define _LIBCPP_TEMPLATE_DATA_VIS __attribute__ ((__visibility__("default")))
+#  else
+#    define _LIBCPP_TEMPLATE_DATA_VIS
+#  endif
+#endif
+
+#ifndef _LIBCPP_EXPORTED_FROM_ABI
+#  if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+#    define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default")))
+#  else
+#    define _LIBCPP_EXPORTED_FROM_ABI
+#  endif
+#endif
+
+#ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS
+#define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_FUNC_VIS
+#endif
+
+#ifndef _LIBCPP_EXCEPTION_ABI
+#  if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+#    define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default")))
+#  else
+#    define _LIBCPP_EXCEPTION_ABI
+#  endif
+#endif
+
+#ifndef _LIBCPP_ENUM_VIS
+#  if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__)
+#    define _LIBCPP_ENUM_VIS __attribute__ ((__type_visibility__("default")))
+#  else
+#    define _LIBCPP_ENUM_VIS
+#  endif
+#endif
+
+#ifndef _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
+#  if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+#    define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __attribute__ ((__visibility__("default")))
+#  else
+#    define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
+#  endif
+#endif
+
+#ifndef _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
+#define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
+#endif
+
+#if __has_attribute(internal_linkage)
+#  define _LIBCPP_INTERNAL_LINKAGE __attribute__ ((internal_linkage))
+#else
+#  define _LIBCPP_INTERNAL_LINKAGE _LIBCPP_ALWAYS_INLINE
+#endif
+
+#if __has_attribute(exclude_from_explicit_instantiation)
+#  define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__ ((__exclude_from_explicit_instantiation__))
+#else
+   // Try to approximate the effect of exclude_from_explicit_instantiation
+   // (which is that entities are not assumed to be provided by explicit
+   // template instantiations in the dylib) by always inlining those entities.
+#  define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE
+#endif
+
+#ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU
+#  ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT
+#    define _LIBCPP_HIDE_FROM_ABI_PER_TU 0
+#  else
+#    define _LIBCPP_HIDE_FROM_ABI_PER_TU 1
+#  endif
+#endif
+
+#ifndef _LIBCPP_HIDE_FROM_ABI
+#  if _LIBCPP_HIDE_FROM_ABI_PER_TU
+#    define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE
+#  else
+#    define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
+#  endif
+#endif
+
+#ifdef _LIBCPP_BUILDING_LIBRARY
+#  if _LIBCPP_ABI_VERSION > 1
+#    define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
+#  else
+#    define _LIBCPP_HIDE_FROM_ABI_AFTER_V1
+#  endif
+#else
+#  define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
+#endif
+
+// Just so we can migrate to the new macros gradually.
+#define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI
+
+// Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect.
+#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_ABI_NAMESPACE {
+#define _LIBCPP_END_NAMESPACE_STD  } }
+#define _VSTD std::_LIBCPP_ABI_NAMESPACE
+_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 17
+#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
+  _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem {
+#else
+#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
+  _LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem {
+#endif
+
+#define _LIBCPP_END_NAMESPACE_FILESYSTEM \
+  _LIBCPP_END_NAMESPACE_STD } }
+
+#define _VSTD_FS _VSTD::__fs::filesystem
+
+#if __has_attribute(__enable_if__)
+#   define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, "")))
+#endif
+
+#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;
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
 
 #ifndef __SIZEOF_INT128__
 #define _LIBCPP_HAS_NO_INT128
 #endif
 
-#ifdef _LIBCPP_HAS_NO_STATIC_ASSERT
+#ifdef _LIBCPP_CXX03_LANG
+# define static_assert(...) _Static_assert(__VA_ARGS__)
+# define decltype(...) __decltype(__VA_ARGS__)
+#endif // _LIBCPP_CXX03_LANG
 
-template <bool> struct __static_assert_test;
-template <> struct __static_assert_test<true> {};
-template <unsigned> struct __static_assert_check {};
-#define static_assert(__b, __m) \
-    typedef __static_assert_check<sizeof(__static_assert_test<(__b)>)> \
-    _LIBCPP_CONCAT(__t, __LINE__)
-
-#endif  // _LIBCPP_HAS_NO_STATIC_ASSERT
-
-#ifdef _LIBCPP_HAS_NO_DECLTYPE
-#define decltype(x) __typeof__(x)
+#ifdef _LIBCPP_CXX03_LANG
+#  define _LIBCPP_CONSTEXPR
+#else
+#  define _LIBCPP_CONSTEXPR constexpr
 #endif
 
-#ifdef _LIBCPP_HAS_NO_CONSTEXPR
-#define _LIBCPP_CONSTEXPR
+#ifndef __cpp_consteval
+#  define _LIBCPP_CONSTEVAL _LIBCPP_CONSTEXPR
 #else
-#define _LIBCPP_CONSTEXPR constexpr
+#  define _LIBCPP_CONSTEVAL consteval
 #endif
 
-#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
-#define _LIBCPP_DEFAULT {}
+#if !defined(__cpp_concepts) || __cpp_concepts < 201907L
+#define _LIBCPP_HAS_NO_CONCEPTS
+#endif
+
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_HAS_NO_CONCEPTS)
+#define _LIBCPP_HAS_NO_RANGES
+#endif
+
+#ifdef _LIBCPP_CXX03_LANG
+#  define _LIBCPP_DEFAULT {}
 #else
-#define _LIBCPP_DEFAULT = default;
+#  define _LIBCPP_DEFAULT = default;
+#endif
+
+#ifdef _LIBCPP_CXX03_LANG
+#  define _LIBCPP_EQUAL_DELETE
+#else
+#  define _LIBCPP_EQUAL_DELETE = delete
 #endif
 
 #ifdef __GNUC__
-#define _NOALIAS __attribute__((__malloc__))
+#  define _LIBCPP_NOALIAS __attribute__((__malloc__))
 #else
-#define _NOALIAS
+#  define _LIBCPP_NOALIAS
 #endif
 
-#ifndef __has_feature
-#define __has_feature(__x) 0
-#endif
-
-#ifndef __has_builtin
-#define __has_builtin(__x) 0
-#endif
-
-#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__)
-#   define _LIBCPP_EXPLICIT explicit
+#if __has_attribute(using_if_exists)
+# define _LIBCPP_USING_IF_EXISTS __attribute__((using_if_exists))
 #else
-#   define _LIBCPP_EXPLICIT
-#endif
-
-#if !__has_builtin(__builtin_operator_new) || !__has_builtin(__builtin_operator_delete)
-#   define _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
+# define _LIBCPP_USING_IF_EXISTS
 #endif
 
 #ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
-#define _LIBCPP_DECLARE_STRONG_ENUM(x) struct _LIBCPP_TYPE_VIS x { enum __lx
-#define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \
-    __lx __v_; \
-    _LIBCPP_ALWAYS_INLINE x(__lx __v) : __v_(__v) {} \
-    _LIBCPP_ALWAYS_INLINE explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \
-    _LIBCPP_ALWAYS_INLINE operator int() const {return __v_;} \
-    };
+#  define _LIBCPP_DECLARE_STRONG_ENUM(x) struct _LIBCPP_TYPE_VIS x { enum __lx
+#  define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \
+     __lx __v_; \
+     _LIBCPP_INLINE_VISIBILITY x(__lx __v) : __v_(__v) {} \
+     _LIBCPP_INLINE_VISIBILITY explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \
+     _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;} \
+     };
 #else  // _LIBCPP_HAS_NO_STRONG_ENUMS
-#define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_TYPE_VIS x
-#define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)
-#endif  // _LIBCPP_HAS_NO_STRONG_ENUMS
+#  define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_ENUM_VIS x
+#  define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)
+#endif // _LIBCPP_HAS_NO_STRONG_ENUMS
 
-#ifdef _LIBCPP_DEBUG
-#   if _LIBCPP_DEBUG == 0
-#       define _LIBCPP_DEBUG_LEVEL 1
-#   elif _LIBCPP_DEBUG == 1
-#       define _LIBCPP_DEBUG_LEVEL 2
-#   else
-#       error Supported values for _LIBCPP_DEBUG are 0 and 1
-#   endif
-#   define _LIBCPP_EXTERN_TEMPLATE(...)
+// _LIBCPP_DEBUG potential values:
+//  - undefined: No assertions. This is the default.
+//  - 0:         Basic assertions
+//  - 1:         Basic assertions + iterator validity checks.
+#if !defined(_LIBCPP_DEBUG)
+# define _LIBCPP_DEBUG_LEVEL 0
+#elif _LIBCPP_DEBUG == 0
+# define _LIBCPP_DEBUG_LEVEL 1
+#elif _LIBCPP_DEBUG == 1
+# define _LIBCPP_DEBUG_LEVEL 2
+#else
+# error Supported values for _LIBCPP_DEBUG are 0 and 1
 #endif
 
-#ifndef _LIBCPP_EXTERN_TEMPLATE
-#define _LIBCPP_EXTERN_TEMPLATE(...)
+// Libc++ allows disabling extern template instantiation declarations by
+// means of users defining _LIBCPP_DISABLE_EXTERN_TEMPLATE.
+//
+// Furthermore, when the Debug mode is enabled, we disable extern declarations
+// when building user code because we don't want to use the functions compiled
+// in the library, which might not have had the debug mode enabled when built.
+// However, some extern declarations need to be used, because code correctness
+// depends on it (several instances in <locale>). Those special declarations
+// are declared with _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE, which is enabled
+// even when the debug mode is enabled.
+#if defined(_LIBCPP_DISABLE_EXTERN_TEMPLATE)
+#   define _LIBCPP_EXTERN_TEMPLATE(...) /* nothing */
+#   define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) /* nothing */
+#elif _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_BUILDING_LIBRARY)
+#   define _LIBCPP_EXTERN_TEMPLATE(...) /* nothing */
+#   define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) extern template __VA_ARGS__;
+#else
+#   define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
+#   define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) extern template __VA_ARGS__;
 #endif
 
-#ifndef _LIBCPP_EXTERN_TEMPLATE2
-#define _LIBCPP_EXTERN_TEMPLATE2(...) extern template __VA_ARGS__;
-#endif
-
-#if defined(__APPLE__) && defined(__LP64__) && !defined(__x86_64__)
-#define _LIBCPP_NONUNIQUE_RTTI_BIT (1ULL << 63)
-#endif
-
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || defined(__sun__) || defined(__NetBSD__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || \
+    defined(__sun__) || defined(__NetBSD__) || defined(__CloudABI__)
 #define _LIBCPP_LOCALE__L_EXTENSIONS 1
 #endif
 
@@ -627,6 +948,30 @@
 #define _DECLARE_C99_LDBL_MATH 1
 #endif
 
+// If we are getting operator new from the MSVC CRT, then allocation overloads
+// for align_val_t were added in 19.12, aka VS 2017 version 15.3.
+#if defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912
+#  define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+#elif defined(_LIBCPP_ABI_VCRUNTIME) && !defined(__cpp_aligned_new)
+   // We're deferring to Microsoft's STL to provide aligned new et al. We don't
+   // have it unless the language feature test macro is defined.
+#  define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+#elif defined(__MVS__)
+#  define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+#endif
+
+#if defined(__APPLE__)
+#  if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
+      defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
+#    define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
+#  endif
+#endif // defined(__APPLE__)
+
+#if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) || \
+    (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606)
+#  define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+#endif
+
 #if defined(__APPLE__) || defined(__FreeBSD__)
 #define _LIBCPP_HAS_DEFAULTRUNELOCALE
 #endif
@@ -635,59 +980,493 @@
 #define _LIBCPP_WCTYPE_IS_MASK
 #endif
 
-#ifndef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR
-#  define _LIBCPP_TRIVIAL_PAIR_COPY_CTOR 1
+#if _LIBCPP_STD_VER <= 17 || !defined(__cpp_char8_t)
+#define _LIBCPP_HAS_NO_CHAR8_T
 #endif
 
-#ifndef _LIBCPP_STD_VER
-#  if  __cplusplus <= 201103L
-#    define _LIBCPP_STD_VER 11
-#  elif __cplusplus <= 201402L
-#    define _LIBCPP_STD_VER 14
+// Deprecation macros.
+//
+// Deprecations warnings are always enabled, except when users explicitly opt-out
+// by defining _LIBCPP_DISABLE_DEPRECATION_WARNINGS.
+#if !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
+#  if __has_attribute(deprecated)
+#    define _LIBCPP_DEPRECATED __attribute__ ((deprecated))
+#  elif _LIBCPP_STD_VER > 11
+#    define _LIBCPP_DEPRECATED [[deprecated]]
 #  else
-#    define _LIBCPP_STD_VER 15  // current year, or date of c++17 ratification
+#    define _LIBCPP_DEPRECATED
 #  endif
-#endif  // _LIBCPP_STD_VER
-
-#if _LIBCPP_STD_VER > 11
-#define _LIBCPP_DEPRECATED [[deprecated]]
 #else
-#define _LIBCPP_DEPRECATED
+#  define _LIBCPP_DEPRECATED
+#endif
+
+#if !defined(_LIBCPP_CXX03_LANG)
+#  define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED
+#else
+#  define _LIBCPP_DEPRECATED_IN_CXX11
+#endif
+
+#if _LIBCPP_STD_VER >= 14
+#  define _LIBCPP_DEPRECATED_IN_CXX14 _LIBCPP_DEPRECATED
+#else
+#  define _LIBCPP_DEPRECATED_IN_CXX14
+#endif
+
+#if _LIBCPP_STD_VER >= 17
+#  define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
+#else
+#  define _LIBCPP_DEPRECATED_IN_CXX17
+#endif
+
+#if _LIBCPP_STD_VER > 17
+#  define _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_DEPRECATED
+#else
+#  define _LIBCPP_DEPRECATED_IN_CXX20
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_CHAR8_T)
+#  define _LIBCPP_DEPRECATED_WITH_CHAR8_T _LIBCPP_DEPRECATED
+#else
+#  define _LIBCPP_DEPRECATED_WITH_CHAR8_T
+#endif
+
+// Macros to enter and leave a state where deprecation warnings are suppressed.
+#if defined(_LIBCPP_COMPILER_CLANG_BASED) || defined(_LIBCPP_COMPILER_GCC)
+#   define _LIBCPP_SUPPRESS_DEPRECATED_PUSH \
+        _Pragma("GCC diagnostic push") \
+        _Pragma("GCC diagnostic ignored \"-Wdeprecated\"") \
+        _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+#   define _LIBCPP_SUPPRESS_DEPRECATED_POP \
+        _Pragma("GCC diagnostic pop")
+#else
+#   define _LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#   define _LIBCPP_SUPPRESS_DEPRECATED_POP
 #endif
 
 #if _LIBCPP_STD_VER <= 11
-#define _LIBCPP_EXPLICIT_AFTER_CXX11
-#define _LIBCPP_DEPRECATED_AFTER_CXX11
+#  define _LIBCPP_EXPLICIT_AFTER_CXX11
 #else
-#define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit
-#define _LIBCPP_DEPRECATED_AFTER_CXX11 [[deprecated]]
+#  define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit
 #endif
 
 #if _LIBCPP_STD_VER > 11 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR)
-#define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr
+#  define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr
 #else
-#define _LIBCPP_CONSTEXPR_AFTER_CXX11
+#  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
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR)
+#  define _LIBCPP_CONSTEXPR_AFTER_CXX17 constexpr
+#else
+#  define _LIBCPP_CONSTEXPR_AFTER_CXX17
+#endif
+
+// The _LIBCPP_NODISCARD_ATTRIBUTE should only be used to define other
+// NODISCARD macros to the correct attribute.
+#if __has_cpp_attribute(nodiscard) || defined(_LIBCPP_COMPILER_MSVC)
+#  define _LIBCPP_NODISCARD_ATTRIBUTE [[nodiscard]]
+#elif defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_CXX03_LANG)
+#  define _LIBCPP_NODISCARD_ATTRIBUTE [[clang::warn_unused_result]]
+#else
+// We can't use GCC's [[gnu::warn_unused_result]] and
+// __attribute__((warn_unused_result)), because GCC does not silence them via
+// (void) cast.
+#  define _LIBCPP_NODISCARD_ATTRIBUTE
+#endif
+
+// _LIBCPP_NODISCARD_EXT may be used to apply [[nodiscard]] to entities not
+// specified as such as an extension.
+#if defined(_LIBCPP_ENABLE_NODISCARD) && !defined(_LIBCPP_DISABLE_NODISCARD_EXT)
+#  define _LIBCPP_NODISCARD_EXT _LIBCPP_NODISCARD_ATTRIBUTE
+#else
+#  define _LIBCPP_NODISCARD_EXT
+#endif
+
+#if !defined(_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17) && \
+    (_LIBCPP_STD_VER > 17 || defined(_LIBCPP_ENABLE_NODISCARD))
+#  define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD_ATTRIBUTE
+#else
+#  define _LIBCPP_NODISCARD_AFTER_CXX17
+#endif
+
+#if _LIBCPP_STD_VER > 14 && defined(__cpp_inline_variables) && (__cpp_inline_variables >= 201606L)
+#  define _LIBCPP_INLINE_VAR inline
+#else
+#  define _LIBCPP_INLINE_VAR
+#endif
+
+#if defined(_LIBCPP_DEBUG) || defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR)
+#   define _LIBCPP_CONSTEXPR_IF_NODEBUG
+#else
+#   define _LIBCPP_CONSTEXPR_IF_NODEBUG constexpr
+#endif
+
+#if __has_attribute(no_destroy)
+#  define _LIBCPP_NO_DESTROY __attribute__((__no_destroy__))
+#else
+#  define _LIBCPP_NO_DESTROY
 #endif
 
 #ifndef _LIBCPP_HAS_NO_ASAN
-extern "C" void __sanitizer_annotate_contiguous_container(
+extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
   const void *, const void *, const void *, const void *);
 #endif
 
 // Try to find out if RTTI is disabled.
-// g++ and cl.exe have RTTI on by default and define a macro when it is.
-// g++ only defines the macro in 4.3.2 and onwards.
-#if !defined(_LIBCPP_NO_RTTI)
-#  if defined(__GNUG__) && (__GNUC__ >= 4 && \
-   (__GNUC_MINOR__ >= 3 || __GNUC_PATCHLEVEL__ >= 2)) && !defined(__GXX_RTTI)
-#    define _LIBCPP_NO_RTTI
-#  elif (defined(_MSC_VER) && !defined(__clang__)) && !defined(_CPPRTTI)
-#    define _LIBCPP_NO_RTTI
-#  endif
+#if defined(_LIBCPP_COMPILER_CLANG_BASED) && !__has_feature(cxx_rtti)
+#  define _LIBCPP_NO_RTTI
+#elif defined(__GNUC__) && !defined(__GXX_RTTI)
+#  define _LIBCPP_NO_RTTI
+#elif defined(_LIBCPP_COMPILER_MSVC) && !defined(_CPPRTTI)
+#  define _LIBCPP_NO_RTTI
 #endif
 
 #ifndef _LIBCPP_WEAK
-#  define _LIBCPP_WEAK __attribute__((__weak__))
+#define _LIBCPP_WEAK __attribute__((__weak__))
 #endif
 
-#endif  // _LIBCPP_CONFIG
+// Thread API
+#if !defined(_LIBCPP_HAS_NO_THREADS) && \
+    !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && \
+    !defined(_LIBCPP_HAS_THREAD_API_WIN32) && \
+    !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
+#  if defined(__FreeBSD__) || \
+      defined(__wasi__) || \
+      defined(__NetBSD__) || \
+      defined(__OpenBSD__) || \
+      defined(__NuttX__) || \
+      defined(__linux__) || \
+      defined(__GNU__) || \
+      defined(__APPLE__) || \
+      defined(__CloudABI__) || \
+      defined(__sun__) || \
+      defined(__MVS__) || \
+      defined(_AIX) || \
+      (defined(__MINGW32__) && __has_include(<pthread.h>))
+#    define _LIBCPP_HAS_THREAD_API_PTHREAD
+#  elif defined(__Fuchsia__)
+     // TODO(44575): Switch to C11 thread API when possible.
+#    define _LIBCPP_HAS_THREAD_API_PTHREAD
+#  elif defined(_LIBCPP_WIN32API)
+#    define _LIBCPP_HAS_THREAD_API_WIN32
+#  else
+#    error "No thread API"
+#  endif // _LIBCPP_HAS_THREAD_API
+#endif // _LIBCPP_HAS_NO_THREADS
+
+#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+#if defined(__ANDROID__) && __ANDROID_API__ >= 30
+#define _LIBCPP_HAS_COND_CLOCKWAIT
+#elif defined(_LIBCPP_GLIBC_PREREQ)
+#if _LIBCPP_GLIBC_PREREQ(2, 30)
+#define _LIBCPP_HAS_COND_CLOCKWAIT
+#endif
+#endif
+#endif
+
+#if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+#error _LIBCPP_HAS_THREAD_API_PTHREAD may only be defined when \
+       _LIBCPP_HAS_NO_THREADS is not defined.
+#endif
+
+#if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
+#error _LIBCPP_HAS_THREAD_API_EXTERNAL may not be defined when \
+       _LIBCPP_HAS_NO_THREADS is defined.
+#endif
+
+#if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS)
+#error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \
+       _LIBCPP_HAS_NO_THREADS is defined.
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(__STDCPP_THREADS__)
+#define __STDCPP_THREADS__ 1
+#endif
+
+// The glibc and Bionic implementation of pthreads implements
+// pthread_mutex_destroy as nop for regular mutexes. Additionally, Win32
+// mutexes have no destroy mechanism.
+//
+// This optimization can't be performed on Apple platforms, where
+// pthread_mutex_destroy can allow the kernel to release resources.
+// See https://llvm.org/D64298 for details.
+//
+// TODO(EricWF): Enable this optimization on Bionic after speaking to their
+//               respective stakeholders.
+#if (defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && defined(__GLIBC__)) \
+  || (defined(_LIBCPP_HAS_THREAD_API_C11) && defined(__Fuchsia__)) \
+  || defined(_LIBCPP_HAS_THREAD_API_WIN32)
+# define _LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION
+#endif
+
+// Destroying a condvar is a nop on Windows.
+//
+// This optimization can't be performed on Apple platforms, where
+// pthread_cond_destroy can allow the kernel to release resources.
+// See https://llvm.org/D64298 for details.
+//
+// TODO(EricWF): This is potentially true for some pthread implementations
+// as well.
+#if (defined(_LIBCPP_HAS_THREAD_API_C11) && defined(__Fuchsia__)) || \
+     defined(_LIBCPP_HAS_THREAD_API_WIN32)
+# define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
+#endif
+
+// Systems that use capability-based security (FreeBSD with Capsicum,
+// Nuxi CloudABI) may only provide local filesystem access (using *at()).
+// Functions like open(), rename(), unlink() and stat() should not be
+// used, as they attempt to access the global filesystem namespace.
+#ifdef __CloudABI__
+#define _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
+#endif
+
+// CloudABI is intended for running networked services. Processes do not
+// have standard input and output channels.
+#ifdef __CloudABI__
+#define _LIBCPP_HAS_NO_STDIN
+#define _LIBCPP_HAS_NO_STDOUT
+#endif
+
+// Some systems do not provide gets() in their C library, for security reasons.
+#if defined(_LIBCPP_MSVCRT) || \
+    (defined(__FreeBSD_version) && __FreeBSD_version >= 1300043) || \
+    defined(__OpenBSD__)
+#   define _LIBCPP_C_HAS_NO_GETS
+#endif
+
+#if defined(__BIONIC__) || defined(__CloudABI__) || defined(__NuttX__) ||      \
+    defined(__Fuchsia__) || defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC) || \
+    defined(__MVS__) || defined(__OpenBSD__)
+#define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
+#endif
+
+// Thread-unsafe functions such as strtok() and localtime()
+// are not available.
+#ifdef __CloudABI__
+#define _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
+#endif
+
+#if __has_feature(cxx_atomic) || __has_extension(c_atomic) || __has_keyword(_Atomic)
+#  define _LIBCPP_HAS_C_ATOMIC_IMP
+#elif defined(_LIBCPP_COMPILER_GCC)
+#  define _LIBCPP_HAS_GCC_ATOMIC_IMP
+#endif
+
+#if (!defined(_LIBCPP_HAS_C_ATOMIC_IMP) && \
+     !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) && \
+     !defined(_LIBCPP_HAS_EXTERNAL_ATOMIC_IMP)) \
+     || defined(_LIBCPP_HAS_NO_THREADS)
+#  define _LIBCPP_HAS_NO_ATOMIC_HEADER
+#else
+#  ifndef _LIBCPP_ATOMIC_FLAG_TYPE
+#    define _LIBCPP_ATOMIC_FLAG_TYPE bool
+#  endif
+#  ifdef _LIBCPP_FREESTANDING
+#    define _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
+#  endif
+#endif
+
+#ifndef _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+#endif
+
+#if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS)
+#  if defined(__clang__) && __has_attribute(acquire_capability)
+// Work around the attribute handling in clang.  When both __declspec and
+// __attribute__ are present, the processing goes awry preventing the definition
+// of the types.
+#    if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
+#      define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
+#    endif
+#  endif
+#endif
+
+#ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
+#   define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x))
+#else
+#   define _LIBCPP_THREAD_SAFETY_ANNOTATION(x)
+#endif
+
+#if __has_attribute(require_constant_initialization)
+#  define _LIBCPP_SAFE_STATIC __attribute__((__require_constant_initialization__))
+#else
+#  define _LIBCPP_SAFE_STATIC
+#endif
+
+#if !__has_builtin(__builtin_addressof) && _GNUC_VER < 700
+#define _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
+#endif
+
+#if !__has_builtin(__builtin_is_constant_evaluated) && _GNUC_VER < 900
+#define _LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED
+#endif
+
+#if __has_attribute(diagnose_if) && !defined(_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS)
+#  define _LIBCPP_DIAGNOSE_WARNING(...) \
+     __attribute__((diagnose_if(__VA_ARGS__, "warning")))
+#  define _LIBCPP_DIAGNOSE_ERROR(...) \
+     __attribute__((diagnose_if(__VA_ARGS__, "error")))
+#else
+#  define _LIBCPP_DIAGNOSE_WARNING(...)
+#  define _LIBCPP_DIAGNOSE_ERROR(...)
+#endif
+
+// Use a function like macro to imply that it must be followed by a semicolon
+#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
+#  define _LIBCPP_FALLTHROUGH() [[fallthrough]]
+#elif __has_cpp_attribute(clang::fallthrough)
+#  define _LIBCPP_FALLTHROUGH() [[clang::fallthrough]]
+#elif __has_attribute(fallthrough) || _GNUC_VER >= 700
+#  define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__))
+#else
+#  define _LIBCPP_FALLTHROUGH() ((void)0)
+#endif
+
+#if __has_attribute(__nodebug__)
+#define _LIBCPP_NODEBUG __attribute__((__nodebug__))
+#else
+#define _LIBCPP_NODEBUG
+#endif
+
+#if __has_attribute(__nodebug__) && (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 900)
+#   define _LIBCPP_NODEBUG_TYPE __attribute__((nodebug))
+#else
+#   define _LIBCPP_NODEBUG_TYPE
+#endif
+
+#if __has_attribute(__standalone_debug__)
+#define _LIBCPP_STANDALONE_DEBUG __attribute__((__standalone_debug__))
+#else
+#define _LIBCPP_STANDALONE_DEBUG
+#endif
+
+#if __has_attribute(__preferred_name__)
+#define _LIBCPP_PREFERRED_NAME(x) __attribute__((__preferred_name__(x)))
+#else
+#define _LIBCPP_PREFERRED_NAME(x)
+#endif
+
+#if defined(_LIBCPP_ABI_MICROSOFT) && \
+    (defined(_LIBCPP_COMPILER_MSVC) || __has_declspec_attribute(empty_bases))
+#  define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
+#else
+#  define _LIBCPP_DECLSPEC_EMPTY_BASES
+#endif
+
+#if defined(_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES)
+#define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR
+#define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+#define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
+#define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS
+#endif // _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES
+
+#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES)
+#define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
+#define _LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS
+#define _LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS
+#define _LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR
+#define _LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
+#endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES
+
+#if !defined(__cpp_deduction_guides) || __cpp_deduction_guides < 201611
+#define _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+#endif
+
+#if !__has_keyword(__is_aggregate) && (_GNUC_VER_NEW < 7001)
+#define _LIBCPP_HAS_NO_IS_AGGREGATE
+#endif
+
+#if !defined(__cpp_coroutines) || __cpp_coroutines < 201703L
+#define _LIBCPP_HAS_NO_COROUTINES
+#endif
+
+#if !defined(__cpp_impl_three_way_comparison) || __cpp_impl_three_way_comparison < 201907L
+#define _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
+#endif
+
+#if defined(_LIBCPP_COMPILER_IBM)
+#define _LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO
+#endif
+
+#if defined(_LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO)
+#  define _LIBCPP_PUSH_MACROS
+#  define _LIBCPP_POP_MACROS
+#else
+  // Don't warn about macro conflicts when we can restore them at the
+  // end of the header.
+#  ifndef _LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS
+#    define _LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS
+#  endif
+#  if defined(_LIBCPP_COMPILER_MSVC)
+#    define _LIBCPP_PUSH_MACROS    \
+       __pragma(push_macro("min")) \
+       __pragma(push_macro("max"))
+#    define _LIBCPP_POP_MACROS     \
+       __pragma(pop_macro("min"))  \
+       __pragma(pop_macro("max"))
+#  else
+#    define _LIBCPP_PUSH_MACROS        \
+       _Pragma("push_macro(\"min\")")  \
+       _Pragma("push_macro(\"max\")")
+#    define _LIBCPP_POP_MACROS         \
+       _Pragma("pop_macro(\"min\")")   \
+       _Pragma("pop_macro(\"max\")")
+#  endif
+#endif // defined(_LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO)
+
+#ifndef _LIBCPP_NO_AUTO_LINK
+#  if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY)
+#    if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+#      pragma comment(lib, "c++.lib")
+#    else
+#      pragma comment(lib, "libc++.lib")
+#    endif
+#  endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY)
+#endif // _LIBCPP_NO_AUTO_LINK
+
+// Configures the fopen close-on-exec mode character, if any. This string will
+// be appended to any mode string used by fstream for fopen/fdopen.
+//
+// Not all platforms support this, but it helps avoid fd-leaks on platforms that
+// do.
+#if defined(__BIONIC__)
+#  define _LIBCPP_FOPEN_CLOEXEC_MODE "e"
+#else
+#  define _LIBCPP_FOPEN_CLOEXEC_MODE
+#endif
+
+#ifdef _LIBCPP_COMPILER_HAS_BUILTIN_CONSTANT_P
+#define _LIBCPP_BUILTIN_CONSTANT_P(x) __builtin_constant_p(x)
+#else
+#define _LIBCPP_BUILTIN_CONSTANT_P(x) false
+#endif
+
+// Support for _FILE_OFFSET_BITS=64 landed gradually in Android, so the full set
+// of functions used in cstdio may not be available for low API levels when
+// using 64-bit file offsets on LP32.
+#if defined(__BIONIC__) && defined(__USE_FILE_OFFSET64) && __ANDROID_API__ < 24
+#define _LIBCPP_HAS_NO_FGETPOS_FSETPOS
+#endif
+
+#if __has_attribute(init_priority)
+# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((init_priority(101)))
+#else
+# define _LIBCPP_INIT_PRIORITY_MAX
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define _LIBCPP_FORMAT_PRINTF(a, b)                                            \
+  __attribute__((__format__(__printf__, a, b)))
+#else
+#define _LIBCPP_FORMAT_PRINTF(a, b)
+#endif
+
+#endif // __cplusplus
+
+#endif // _LIBCPP_CONFIG
diff --git a/include/__config_site.in b/include/__config_site.in
new file mode 100644
index 0000000..e202d92
--- /dev/null
+++ b/include/__config_site.in
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CONFIG_SITE
+#define _LIBCPP_CONFIG_SITE
+
+#cmakedefine _LIBCPP_ABI_VERSION @_LIBCPP_ABI_VERSION@
+#cmakedefine _LIBCPP_ABI_UNSTABLE
+#cmakedefine _LIBCPP_ABI_FORCE_ITANIUM
+#cmakedefine _LIBCPP_ABI_FORCE_MICROSOFT
+#cmakedefine _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT
+#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
+#cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD
+#cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL
+#cmakedefine _LIBCPP_HAS_THREAD_API_WIN32
+#cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL
+#cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS
+#cmakedefine _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS
+#cmakedefine _LIBCPP_NO_VCRUNTIME
+#cmakedefine _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION @_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION@
+#cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@
+#cmakedefine _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY
+#cmakedefine _LIBCPP_HAS_PARALLEL_ALGORITHMS
+#cmakedefine _LIBCPP_HAS_NO_RANDOM_DEVICE
+#cmakedefine _LIBCPP_HAS_NO_LOCALIZATION
+#cmakedefine _LIBCPP_HAS_NO_INCOMPLETE_FORMAT
+#cmakedefine _LIBCPP_HAS_NO_INCOMPLETE_RANGES
+
+@_LIBCPP_ABI_DEFINES@
+
+#endif // _LIBCPP_CONFIG_SITE
diff --git a/include/__debug b/include/__debug
index c151224..771e431 100644
--- a/include/__debug
+++ b/include/__debug
@@ -1,10 +1,9 @@
 // -*- C++ -*-
 //===--------------------------- __debug ----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,28 +11,75 @@
 #define _LIBCPP_DEBUG_H
 
 #include <__config>
+#include <iosfwd>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
 
-#if _LIBCPP_DEBUG_LEVEL >= 1
+#if defined(_LIBCPP_HAS_NO_NULLPTR)
+# include <cstddef>
+#endif
+
+#if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY)
 #   include <cstdlib>
 #   include <cstdio>
 #   include <cstddef>
-#   ifndef _LIBCPP_ASSERT
-#      define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (_VSTD::printf("%s\n", m), _VSTD::abort()))
-#   endif
 #endif
 
-#ifndef _LIBCPP_ASSERT
-#   define _LIBCPP_ASSERT(x, m) ((void)0)
+#if _LIBCPP_DEBUG_LEVEL == 0
+#   define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0)
+#   define _LIBCPP_ASSERT_IMPL(x, m) ((void)0)
+#elif _LIBCPP_DEBUG_LEVEL == 1
+#   define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0)
+#   define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m)))
+#elif _LIBCPP_DEBUG_LEVEL == 2
+#   define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(x, m)
+#   define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m)))
+#else
+#   error _LIBCPP_DEBUG_LEVEL must be one of 0, 1, 2
 #endif
 
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if !defined(_LIBCPP_ASSERT)
+#   define _LIBCPP_ASSERT(x, m) _LIBCPP_ASSERT_IMPL(x, m)
+#endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+struct _LIBCPP_TEMPLATE_VIS __libcpp_debug_info {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+  __libcpp_debug_info()
+      : __file_(nullptr), __line_(-1), __pred_(nullptr), __msg_(nullptr) {}
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+  __libcpp_debug_info(const char* __f, int __l, const char* __p, const char* __m)
+    : __file_(__f), __line_(__l), __pred_(__p), __msg_(__m) {}
+
+  _LIBCPP_FUNC_VIS string what() const;
+
+  const char* __file_;
+  int __line_;
+  const char* __pred_;
+  const char* __msg_;
+};
+
+/// __libcpp_debug_function_type - The type of the assertion failure handler.
+typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&);
+
+/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT
+///    fails.
+extern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function;
+
+/// __libcpp_abort_debug_function - A debug handler that aborts when called.
+_LIBCPP_NORETURN _LIBCPP_FUNC_VIS
+void __libcpp_abort_debug_function(__libcpp_debug_info const&);
+
+/// __libcpp_set_debug_function - Set the debug handler to the specified
+///    function.
+_LIBCPP_FUNC_VIS
+bool __libcpp_set_debug_function(__libcpp_debug_function_type __func);
+
+#if _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY)
+
 struct _LIBCPP_TYPE_VIS __c_node;
 
 struct _LIBCPP_TYPE_VIS __i_node
@@ -42,7 +88,7 @@
     __i_node* __next_;
     __c_node* __c_;
 
-#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+#ifndef _LIBCPP_CXX03_LANG
     __i_node(const __i_node&) = delete;
     __i_node& operator=(const __i_node&) = delete;
 #else
@@ -65,7 +111,7 @@
     __i_node** end_;
     __i_node** cap_;
 
-#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+#ifndef _LIBCPP_CXX03_LANG
     __c_node(const __c_node&) = delete;
     __c_node& operator=(const __c_node&) = delete;
 #else
@@ -102,7 +148,7 @@
 };
 
 template <class _Cont>
-bool
+inline bool
 _C_node<_Cont>::__dereferenceable(const void* __i) const
 {
     typedef typename _Cont::const_iterator iterator;
@@ -112,7 +158,7 @@
 }
 
 template <class _Cont>
-bool
+inline bool
 _C_node<_Cont>::__decrementable(const void* __i) const
 {
     typedef typename _Cont::const_iterator iterator;
@@ -122,7 +168,7 @@
 }
 
 template <class _Cont>
-bool
+inline bool
 _C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const
 {
     typedef typename _Cont::const_iterator iterator;
@@ -132,7 +178,7 @@
 }
 
 template <class _Cont>
-bool
+inline bool
 _C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const
 {
     typedef typename _Cont::const_iterator iterator;
@@ -152,7 +198,7 @@
 
     __libcpp_db();
 public:
-#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+#ifndef _LIBCPP_CXX03_LANG
     __libcpp_db(const __libcpp_db&) = delete;
     __libcpp_db& operator=(const __libcpp_db&) = delete;
 #else
@@ -171,16 +217,22 @@
     __db_c_const_iterator __c_end() const;
     __db_i_const_iterator __i_end() const;
 
+    typedef __c_node*(_InsertConstruct)(void*, void*, __c_node*);
+
+    template <class _Cont>
+    _LIBCPP_INLINE_VISIBILITY static __c_node* __create_C_node(void *__mem, void *__c, __c_node *__next) {
+        return ::new (__mem) _C_node<_Cont>(__c, __next);
+    }
+
     template <class _Cont>
     _LIBCPP_INLINE_VISIBILITY
     void __insert_c(_Cont* __c)
     {
-        __c_node* __n = __insert_c(static_cast<void*>(__c));
-        ::new(__n) _C_node<_Cont>(__n->__c_, __n->__next_);
+        __insert_c(static_cast<void*>(__c), &__create_C_node<_Cont>);
     }
 
     void __insert_i(void* __i);
-    __c_node* __insert_c(void* __c);
+    void __insert_c(void* __c, _InsertConstruct* __fn);
     void __erase_c(void* __c);
 
     void __insert_ic(void* __i, const void* __c);
@@ -214,9 +266,8 @@
 _LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db();
 
 
+#endif // _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY)
+
 _LIBCPP_END_NAMESPACE_STD
 
-#endif
-
-#endif  // _LIBCPP_DEBUG_H
-
+#endif // _LIBCPP_DEBUG_H
diff --git a/include/__errc b/include/__errc
new file mode 100644
index 0000000..81da2e1
--- /dev/null
+++ b/include/__errc
@@ -0,0 +1,217 @@
+// -*- C++ -*-
+//===---------------------------- __errc ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ERRC
+#define _LIBCPP___ERRC
+
+/*
+    system_error synopsis
+
+namespace std
+{
+
+enum class errc
+{
+    address_family_not_supported,       // EAFNOSUPPORT
+    address_in_use,                     // EADDRINUSE
+    address_not_available,              // EADDRNOTAVAIL
+    already_connected,                  // EISCONN
+    argument_list_too_long,             // E2BIG
+    argument_out_of_domain,             // EDOM
+    bad_address,                        // EFAULT
+    bad_file_descriptor,                // EBADF
+    bad_message,                        // EBADMSG
+    broken_pipe,                        // EPIPE
+    connection_aborted,                 // ECONNABORTED
+    connection_already_in_progress,     // EALREADY
+    connection_refused,                 // ECONNREFUSED
+    connection_reset,                   // ECONNRESET
+    cross_device_link,                  // EXDEV
+    destination_address_required,       // EDESTADDRREQ
+    device_or_resource_busy,            // EBUSY
+    directory_not_empty,                // ENOTEMPTY
+    executable_format_error,            // ENOEXEC
+    file_exists,                        // EEXIST
+    file_too_large,                     // EFBIG
+    filename_too_long,                  // ENAMETOOLONG
+    function_not_supported,             // ENOSYS
+    host_unreachable,                   // EHOSTUNREACH
+    identifier_removed,                 // EIDRM
+    illegal_byte_sequence,              // EILSEQ
+    inappropriate_io_control_operation, // ENOTTY
+    interrupted,                        // EINTR
+    invalid_argument,                   // EINVAL
+    invalid_seek,                       // ESPIPE
+    io_error,                           // EIO
+    is_a_directory,                     // EISDIR
+    message_size,                       // EMSGSIZE
+    network_down,                       // ENETDOWN
+    network_reset,                      // ENETRESET
+    network_unreachable,                // ENETUNREACH
+    no_buffer_space,                    // ENOBUFS
+    no_child_process,                   // ECHILD
+    no_link,                            // ENOLINK
+    no_lock_available,                  // ENOLCK
+    no_message_available,               // ENODATA
+    no_message,                         // ENOMSG
+    no_protocol_option,                 // ENOPROTOOPT
+    no_space_on_device,                 // ENOSPC
+    no_stream_resources,                // ENOSR
+    no_such_device_or_address,          // ENXIO
+    no_such_device,                     // ENODEV
+    no_such_file_or_directory,          // ENOENT
+    no_such_process,                    // ESRCH
+    not_a_directory,                    // ENOTDIR
+    not_a_socket,                       // ENOTSOCK
+    not_a_stream,                       // ENOSTR
+    not_connected,                      // ENOTCONN
+    not_enough_memory,                  // ENOMEM
+    not_supported,                      // ENOTSUP
+    operation_canceled,                 // ECANCELED
+    operation_in_progress,              // EINPROGRESS
+    operation_not_permitted,            // EPERM
+    operation_not_supported,            // EOPNOTSUPP
+    operation_would_block,              // EWOULDBLOCK
+    owner_dead,                         // EOWNERDEAD
+    permission_denied,                  // EACCES
+    protocol_error,                     // EPROTO
+    protocol_not_supported,             // EPROTONOSUPPORT
+    read_only_file_system,              // EROFS
+    resource_deadlock_would_occur,      // EDEADLK
+    resource_unavailable_try_again,     // EAGAIN
+    result_out_of_range,                // ERANGE
+    state_not_recoverable,              // ENOTRECOVERABLE
+    stream_timeout,                     // ETIME
+    text_file_busy,                     // ETXTBSY
+    timed_out,                          // ETIMEDOUT
+    too_many_files_open_in_system,      // ENFILE
+    too_many_files_open,                // EMFILE
+    too_many_links,                     // EMLINK
+    too_many_symbolic_link_levels,      // ELOOP
+    value_too_large,                    // EOVERFLOW
+    wrong_protocol_type                 // EPROTOTYPE
+};
+
+*/
+
+#include <__config>
+#include <cerrno>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Some error codes are not present on all platforms, so we provide equivalents
+// for them:
+
+//enum class errc
+_LIBCPP_DECLARE_STRONG_ENUM(errc)
+{
+    address_family_not_supported        = EAFNOSUPPORT,
+    address_in_use                      = EADDRINUSE,
+    address_not_available               = EADDRNOTAVAIL,
+    already_connected                   = EISCONN,
+    argument_list_too_long              = E2BIG,
+    argument_out_of_domain              = EDOM,
+    bad_address                         = EFAULT,
+    bad_file_descriptor                 = EBADF,
+    bad_message                         = EBADMSG,
+    broken_pipe                         = EPIPE,
+    connection_aborted                  = ECONNABORTED,
+    connection_already_in_progress      = EALREADY,
+    connection_refused                  = ECONNREFUSED,
+    connection_reset                    = ECONNRESET,
+    cross_device_link                   = EXDEV,
+    destination_address_required        = EDESTADDRREQ,
+    device_or_resource_busy             = EBUSY,
+    directory_not_empty                 = ENOTEMPTY,
+    executable_format_error             = ENOEXEC,
+    file_exists                         = EEXIST,
+    file_too_large                      = EFBIG,
+    filename_too_long                   = ENAMETOOLONG,
+    function_not_supported              = ENOSYS,
+    host_unreachable                    = EHOSTUNREACH,
+    identifier_removed                  = EIDRM,
+    illegal_byte_sequence               = EILSEQ,
+    inappropriate_io_control_operation  = ENOTTY,
+    interrupted                         = EINTR,
+    invalid_argument                    = EINVAL,
+    invalid_seek                        = ESPIPE,
+    io_error                            = EIO,
+    is_a_directory                      = EISDIR,
+    message_size                        = EMSGSIZE,
+    network_down                        = ENETDOWN,
+    network_reset                       = ENETRESET,
+    network_unreachable                 = ENETUNREACH,
+    no_buffer_space                     = ENOBUFS,
+    no_child_process                    = ECHILD,
+    no_link                             = ENOLINK,
+    no_lock_available                   = ENOLCK,
+#ifdef ENODATA
+    no_message_available                = ENODATA,
+#else
+    no_message_available                = ENOMSG,
+#endif
+    no_message                          = ENOMSG,
+    no_protocol_option                  = ENOPROTOOPT,
+    no_space_on_device                  = ENOSPC,
+#ifdef ENOSR
+    no_stream_resources                 = ENOSR,
+#else
+    no_stream_resources                 = ENOMEM,
+#endif
+    no_such_device_or_address           = ENXIO,
+    no_such_device                      = ENODEV,
+    no_such_file_or_directory           = ENOENT,
+    no_such_process                     = ESRCH,
+    not_a_directory                     = ENOTDIR,
+    not_a_socket                        = ENOTSOCK,
+#ifdef ENOSTR
+    not_a_stream                        = ENOSTR,
+#else
+    not_a_stream                        = EINVAL,
+#endif
+    not_connected                       = ENOTCONN,
+    not_enough_memory                   = ENOMEM,
+    not_supported                       = ENOTSUP,
+    operation_canceled                  = ECANCELED,
+    operation_in_progress               = EINPROGRESS,
+    operation_not_permitted             = EPERM,
+    operation_not_supported             = EOPNOTSUPP,
+    operation_would_block               = EWOULDBLOCK,
+    owner_dead                          = EOWNERDEAD,
+    permission_denied                   = EACCES,
+    protocol_error                      = EPROTO,
+    protocol_not_supported              = EPROTONOSUPPORT,
+    read_only_file_system               = EROFS,
+    resource_deadlock_would_occur       = EDEADLK,
+    resource_unavailable_try_again      = EAGAIN,
+    result_out_of_range                 = ERANGE,
+    state_not_recoverable               = ENOTRECOVERABLE,
+#ifdef ETIME
+    stream_timeout                      = ETIME,
+#else
+    stream_timeout                      = ETIMEDOUT,
+#endif
+    text_file_busy                      = ETXTBSY,
+    timed_out                           = ETIMEDOUT,
+    too_many_files_open_in_system       = ENFILE,
+    too_many_files_open                 = EMFILE,
+    too_many_links                      = EMLINK,
+    too_many_symbolic_link_levels       = ELOOP,
+    value_too_large                     = EOVERFLOW,
+    wrong_protocol_type                 = EPROTOTYPE
+};
+_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ERRC
diff --git a/include/__format/format_error.h b/include/__format/format_error.h
new file mode 100644
index 0000000..f983d0c
--- /dev/null
+++ b/include/__format/format_error.h
@@ -0,0 +1,56 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FORMAT_FORMAT_ERROR_H
+#define _LIBCPP___FORMAT_FORMAT_ERROR_H
+
+#include <__config>
+#include <stdexcept>
+
+#ifdef _LIBCPP_NO_EXCEPTIONS
+#include <cstdlib>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+class _LIBCPP_EXCEPTION_ABI format_error : public runtime_error {
+public:
+  _LIBCPP_HIDE_FROM_ABI explicit format_error(const string& __s)
+      : runtime_error(__s) {}
+  _LIBCPP_HIDE_FROM_ABI explicit format_error(const char* __s)
+      : runtime_error(__s) {}
+  virtual ~format_error() noexcept;
+};
+
+_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void
+__throw_format_error(const char* __s) {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+  throw format_error(__s);
+#else
+  (void)__s;
+  _VSTD::abort();
+#endif
+}
+
+#endif //_LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___FORMAT_FORMAT_ERROR_H
diff --git a/include/__format/format_parse_context.h b/include/__format/format_parse_context.h
new file mode 100644
index 0000000..db39c1b
--- /dev/null
+++ b/include/__format/format_parse_context.h
@@ -0,0 +1,113 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H
+#define _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H
+
+#include <__config>
+#include <__format/format_error.h>
+#include <string_view>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+// TODO FMT Remove this once we require compilers with proper C++20 support.
+// If the compiler has no concepts support, the format header will be disabled.
+// Without concepts support enable_if needs to be used and that too much effort
+// to support compilers with partial C++20 support.
+#if !defined(_LIBCPP_HAS_NO_CONCEPTS) &&                                       \
+    !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED)
+
+template <class _CharT>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_parse_context {
+public:
+  using char_type = _CharT;
+  using const_iterator = typename basic_string_view<_CharT>::const_iterator;
+  using iterator = const_iterator;
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr explicit basic_format_parse_context(basic_string_view<_CharT> __fmt,
+                                                size_t __num_args = 0) noexcept
+      : __begin_(__fmt.begin()),
+        __end_(__fmt.end()),
+        __indexing_(__unknown),
+        __next_arg_id_(0),
+        __num_args_(__num_args) {}
+
+  basic_format_parse_context(const basic_format_parse_context&) = delete;
+  basic_format_parse_context&
+  operator=(const basic_format_parse_context&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept {
+    return __begin_;
+  }
+  _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept {
+    return __end_;
+  }
+  _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(const_iterator __it) {
+    __begin_ = __it;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr size_t next_arg_id() {
+    if (__indexing_ == __manual)
+      __throw_format_error("Using automatic argument numbering in manual "
+                           "argument numbering mode");
+
+    if (__indexing_ == __unknown)
+      __indexing_ = __automatic;
+    return __next_arg_id_++;
+  }
+  _LIBCPP_HIDE_FROM_ABI constexpr void check_arg_id(size_t __id) {
+    if (__indexing_ == __automatic)
+      __throw_format_error("Using manual argument numbering in automatic "
+                           "argument numbering mode");
+
+    if (__indexing_ == __unknown)
+      __indexing_ = __manual;
+
+    // Throws an exception to make the expression a non core constant
+    // expression as required by:
+    // [format.parse.ctx]/11
+    //   Remarks: Call expressions where id >= num_args_ are not core constant
+    //   expressions ([expr.const]).
+    // Note: the Throws clause [format.parse.ctx]/10 doesn't specify the
+    // behavior when id >= num_args_.
+    if (is_constant_evaluated() && __id >= __num_args_)
+      __throw_format_error("Argument index outside the valid range");
+  }
+
+private:
+  iterator __begin_;
+  iterator __end_;
+  enum _Indexing { __unknown, __manual, __automatic };
+  _Indexing __indexing_;
+  size_t __next_arg_id_;
+  size_t __num_args_;
+};
+
+using format_parse_context = basic_format_parse_context<char>;
+using wformat_parse_context = basic_format_parse_context<wchar_t>;
+
+#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED)
+
+#endif //_LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H
diff --git a/include/__function_like.h b/include/__function_like.h
new file mode 100644
index 0000000..8a3597b
--- /dev/null
+++ b/include/__function_like.h
@@ -0,0 +1,56 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_FUNCTION_LIKE_H
+#define _LIBCPP___ITERATOR_FUNCTION_LIKE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+// Per [range.iter.ops.general] and [algorithms.requirements], functions in namespace std::ranges
+// can't be found by ADL and inhibit ADL when found by unqualified lookup. The easiest way to
+// facilitate this is to use function objects.
+//
+// Since these are still standard library functions, we use `__function_like` to eliminate most of
+// the properties that function objects get by default (e.g. semiregularity, addressability), to
+// limit the surface area of the unintended public interface, so as to curb the effect of Hyrum's
+// law.
+struct __function_like {
+  __function_like() = delete;
+  __function_like(__function_like const&) = delete;
+  __function_like& operator=(__function_like const&) = delete;
+
+  void operator&() const = delete;
+
+  struct __tag { };
+
+protected:
+  constexpr explicit __function_like(__tag) noexcept {}
+  ~__function_like() = default;
+};
+} // namespace ranges
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_FUNCTION_LIKE_H
diff --git a/include/__functional/binary_function.h b/include/__functional/binary_function.h
new file mode 100644
index 0000000..8ca7b06
--- /dev/null
+++ b/include/__functional/binary_function.h
@@ -0,0 +1,31 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H
+#define _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Arg1, class _Arg2, class _Result>
+struct _LIBCPP_TEMPLATE_VIS binary_function
+{
+    typedef _Arg1   first_argument_type;
+    typedef _Arg2   second_argument_type;
+    typedef _Result result_type;
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H
diff --git a/include/__functional/binary_negate.h b/include/__functional/binary_negate.h
new file mode 100644
index 0000000..4fc3f1b
--- /dev/null
+++ b/include/__functional/binary_negate.h
@@ -0,0 +1,50 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H
+#define _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H
+
+#include <__config>
+#include <__functional/binary_function.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS)
+
+template <class _Predicate>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 binary_negate
+    : public binary_function<typename _Predicate::first_argument_type,
+                             typename _Predicate::second_argument_type,
+                             bool>
+{
+    _Predicate __pred_;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11
+    binary_negate(const _Predicate& __pred) : __pred_(__pred) {}
+
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const typename _Predicate::first_argument_type& __x,
+                    const typename _Predicate::second_argument_type& __y) const
+        {return !__pred_(__x, __y);}
+};
+
+template <class _Predicate>
+_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+binary_negate<_Predicate>
+not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);}
+
+#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H
diff --git a/include/__functional/bind.h b/include/__functional/bind.h
new file mode 100644
index 0000000..79dfad7
--- /dev/null
+++ b/include/__functional/bind.h
@@ -0,0 +1,386 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_BIND_H
+#define _LIBCPP___FUNCTIONAL_BIND_H
+
+#include <__config>
+#include <__functional/weak_result_type.h>
+#include <__functional/invoke.h>
+#include <cstddef>
+#include <tuple>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template<class _Tp> struct __is_bind_expression : public false_type {};
+template<class _Tp> struct _LIBCPP_TEMPLATE_VIS is_bind_expression
+    : public __is_bind_expression<typename remove_cv<_Tp>::type> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+_LIBCPP_INLINE_VAR constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value;
+#endif
+
+template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {};
+template<class _Tp> struct _LIBCPP_TEMPLATE_VIS is_placeholder
+    : public __is_placeholder<typename remove_cv<_Tp>::type> {};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+_LIBCPP_INLINE_VAR constexpr size_t is_placeholder_v = is_placeholder<_Tp>::value;
+#endif
+
+namespace placeholders
+{
+
+template <int _Np> struct __ph {};
+
+#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
+_LIBCPP_FUNC_VIS extern const __ph<1>   _1;
+_LIBCPP_FUNC_VIS extern const __ph<2>   _2;
+_LIBCPP_FUNC_VIS extern const __ph<3>   _3;
+_LIBCPP_FUNC_VIS extern const __ph<4>   _4;
+_LIBCPP_FUNC_VIS extern const __ph<5>   _5;
+_LIBCPP_FUNC_VIS extern const __ph<6>   _6;
+_LIBCPP_FUNC_VIS extern const __ph<7>   _7;
+_LIBCPP_FUNC_VIS extern const __ph<8>   _8;
+_LIBCPP_FUNC_VIS extern const __ph<9>   _9;
+_LIBCPP_FUNC_VIS extern const __ph<10> _10;
+#else
+/* _LIBCPP_INLINE_VAR */ constexpr __ph<1>   _1{};
+/* _LIBCPP_INLINE_VAR */ constexpr __ph<2>   _2{};
+/* _LIBCPP_INLINE_VAR */ constexpr __ph<3>   _3{};
+/* _LIBCPP_INLINE_VAR */ constexpr __ph<4>   _4{};
+/* _LIBCPP_INLINE_VAR */ constexpr __ph<5>   _5{};
+/* _LIBCPP_INLINE_VAR */ constexpr __ph<6>   _6{};
+/* _LIBCPP_INLINE_VAR */ constexpr __ph<7>   _7{};
+/* _LIBCPP_INLINE_VAR */ constexpr __ph<8>   _8{};
+/* _LIBCPP_INLINE_VAR */ constexpr __ph<9>   _9{};
+/* _LIBCPP_INLINE_VAR */ constexpr __ph<10> _10{};
+#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
+
+}  // placeholders
+
+template<int _Np>
+struct __is_placeholder<placeholders::__ph<_Np> >
+    : public integral_constant<int, _Np> {};
+
+
+#ifndef _LIBCPP_CXX03_LANG
+
+template <class _Tp, class _Uj>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp&
+__mu(reference_wrapper<_Tp> __t, _Uj&)
+{
+    return __t.get();
+}
+
+template <class _Ti, class ..._Uj, size_t ..._Indx>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __invoke_of<_Ti&, _Uj...>::type
+__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>)
+{
+    return __ti(_VSTD::forward<_Uj>(_VSTD::get<_Indx>(__uj))...);
+}
+
+template <class _Ti, class ..._Uj>
+inline _LIBCPP_INLINE_VISIBILITY
+typename _EnableIf
+<
+    is_bind_expression<_Ti>::value,
+    __invoke_of<_Ti&, _Uj...>
+>::type
+__mu(_Ti& __ti, tuple<_Uj...>& __uj)
+{
+    typedef typename __make_tuple_indices<sizeof...(_Uj)>::type __indices;
+    return _VSTD::__mu_expand(__ti, __uj, __indices());
+}
+
+template <bool IsPh, class _Ti, class _Uj>
+struct __mu_return2 {};
+
+template <class _Ti, class _Uj>
+struct __mu_return2<true, _Ti, _Uj>
+{
+    typedef typename tuple_element<is_placeholder<_Ti>::value - 1, _Uj>::type type;
+};
+
+template <class _Ti, class _Uj>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    0 < is_placeholder<_Ti>::value,
+    typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type
+>::type
+__mu(_Ti&, _Uj& __uj)
+{
+    const size_t _Indx = is_placeholder<_Ti>::value - 1;
+    return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj));
+}
+
+template <class _Ti, class _Uj>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_bind_expression<_Ti>::value &&
+    is_placeholder<_Ti>::value == 0 &&
+    !__is_reference_wrapper<_Ti>::value,
+    _Ti&
+>::type
+__mu(_Ti& __ti, _Uj&)
+{
+    return __ti;
+}
+
+template <class _Ti, bool IsReferenceWrapper, bool IsBindEx, bool IsPh,
+          class _TupleUj>
+struct __mu_return_impl;
+
+template <bool _Invokable, class _Ti, class ..._Uj>
+struct __mu_return_invokable  // false
+{
+    typedef __nat type;
+};
+
+template <class _Ti, class ..._Uj>
+struct __mu_return_invokable<true, _Ti, _Uj...>
+{
+    typedef typename __invoke_of<_Ti&, _Uj...>::type type;
+};
+
+template <class _Ti, class ..._Uj>
+struct __mu_return_impl<_Ti, false, true, false, tuple<_Uj...> >
+    : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...>
+{
+};
+
+template <class _Ti, class _TupleUj>
+struct __mu_return_impl<_Ti, false, false, true, _TupleUj>
+{
+    typedef typename tuple_element<is_placeholder<_Ti>::value - 1,
+                                   _TupleUj>::type&& type;
+};
+
+template <class _Ti, class _TupleUj>
+struct __mu_return_impl<_Ti, true, false, false, _TupleUj>
+{
+    typedef typename _Ti::type& type;
+};
+
+template <class _Ti, class _TupleUj>
+struct __mu_return_impl<_Ti, false, false, false, _TupleUj>
+{
+    typedef _Ti& type;
+};
+
+template <class _Ti, class _TupleUj>
+struct __mu_return
+    : public __mu_return_impl<_Ti,
+                              __is_reference_wrapper<_Ti>::value,
+                              is_bind_expression<_Ti>::value,
+                              0 < is_placeholder<_Ti>::value &&
+                              is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value,
+                              _TupleUj>
+{
+};
+
+template <class _Fp, class _BoundArgs, class _TupleUj>
+struct __is_valid_bind_return
+{
+    static const bool value = false;
+};
+
+template <class _Fp, class ..._BoundArgs, class _TupleUj>
+struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>
+{
+    static const bool value = __invokable<_Fp,
+                    typename __mu_return<_BoundArgs, _TupleUj>::type...>::value;
+};
+
+template <class _Fp, class ..._BoundArgs, class _TupleUj>
+struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj>
+{
+    static const bool value = __invokable<_Fp,
+                    typename __mu_return<const _BoundArgs, _TupleUj>::type...>::value;
+};
+
+template <class _Fp, class _BoundArgs, class _TupleUj,
+          bool = __is_valid_bind_return<_Fp, _BoundArgs, _TupleUj>::value>
+struct __bind_return;
+
+template <class _Fp, class ..._BoundArgs, class _TupleUj>
+struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true>
+{
+    typedef typename __invoke_of
+    <
+        _Fp&,
+        typename __mu_return
+        <
+            _BoundArgs,
+            _TupleUj
+        >::type...
+    >::type type;
+};
+
+template <class _Fp, class ..._BoundArgs, class _TupleUj>
+struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true>
+{
+    typedef typename __invoke_of
+    <
+        _Fp&,
+        typename __mu_return
+        <
+            const _BoundArgs,
+            _TupleUj
+        >::type...
+    >::type type;
+};
+
+template <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __bind_return<_Fp, _BoundArgs, _Args>::type
+__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
+                _Args&& __args)
+{
+    return _VSTD::__invoke(__f, _VSTD::__mu(_VSTD::get<_Indx>(__bound_args), __args)...);
+}
+
+template<class _Fp, class ..._BoundArgs>
+class __bind
+#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public __weak_result_type<typename decay<_Fp>::type>
+#endif
+{
+protected:
+    typedef typename decay<_Fp>::type _Fd;
+    typedef tuple<typename decay<_BoundArgs>::type...> _Td;
+private:
+    _Fd __f_;
+    _Td __bound_args_;
+
+    typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices;
+public:
+    template <class _Gp, class ..._BA,
+              class = typename enable_if
+                               <
+                                  is_constructible<_Fd, _Gp>::value &&
+                                  !is_same<typename remove_reference<_Gp>::type,
+                                           __bind>::value
+                               >::type>
+      _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+      explicit __bind(_Gp&& __f, _BA&& ...__bound_args)
+        : __f_(_VSTD::forward<_Gp>(__f)),
+          __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {}
+
+    template <class ..._Args>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+        typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type
+        operator()(_Args&& ...__args)
+        {
+            return _VSTD::__apply_functor(__f_, __bound_args_, __indices(),
+                                  tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
+        }
+
+    template <class ..._Args>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+        typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type
+        operator()(_Args&& ...__args) const
+        {
+            return _VSTD::__apply_functor(__f_, __bound_args_, __indices(),
+                                   tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
+        }
+};
+
+template<class _Fp, class ..._BoundArgs>
+struct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {};
+
+template<class _Rp, class _Fp, class ..._BoundArgs>
+class __bind_r
+    : public __bind<_Fp, _BoundArgs...>
+{
+    typedef __bind<_Fp, _BoundArgs...> base;
+    typedef typename base::_Fd _Fd;
+    typedef typename base::_Td _Td;
+public:
+    typedef _Rp result_type;
+
+
+    template <class _Gp, class ..._BA,
+              class = typename enable_if
+                               <
+                                  is_constructible<_Fd, _Gp>::value &&
+                                  !is_same<typename remove_reference<_Gp>::type,
+                                           __bind_r>::value
+                               >::type>
+      _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+      explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args)
+        : base(_VSTD::forward<_Gp>(__f),
+               _VSTD::forward<_BA>(__bound_args)...) {}
+
+    template <class ..._Args>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+        typename enable_if
+        <
+            is_convertible<typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type,
+                           result_type>::value || is_void<_Rp>::value,
+            result_type
+        >::type
+        operator()(_Args&& ...__args)
+        {
+            typedef __invoke_void_return_wrapper<_Rp> _Invoker;
+            return _Invoker::__call(static_cast<base&>(*this), _VSTD::forward<_Args>(__args)...);
+        }
+
+    template <class ..._Args>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+        typename enable_if
+        <
+            is_convertible<typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type,
+                           result_type>::value || is_void<_Rp>::value,
+            result_type
+        >::type
+        operator()(_Args&& ...__args) const
+        {
+            typedef __invoke_void_return_wrapper<_Rp> _Invoker;
+            return _Invoker::__call(static_cast<base const&>(*this), _VSTD::forward<_Args>(__args)...);
+        }
+};
+
+template<class _Rp, class _Fp, class ..._BoundArgs>
+struct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};
+
+template<class _Fp, class ..._BoundArgs>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+__bind<_Fp, _BoundArgs...>
+bind(_Fp&& __f, _BoundArgs&&... __bound_args)
+{
+    typedef __bind<_Fp, _BoundArgs...> type;
+    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
+}
+
+template<class _Rp, class _Fp, class ..._BoundArgs>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+__bind_r<_Rp, _Fp, _BoundArgs...>
+bind(_Fp&& __f, _BoundArgs&&... __bound_args)
+{
+    typedef __bind_r<_Rp, _Fp, _BoundArgs...> type;
+    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
+}
+
+#endif // _LIBCPP_CXX03_LANG
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_BIND_H
diff --git a/include/__functional/bind_front.h b/include/__functional/bind_front.h
new file mode 100644
index 0000000..8690499
--- /dev/null
+++ b/include/__functional/bind_front.h
@@ -0,0 +1,52 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_BIND_FRONT_H
+#define _LIBCPP___FUNCTIONAL_BIND_FRONT_H
+
+#include <__config>
+#include <__functional/perfect_forward.h>
+#include <__functional/invoke.h>
+#include <type_traits>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+struct __bind_front_op
+{
+    template<class... _Args>
+    constexpr static auto __call(_Args&&... __args)
+    noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Args>(__args)...)))
+    -> decltype(      _VSTD::invoke(_VSTD::forward<_Args>(__args)...))
+    { return          _VSTD::invoke(_VSTD::forward<_Args>(__args)...); }
+};
+
+template<class _Fn, class... _Args,
+         class = _EnableIf<conjunction<is_constructible<decay_t<_Fn>, _Fn>,
+                                       is_move_constructible<decay_t<_Fn>>,
+                                       is_constructible<decay_t<_Args>, _Args>...,
+                                       is_move_constructible<decay_t<_Args>>...
+                                       >::value>>
+constexpr auto bind_front(_Fn&& __f, _Args&&... __args)
+{
+    return __perfect_forward<__bind_front_op, _Fn, _Args...>(_VSTD::forward<_Fn>(__f),
+                                                             _VSTD::forward<_Args>(__args)...);
+}
+
+#endif // _LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_BIND_FRONT_H
diff --git a/include/__functional/binder1st.h b/include/__functional/binder1st.h
new file mode 100644
index 0000000..5dd8f5c
--- /dev/null
+++ b/include/__functional/binder1st.h
@@ -0,0 +1,54 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_BINDER1ST_H
+#define _LIBCPP___FUNCTIONAL_BINDER1ST_H
+
+#include <__config>
+#include <__functional/unary_function.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
+
+template <class __Operation>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st
+    : public unary_function<typename __Operation::second_argument_type,
+                            typename __Operation::result_type>
+{
+protected:
+    __Operation                               op;
+    typename __Operation::first_argument_type value;
+public:
+    _LIBCPP_INLINE_VISIBILITY binder1st(const __Operation& __x,
+                               const typename __Operation::first_argument_type __y)
+        : op(__x), value(__y) {}
+    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
+        (typename __Operation::second_argument_type& __x) const
+            {return op(value, __x);}
+    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
+        (const typename __Operation::second_argument_type& __x) const
+            {return op(value, __x);}
+};
+
+template <class __Operation, class _Tp>
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
+binder1st<__Operation>
+bind1st(const __Operation& __op, const _Tp& __x)
+    {return binder1st<__Operation>(__op, __x);}
+
+#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_BINDER1ST_H
diff --git a/include/__functional/binder2nd.h b/include/__functional/binder2nd.h
new file mode 100644
index 0000000..3ed5f5b
--- /dev/null
+++ b/include/__functional/binder2nd.h
@@ -0,0 +1,54 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_BINDER2ND_H
+#define _LIBCPP___FUNCTIONAL_BINDER2ND_H
+
+#include <__config>
+#include <__functional/unary_function.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
+
+template <class __Operation>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd
+    : public unary_function<typename __Operation::first_argument_type,
+                            typename __Operation::result_type>
+{
+protected:
+    __Operation                                op;
+    typename __Operation::second_argument_type value;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    binder2nd(const __Operation& __x, const typename __Operation::second_argument_type __y)
+        : op(__x), value(__y) {}
+    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
+        (      typename __Operation::first_argument_type& __x) const
+            {return op(__x, value);}
+    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
+        (const typename __Operation::first_argument_type& __x) const
+            {return op(__x, value);}
+};
+
+template <class __Operation, class _Tp>
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
+binder2nd<__Operation>
+bind2nd(const __Operation& __op, const _Tp& __x)
+    {return binder2nd<__Operation>(__op, __x);}
+
+#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_BINDER2ND_H
diff --git a/include/__functional/default_searcher.h b/include/__functional/default_searcher.h
new file mode 100644
index 0000000..1acbc18
--- /dev/null
+++ b/include/__functional/default_searcher.h
@@ -0,0 +1,56 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H
+#define _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H
+
+#include <__algorithm/search.h>
+#include <__config>
+#include <__functional/operations.h>
+#include <__iterator/iterator_traits.h>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+// default searcher
+template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
+class _LIBCPP_TEMPLATE_VIS default_searcher {
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    default_searcher(_ForwardIterator __f, _ForwardIterator __l,
+                       _BinaryPredicate __p = _BinaryPredicate())
+        : __first_(__f), __last_(__l), __pred_(__p) {}
+
+    template <typename _ForwardIterator2>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    pair<_ForwardIterator2, _ForwardIterator2>
+    operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const
+    {
+        return _VSTD::__search(__f, __l, __first_, __last_, __pred_,
+            typename iterator_traits<_ForwardIterator>::iterator_category(),
+            typename iterator_traits<_ForwardIterator2>::iterator_category());
+    }
+
+private:
+    _ForwardIterator __first_;
+    _ForwardIterator __last_;
+    _BinaryPredicate __pred_;
+    };
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H
diff --git a/include/__functional/function.h b/include/__functional/function.h
new file mode 100644
index 0000000..ba629e1
--- /dev/null
+++ b/include/__functional/function.h
@@ -0,0 +1,2809 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H
+#define _LIBCPP___FUNCTIONAL_FUNCTION_H
+
+#include <__config>
+#include <__functional/binary_function.h>
+#include <__functional/invoke.h>
+#include <__functional/unary_function.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/allocator_traits.h>
+#include <__memory/compressed_pair.h>
+#include <__memory/shared_ptr.h>
+#include <exception>
+#include <memory> // TODO: replace with <__memory/__builtin_new_allocator.h>
+#include <type_traits>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// bad_function_call
+
+class _LIBCPP_EXCEPTION_ABI bad_function_call
+    : public exception
+{
+#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
+public:
+    virtual ~bad_function_call() _NOEXCEPT;
+
+    virtual const char* what() const _NOEXCEPT;
+#endif
+};
+
+_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
+void __throw_bad_function_call()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    throw bad_function_call();
+#else
+    _VSTD::abort();
+#endif
+}
+
+#if defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && __has_attribute(deprecated)
+#   define _LIBCPP_DEPRECATED_CXX03_FUNCTION \
+        __attribute__((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type")))
+#else
+#   define _LIBCPP_DEPRECATED_CXX03_FUNCTION /* nothing */
+#endif
+
+template<class _Fp> class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function; // undefined
+
+namespace __function
+{
+
+template<class _Rp>
+struct __maybe_derive_from_unary_function
+{
+};
+
+template<class _Rp, class _A1>
+struct __maybe_derive_from_unary_function<_Rp(_A1)>
+    : public unary_function<_A1, _Rp>
+{
+};
+
+template<class _Rp>
+struct __maybe_derive_from_binary_function
+{
+};
+
+template<class _Rp, class _A1, class _A2>
+struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
+    : public binary_function<_A1, _A2, _Rp>
+{
+};
+
+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; }
+
+#ifdef _LIBCPP_HAS_EXTENSION_BLOCKS
+template <class _Rp, class ..._Args>
+_LIBCPP_INLINE_VISIBILITY
+bool __not_null(_Rp (^__p)(_Args...)) { return __p; }
+#endif
+
+} // namespace __function
+
+#ifndef _LIBCPP_CXX03_LANG
+
+namespace __function {
+
+// __alloc_func holds a functor and an allocator.
+
+template <class _Fp, class _Ap, class _FB> class __alloc_func;
+template <class _Fp, class _FB>
+class __default_alloc_func;
+
+template <class _Fp, class _Ap, class _Rp, class... _ArgTypes>
+class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
+{
+    __compressed_pair<_Fp, _Ap> __f_;
+
+  public:
+    typedef _LIBCPP_NODEBUG_TYPE _Fp _Target;
+    typedef _LIBCPP_NODEBUG_TYPE _Ap _Alloc;
+
+    _LIBCPP_INLINE_VISIBILITY
+    const _Target& __target() const { return __f_.first(); }
+
+    // WIN32 APIs may define __allocator, so use __get_allocator instead.
+    _LIBCPP_INLINE_VISIBILITY
+    const _Alloc& __get_allocator() const { return __f_.second(); }
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __alloc_func(_Target&& __f)
+        : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
+               _VSTD::forward_as_tuple())
+    {
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __alloc_func(const _Target& __f, const _Alloc& __a)
+        : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
+               _VSTD::forward_as_tuple(__a))
+    {
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __alloc_func(const _Target& __f, _Alloc&& __a)
+        : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
+               _VSTD::forward_as_tuple(_VSTD::move(__a)))
+    {
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __alloc_func(_Target&& __f, _Alloc&& __a)
+        : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
+               _VSTD::forward_as_tuple(_VSTD::move(__a)))
+    {
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    _Rp operator()(_ArgTypes&&... __arg)
+    {
+        typedef __invoke_void_return_wrapper<_Rp> _Invoker;
+        return _Invoker::__call(__f_.first(),
+                                _VSTD::forward<_ArgTypes>(__arg)...);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __alloc_func* __clone() const
+    {
+        typedef allocator_traits<_Alloc> __alloc_traits;
+        typedef
+            typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type
+                _AA;
+        _AA __a(__f_.second());
+        typedef __allocator_destructor<_AA> _Dp;
+        unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+        ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a));
+        return __hold.release();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
+
+    static void __destroy_and_delete(__alloc_func* __f) {
+      typedef allocator_traits<_Alloc> __alloc_traits;
+      typedef typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type
+          _FunAlloc;
+      _FunAlloc __a(__f->__get_allocator());
+      __f->destroy();
+      __a.deallocate(__f, 1);
+    }
+};
+
+template <class _Fp, class _Rp, class... _ArgTypes>
+class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> {
+  _Fp __f_;
+
+public:
+  typedef _LIBCPP_NODEBUG_TYPE _Fp _Target;
+
+  _LIBCPP_INLINE_VISIBILITY
+  const _Target& __target() const { return __f_; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  explicit __default_alloc_func(_Target&& __f) : __f_(_VSTD::move(__f)) {}
+
+  _LIBCPP_INLINE_VISIBILITY
+  explicit __default_alloc_func(const _Target& __f) : __f_(__f) {}
+
+  _LIBCPP_INLINE_VISIBILITY
+  _Rp operator()(_ArgTypes&&... __arg) {
+    typedef __invoke_void_return_wrapper<_Rp> _Invoker;
+    return _Invoker::__call(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  __default_alloc_func* __clone() const {
+      __builtin_new_allocator::__holder_t __hold =
+        __builtin_new_allocator::__allocate_type<__default_alloc_func>(1);
+    __default_alloc_func* __res =
+        ::new ((void*)__hold.get()) __default_alloc_func(__f_);
+    (void)__hold.release();
+    return __res;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void destroy() _NOEXCEPT { __f_.~_Target(); }
+
+  static void __destroy_and_delete(__default_alloc_func* __f) {
+    __f->destroy();
+      __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1);
+  }
+};
+
+// __base provides an abstract interface for copyable functors.
+
+template<class _Fp> class _LIBCPP_TEMPLATE_VIS __base;
+
+template<class _Rp, class ..._ArgTypes>
+class __base<_Rp(_ArgTypes...)>
+{
+    __base(const __base&);
+    __base& operator=(const __base&);
+public:
+    _LIBCPP_INLINE_VISIBILITY __base() {}
+    _LIBCPP_INLINE_VISIBILITY virtual ~__base() {}
+    virtual __base* __clone() const = 0;
+    virtual void __clone(__base*) const = 0;
+    virtual void destroy() _NOEXCEPT = 0;
+    virtual void destroy_deallocate() _NOEXCEPT = 0;
+    virtual _Rp operator()(_ArgTypes&& ...) = 0;
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const _NOEXCEPT = 0;
+    virtual const std::type_info& target_type() const _NOEXCEPT = 0;
+#endif // _LIBCPP_NO_RTTI
+};
+
+// __func implements __base for a given functor type.
+
+template<class _FD, class _Alloc, class _FB> class __func;
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+class __func<_Fp, _Alloc, _Rp(_ArgTypes...)>
+    : public  __base<_Rp(_ArgTypes...)>
+{
+    __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __func(_Fp&& __f)
+        : __f_(_VSTD::move(__f)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __func(const _Fp& __f, const _Alloc& __a)
+        : __f_(__f, __a) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __func(const _Fp& __f, _Alloc&& __a)
+        : __f_(__f, _VSTD::move(__a)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __func(_Fp&& __f, _Alloc&& __a)
+        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
+
+    virtual __base<_Rp(_ArgTypes...)>* __clone() const;
+    virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
+    virtual void destroy() _NOEXCEPT;
+    virtual void destroy_deallocate() _NOEXCEPT;
+    virtual _Rp operator()(_ArgTypes&&... __arg);
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const _NOEXCEPT;
+    virtual const std::type_info& target_type() const _NOEXCEPT;
+#endif // _LIBCPP_NO_RTTI
+};
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+__base<_Rp(_ArgTypes...)>*
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    _Ap __a(__f_.__get_allocator());
+    typedef __allocator_destructor<_Ap> _Dp;
+    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+    ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a));
+    return __hold.release();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+void
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const
+{
+    ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator());
+}
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+void
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT
+{
+    __f_.destroy();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+void
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    _Ap __a(__f_.__get_allocator());
+    __f_.destroy();
+    __a.deallocate(this, 1);
+}
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+_Rp
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
+{
+    return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+const void*
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
+{
+    if (__ti == typeid(_Fp))
+        return &__f_.__target();
+    return nullptr;
+}
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+const std::type_info&
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
+{
+    return typeid(_Fp);
+}
+
+#endif // _LIBCPP_NO_RTTI
+
+// __value_func creates a value-type from a __func.
+
+template <class _Fp> class __value_func;
+
+template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
+{
+    typename aligned_storage<3 * sizeof(void*)>::type __buf_;
+
+    typedef __base<_Rp(_ArgTypes...)> __func;
+    __func* __f_;
+
+    _LIBCPP_NO_CFI static __func* __as_base(void* p)
+    {
+        return reinterpret_cast<__func*>(p);
+    }
+
+  public:
+    _LIBCPP_INLINE_VISIBILITY
+    __value_func() _NOEXCEPT : __f_(nullptr) {}
+
+    template <class _Fp, class _Alloc>
+    _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc& __a)
+        : __f_(nullptr)
+    {
+        typedef allocator_traits<_Alloc> __alloc_traits;
+        typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
+        typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
+            _FunAlloc;
+
+        if (__function::__not_null(__f))
+        {
+            _FunAlloc __af(__a);
+            if (sizeof(_Fun) <= sizeof(__buf_) &&
+                is_nothrow_copy_constructible<_Fp>::value &&
+                is_nothrow_copy_constructible<_FunAlloc>::value)
+            {
+                __f_ =
+                    ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af));
+            }
+            else
+            {
+                typedef __allocator_destructor<_FunAlloc> _Dp;
+                unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
+                ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a));
+                __f_ = __hold.release();
+            }
+        }
+    }
+
+    template <class _Fp,
+        class = typename enable_if<!is_same<typename decay<_Fp>::type, __value_func>::value>::type>
+    _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f)
+        : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_func(const __value_func& __f)
+    {
+        if (__f.__f_ == nullptr)
+            __f_ = nullptr;
+        else if ((void*)__f.__f_ == &__f.__buf_)
+        {
+            __f_ = __as_base(&__buf_);
+            __f.__f_->__clone(__f_);
+        }
+        else
+            __f_ = __f.__f_->__clone();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_func(__value_func&& __f) _NOEXCEPT
+    {
+        if (__f.__f_ == nullptr)
+            __f_ = nullptr;
+        else if ((void*)__f.__f_ == &__f.__buf_)
+        {
+            __f_ = __as_base(&__buf_);
+            __f.__f_->__clone(__f_);
+        }
+        else
+        {
+            __f_ = __f.__f_;
+            __f.__f_ = nullptr;
+        }
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__value_func()
+    {
+        if ((void*)__f_ == &__buf_)
+            __f_->destroy();
+        else if (__f_)
+            __f_->destroy_deallocate();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_func& operator=(__value_func&& __f)
+    {
+        *this = nullptr;
+        if (__f.__f_ == nullptr)
+            __f_ = nullptr;
+        else if ((void*)__f.__f_ == &__f.__buf_)
+        {
+            __f_ = __as_base(&__buf_);
+            __f.__f_->__clone(__f_);
+        }
+        else
+        {
+            __f_ = __f.__f_;
+            __f.__f_ = nullptr;
+        }
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_func& operator=(nullptr_t)
+    {
+        __func* __f = __f_;
+        __f_ = nullptr;
+        if ((void*)__f == &__buf_)
+            __f->destroy();
+        else if (__f)
+            __f->destroy_deallocate();
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    _Rp operator()(_ArgTypes&&... __args) const
+    {
+        if (__f_ == nullptr)
+            __throw_bad_function_call();
+        return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(__value_func& __f) _NOEXCEPT
+    {
+        if (&__f == this)
+            return;
+        if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_)
+        {
+            typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+            __func* __t = __as_base(&__tempbuf);
+            __f_->__clone(__t);
+            __f_->destroy();
+            __f_ = nullptr;
+            __f.__f_->__clone(__as_base(&__buf_));
+            __f.__f_->destroy();
+            __f.__f_ = nullptr;
+            __f_ = __as_base(&__buf_);
+            __t->__clone(__as_base(&__f.__buf_));
+            __t->destroy();
+            __f.__f_ = __as_base(&__f.__buf_);
+        }
+        else if ((void*)__f_ == &__buf_)
+        {
+            __f_->__clone(__as_base(&__f.__buf_));
+            __f_->destroy();
+            __f_ = __f.__f_;
+            __f.__f_ = __as_base(&__f.__buf_);
+        }
+        else if ((void*)__f.__f_ == &__f.__buf_)
+        {
+            __f.__f_->__clone(__as_base(&__buf_));
+            __f.__f_->destroy();
+            __f.__f_ = __f_;
+            __f_ = __as_base(&__buf_);
+        }
+        else
+            _VSTD::swap(__f_, __f.__f_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; }
+
+#ifndef _LIBCPP_NO_RTTI
+    _LIBCPP_INLINE_VISIBILITY
+    const std::type_info& target_type() const _NOEXCEPT
+    {
+        if (__f_ == nullptr)
+            return typeid(void);
+        return __f_->target_type();
+    }
+
+    template <typename _Tp>
+    _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
+    {
+        if (__f_ == nullptr)
+            return nullptr;
+        return (const _Tp*)__f_->target(typeid(_Tp));
+    }
+#endif // _LIBCPP_NO_RTTI
+};
+
+// Storage for a functor object, to be used with __policy to manage copy and
+// destruction.
+union __policy_storage
+{
+    mutable char __small[sizeof(void*) * 2];
+    void* __large;
+};
+
+// True if _Fun can safely be held in __policy_storage.__small.
+template <typename _Fun>
+struct __use_small_storage
+    : public integral_constant<
+          bool, sizeof(_Fun) <= sizeof(__policy_storage) &&
+                    _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
+                    is_trivially_copy_constructible<_Fun>::value &&
+                    is_trivially_destructible<_Fun>::value> {};
+
+// Policy contains information about how to copy, destroy, and move the
+// underlying functor. You can think of it as a vtable of sorts.
+struct __policy
+{
+    // Used to copy or destroy __large values. null for trivial objects.
+    void* (*const __clone)(const void*);
+    void (*const __destroy)(void*);
+
+    // True if this is the null policy (no value).
+    const bool __is_null;
+
+    // The target type. May be null if RTTI is disabled.
+    const std::type_info* const __type_info;
+
+    // Returns a pointer to a static policy object suitable for the functor
+    // type.
+    template <typename _Fun>
+    _LIBCPP_INLINE_VISIBILITY static const __policy* __create()
+    {
+        return __choose_policy<_Fun>(__use_small_storage<_Fun>());
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    static const __policy* __create_empty()
+    {
+        static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr,
+                                                             true,
+#ifndef _LIBCPP_NO_RTTI
+                                                             &typeid(void)
+#else
+                                                             nullptr
+#endif
+        };
+        return &__policy_;
+    }
+
+  private:
+    template <typename _Fun> static void* __large_clone(const void* __s)
+    {
+        const _Fun* __f = static_cast<const _Fun*>(__s);
+        return __f->__clone();
+    }
+
+    template <typename _Fun>
+    static void __large_destroy(void* __s) {
+      _Fun::__destroy_and_delete(static_cast<_Fun*>(__s));
+    }
+
+    template <typename _Fun>
+    _LIBCPP_INLINE_VISIBILITY static const __policy*
+    __choose_policy(/* is_small = */ false_type) {
+      static const _LIBCPP_CONSTEXPR __policy __policy_ = {
+          &__large_clone<_Fun>, &__large_destroy<_Fun>, false,
+#ifndef _LIBCPP_NO_RTTI
+          &typeid(typename _Fun::_Target)
+#else
+          nullptr
+#endif
+      };
+        return &__policy_;
+    }
+
+    template <typename _Fun>
+    _LIBCPP_INLINE_VISIBILITY static const __policy*
+        __choose_policy(/* is_small = */ true_type)
+    {
+        static const _LIBCPP_CONSTEXPR __policy __policy_ = {
+            nullptr, nullptr, false,
+#ifndef _LIBCPP_NO_RTTI
+            &typeid(typename _Fun::_Target)
+#else
+            nullptr
+#endif
+        };
+        return &__policy_;
+    }
+};
+
+// Used to choose between perfect forwarding or pass-by-value. Pass-by-value is
+// faster for types that can be passed in registers.
+template <typename _Tp>
+using __fast_forward =
+    typename conditional<is_scalar<_Tp>::value, _Tp, _Tp&&>::type;
+
+// __policy_invoker calls an instance of __alloc_func held in __policy_storage.
+
+template <class _Fp> struct __policy_invoker;
+
+template <class _Rp, class... _ArgTypes>
+struct __policy_invoker<_Rp(_ArgTypes...)>
+{
+    typedef _Rp (*__Call)(const __policy_storage*,
+                          __fast_forward<_ArgTypes>...);
+
+    __Call __call_;
+
+    // Creates an invoker that throws bad_function_call.
+    _LIBCPP_INLINE_VISIBILITY
+    __policy_invoker() : __call_(&__call_empty) {}
+
+    // Creates an invoker that calls the given instance of __func.
+    template <typename _Fun>
+    _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create()
+    {
+        return __policy_invoker(&__call_impl<_Fun>);
+    }
+
+  private:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __policy_invoker(__Call __c) : __call_(__c) {}
+
+    static _Rp __call_empty(const __policy_storage*,
+                            __fast_forward<_ArgTypes>...)
+    {
+        __throw_bad_function_call();
+    }
+
+    template <typename _Fun>
+    static _Rp __call_impl(const __policy_storage* __buf,
+                           __fast_forward<_ArgTypes>... __args)
+    {
+        _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value
+                                                ? &__buf->__small
+                                                : __buf->__large);
+        return (*__f)(_VSTD::forward<_ArgTypes>(__args)...);
+    }
+};
+
+// __policy_func uses a __policy and __policy_invoker to create a type-erased,
+// copyable functor.
+
+template <class _Fp> class __policy_func;
+
+template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
+{
+    // Inline storage for small objects.
+    __policy_storage __buf_;
+
+    // Calls the value stored in __buf_. This could technically be part of
+    // policy, but storing it here eliminates a level of indirection inside
+    // operator().
+    typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker;
+    __invoker __invoker_;
+
+    // The policy that describes how to move / copy / destroy __buf_. Never
+    // null, even if the function is empty.
+    const __policy* __policy_;
+
+  public:
+    _LIBCPP_INLINE_VISIBILITY
+    __policy_func() : __policy_(__policy::__create_empty()) {}
+
+    template <class _Fp, class _Alloc>
+    _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a)
+        : __policy_(__policy::__create_empty())
+    {
+        typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
+        typedef allocator_traits<_Alloc> __alloc_traits;
+        typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
+            _FunAlloc;
+
+        if (__function::__not_null(__f))
+        {
+            __invoker_ = __invoker::template __create<_Fun>();
+            __policy_ = __policy::__create<_Fun>();
+
+            _FunAlloc __af(__a);
+            if (__use_small_storage<_Fun>())
+            {
+                ::new ((void*)&__buf_.__small)
+                    _Fun(_VSTD::move(__f), _Alloc(__af));
+            }
+            else
+            {
+                typedef __allocator_destructor<_FunAlloc> _Dp;
+                unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
+                ::new ((void*)__hold.get())
+                    _Fun(_VSTD::move(__f), _Alloc(__af));
+                __buf_.__large = __hold.release();
+            }
+        }
+    }
+
+    template <class _Fp, class = typename enable_if<!is_same<typename decay<_Fp>::type, __policy_func>::value>::type>
+    _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f)
+        : __policy_(__policy::__create_empty()) {
+      typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun;
+
+      if (__function::__not_null(__f)) {
+        __invoker_ = __invoker::template __create<_Fun>();
+        __policy_ = __policy::__create<_Fun>();
+        if (__use_small_storage<_Fun>()) {
+          ::new ((void*)&__buf_.__small) _Fun(_VSTD::move(__f));
+        } else {
+          __builtin_new_allocator::__holder_t __hold =
+              __builtin_new_allocator::__allocate_type<_Fun>(1);
+          __buf_.__large = ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f));
+          (void)__hold.release();
+        }
+      }
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __policy_func(const __policy_func& __f)
+        : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
+          __policy_(__f.__policy_)
+    {
+        if (__policy_->__clone)
+            __buf_.__large = __policy_->__clone(__f.__buf_.__large);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __policy_func(__policy_func&& __f)
+        : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
+          __policy_(__f.__policy_)
+    {
+        if (__policy_->__destroy)
+        {
+            __f.__policy_ = __policy::__create_empty();
+            __f.__invoker_ = __invoker();
+        }
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__policy_func()
+    {
+        if (__policy_->__destroy)
+            __policy_->__destroy(__buf_.__large);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __policy_func& operator=(__policy_func&& __f)
+    {
+        *this = nullptr;
+        __buf_ = __f.__buf_;
+        __invoker_ = __f.__invoker_;
+        __policy_ = __f.__policy_;
+        __f.__policy_ = __policy::__create_empty();
+        __f.__invoker_ = __invoker();
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __policy_func& operator=(nullptr_t)
+    {
+        const __policy* __p = __policy_;
+        __policy_ = __policy::__create_empty();
+        __invoker_ = __invoker();
+        if (__p->__destroy)
+            __p->__destroy(__buf_.__large);
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    _Rp operator()(_ArgTypes&&... __args) const
+    {
+        return __invoker_.__call_(_VSTD::addressof(__buf_),
+                                  _VSTD::forward<_ArgTypes>(__args)...);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(__policy_func& __f)
+    {
+        _VSTD::swap(__invoker_, __f.__invoker_);
+        _VSTD::swap(__policy_, __f.__policy_);
+        _VSTD::swap(__buf_, __f.__buf_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit operator bool() const _NOEXCEPT
+    {
+        return !__policy_->__is_null;
+    }
+
+#ifndef _LIBCPP_NO_RTTI
+    _LIBCPP_INLINE_VISIBILITY
+    const std::type_info& target_type() const _NOEXCEPT
+    {
+        return *__policy_->__type_info;
+    }
+
+    template <typename _Tp>
+    _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
+    {
+        if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info)
+            return nullptr;
+        if (__policy_->__clone) // Out of line storage.
+            return reinterpret_cast<const _Tp*>(__buf_.__large);
+        else
+            return reinterpret_cast<const _Tp*>(&__buf_.__small);
+    }
+#endif // _LIBCPP_NO_RTTI
+};
+
+#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC)
+
+extern "C" void *_Block_copy(const void *);
+extern "C" void _Block_release(const void *);
+
+template<class _Rp1, class ..._ArgTypes1, class _Alloc, class _Rp, class ..._ArgTypes>
+class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)>
+    : public  __base<_Rp(_ArgTypes...)>
+{
+    typedef _Rp1(^__block_type)(_ArgTypes1...);
+    __block_type __f_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __func(__block_type const& __f)
+        : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
+    { }
+
+    // [TODO] add && to save on a retain
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __func(__block_type __f, const _Alloc& /* unused */)
+        : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
+    { }
+
+    virtual __base<_Rp(_ArgTypes...)>* __clone() const {
+        _LIBCPP_ASSERT(false,
+            "Block pointers are just pointers, so they should always fit into "
+            "std::function's small buffer optimization. This function should "
+            "never be invoked.");
+        return nullptr;
+    }
+
+    virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const {
+        ::new ((void*)__p) __func(__f_);
+    }
+
+    virtual void destroy() _NOEXCEPT {
+        if (__f_)
+            _Block_release(__f_);
+        __f_ = 0;
+    }
+
+    virtual void destroy_deallocate() _NOEXCEPT {
+        _LIBCPP_ASSERT(false,
+            "Block pointers are just pointers, so they should always fit into "
+            "std::function's small buffer optimization. This function should "
+            "never be invoked.");
+    }
+
+    virtual _Rp operator()(_ArgTypes&& ... __arg) {
+        return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
+    }
+
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(type_info const& __ti) const _NOEXCEPT {
+        if (__ti == typeid(__func::__block_type))
+            return &__f_;
+        return (const void*)nullptr;
+    }
+
+    virtual const std::type_info& target_type() const _NOEXCEPT {
+        return typeid(__func::__block_type);
+    }
+#endif // _LIBCPP_NO_RTTI
+};
+
+#endif // _LIBCPP_HAS_EXTENSION_BLOCKS && !_LIBCPP_HAS_OBJC_ARC
+
+}  // __function
+
+template<class _Rp, class ..._ArgTypes>
+class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
+#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
+      public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
+#endif
+{
+#ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
+    typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
+#else
+    typedef __function::__policy_func<_Rp(_ArgTypes...)> __func;
+#endif
+
+    __func __f_;
+
+    template <class _Fp, bool = _And<
+        _IsNotSame<__uncvref_t<_Fp>, function>,
+        __invokable<_Fp, _ArgTypes...>
+    >::value>
+    struct __callable;
+    template <class _Fp>
+        struct __callable<_Fp, true>
+        {
+            static const bool value = is_void<_Rp>::value ||
+                __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type,
+                                      _Rp>::value;
+        };
+    template <class _Fp>
+        struct __callable<_Fp, false>
+        {
+            static const bool value = false;
+        };
+
+  template <class _Fp>
+  using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type;
+public:
+    typedef _Rp result_type;
+
+    // construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY
+    function() _NOEXCEPT { }
+    _LIBCPP_INLINE_VISIBILITY
+    function(nullptr_t) _NOEXCEPT {}
+    function(const function&);
+    function(function&&) _NOEXCEPT;
+    template<class _Fp, class = _EnableIfLValueCallable<_Fp>>
+    function(_Fp);
+
+#if _LIBCPP_STD_VER <= 14
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
+    template<class _Alloc>
+      function(allocator_arg_t, const _Alloc&, const function&);
+    template<class _Alloc>
+      function(allocator_arg_t, const _Alloc&, function&&);
+    template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
+      function(allocator_arg_t, const _Alloc& __a, _Fp __f);
+#endif
+
+    function& operator=(const function&);
+    function& operator=(function&&) _NOEXCEPT;
+    function& operator=(nullptr_t) _NOEXCEPT;
+    template<class _Fp, class = _EnableIfLValueCallable<typename decay<_Fp>::type>>
+    function& operator=(_Fp&&);
+
+    ~function();
+
+    // 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
+    explicit operator bool() const _NOEXCEPT {
+      return static_cast<bool>(__f_);
+    }
+
+    // deleted overloads close possible hole in the type system
+    template<class _R2, class... _ArgTypes2>
+      bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
+    template<class _R2, class... _ArgTypes2>
+      bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
+public:
+    // function invocation:
+    _Rp operator()(_ArgTypes...) const;
+
+#ifndef _LIBCPP_NO_RTTI
+    // function target access:
+    const std::type_info& target_type() const _NOEXCEPT;
+    template <typename _Tp> _Tp* target() _NOEXCEPT;
+    template <typename _Tp> const _Tp* target() const _NOEXCEPT;
+#endif // _LIBCPP_NO_RTTI
+};
+
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+template<class _Rp, class ..._Ap>
+function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>;
+
+template<class _Fp>
+struct __strip_signature;
+
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile> { using type = _Rp(_Ap...); };
+
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) &> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const &> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile &> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile &> { using type = _Rp(_Ap...); };
+
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) noexcept> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const noexcept> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile noexcept> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile noexcept> { using type = _Rp(_Ap...); };
+
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) & noexcept> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const & noexcept> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); };
+
+template<class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
+function(_Fp) -> function<_Stripped>;
+#endif // !_LIBCPP_HAS_NO_DEDUCTION_GUIDES
+
+template<class _Rp, class ..._ArgTypes>
+function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
+
+#if _LIBCPP_STD_VER <= 14
+template<class _Rp, class ..._ArgTypes>
+template <class _Alloc>
+function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
+                                     const function& __f) : __f_(__f.__f_) {}
+#endif
+
+template <class _Rp, class... _ArgTypes>
+function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT
+    : __f_(_VSTD::move(__f.__f_)) {}
+
+#if _LIBCPP_STD_VER <= 14
+template<class _Rp, class ..._ArgTypes>
+template <class _Alloc>
+function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
+                                      function&& __f)
+    : __f_(_VSTD::move(__f.__f_)) {}
+#endif
+
+template <class _Rp, class... _ArgTypes>
+template <class _Fp, class>
+function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(_VSTD::move(__f)) {}
+
+#if _LIBCPP_STD_VER <= 14
+template <class _Rp, class... _ArgTypes>
+template <class _Fp, class _Alloc, class>
+function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a,
+                                      _Fp __f)
+    : __f_(_VSTD::move(__f), __a) {}
+#endif
+
+template<class _Rp, class ..._ArgTypes>
+function<_Rp(_ArgTypes...)>&
+function<_Rp(_ArgTypes...)>::operator=(const function& __f)
+{
+    function(__f).swap(*this);
+    return *this;
+}
+
+template<class _Rp, class ..._ArgTypes>
+function<_Rp(_ArgTypes...)>&
+function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT
+{
+    __f_ = _VSTD::move(__f.__f_);
+    return *this;
+}
+
+template<class _Rp, class ..._ArgTypes>
+function<_Rp(_ArgTypes...)>&
+function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
+{
+    __f_ = nullptr;
+    return *this;
+}
+
+template<class _Rp, class ..._ArgTypes>
+template <class _Fp, class>
+function<_Rp(_ArgTypes...)>&
+function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
+{
+    function(_VSTD::forward<_Fp>(__f)).swap(*this);
+    return *this;
+}
+
+template<class _Rp, class ..._ArgTypes>
+function<_Rp(_ArgTypes...)>::~function() {}
+
+template<class _Rp, class ..._ArgTypes>
+void
+function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT
+{
+    __f_.swap(__f.__f_);
+}
+
+template<class _Rp, class ..._ArgTypes>
+_Rp
+function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
+{
+    return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Rp, class ..._ArgTypes>
+const std::type_info&
+function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
+{
+    return __f_.target_type();
+}
+
+template<class _Rp, class ..._ArgTypes>
+template <typename _Tp>
+_Tp*
+function<_Rp(_ArgTypes...)>::target() _NOEXCEPT
+{
+    return (_Tp*)(__f_.template target<_Tp>());
+}
+
+template<class _Rp, class ..._ArgTypes>
+template <typename _Tp>
+const _Tp*
+function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
+{
+    return __f_.template target<_Tp>();
+}
+
+#endif // _LIBCPP_NO_RTTI
+
+template <class _Rp, class... _ArgTypes>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;}
+
+template <class _Rp, class... _ArgTypes>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;}
+
+template <class _Rp, class... _ArgTypes>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;}
+
+template <class _Rp, class... _ArgTypes>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;}
+
+template <class _Rp, class... _ArgTypes>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
+{return __x.swap(__y);}
+
+#else // _LIBCPP_CXX03_LANG
+
+namespace __function {
+
+template<class _Fp> class __base;
+
+template<class _Rp>
+class __base<_Rp()>
+{
+    __base(const __base&);
+    __base& operator=(const __base&);
+public:
+    __base() {}
+    virtual ~__base() {}
+    virtual __base* __clone() const = 0;
+    virtual void __clone(__base*) const = 0;
+    virtual void destroy() = 0;
+    virtual void destroy_deallocate() = 0;
+    virtual _Rp operator()() = 0;
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const = 0;
+    virtual const std::type_info& target_type() const = 0;
+#endif // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp, class _A0>
+class __base<_Rp(_A0)>
+{
+    __base(const __base&);
+    __base& operator=(const __base&);
+public:
+    __base() {}
+    virtual ~__base() {}
+    virtual __base* __clone() const = 0;
+    virtual void __clone(__base*) const = 0;
+    virtual void destroy() = 0;
+    virtual void destroy_deallocate() = 0;
+    virtual _Rp operator()(_A0) = 0;
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const = 0;
+    virtual const std::type_info& target_type() const = 0;
+#endif // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp, class _A0, class _A1>
+class __base<_Rp(_A0, _A1)>
+{
+    __base(const __base&);
+    __base& operator=(const __base&);
+public:
+    __base() {}
+    virtual ~__base() {}
+    virtual __base* __clone() const = 0;
+    virtual void __clone(__base*) const = 0;
+    virtual void destroy() = 0;
+    virtual void destroy_deallocate() = 0;
+    virtual _Rp operator()(_A0, _A1) = 0;
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const = 0;
+    virtual const std::type_info& target_type() const = 0;
+#endif // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp, class _A0, class _A1, class _A2>
+class __base<_Rp(_A0, _A1, _A2)>
+{
+    __base(const __base&);
+    __base& operator=(const __base&);
+public:
+    __base() {}
+    virtual ~__base() {}
+    virtual __base* __clone() const = 0;
+    virtual void __clone(__base*) const = 0;
+    virtual void destroy() = 0;
+    virtual void destroy_deallocate() = 0;
+    virtual _Rp operator()(_A0, _A1, _A2) = 0;
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const = 0;
+    virtual const std::type_info& target_type() const = 0;
+#endif // _LIBCPP_NO_RTTI
+};
+
+template<class _FD, class _Alloc, class _FB> class __func;
+
+template<class _Fp, class _Alloc, class _Rp>
+class __func<_Fp, _Alloc, _Rp()>
+    : public  __base<_Rp()>
+{
+    __compressed_pair<_Fp, _Alloc> __f_;
+public:
+    explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
+    explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
+    virtual __base<_Rp()>* __clone() const;
+    virtual void __clone(__base<_Rp()>*) const;
+    virtual void destroy();
+    virtual void destroy_deallocate();
+    virtual _Rp operator()();
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const;
+    virtual const std::type_info& target_type() const;
+#endif // _LIBCPP_NO_RTTI
+};
+
+template<class _Fp, class _Alloc, class _Rp>
+__base<_Rp()>*
+__func<_Fp, _Alloc, _Rp()>::__clone() const
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    _Ap __a(__f_.second());
+    typedef __allocator_destructor<_Ap> _Dp;
+    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+    ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
+    return __hold.release();
+}
+
+template<class _Fp, class _Alloc, class _Rp>
+void
+__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const
+{
+    ::new ((void*)__p) __func(__f_.first(), __f_.second());
+}
+
+template<class _Fp, class _Alloc, class _Rp>
+void
+__func<_Fp, _Alloc, _Rp()>::destroy()
+{
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+}
+
+template<class _Fp, class _Alloc, class _Rp>
+void
+__func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    _Ap __a(__f_.second());
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+    __a.deallocate(this, 1);
+}
+
+template<class _Fp, class _Alloc, class _Rp>
+_Rp
+__func<_Fp, _Alloc, _Rp()>::operator()()
+{
+    typedef __invoke_void_return_wrapper<_Rp> _Invoker;
+    return _Invoker::__call(__f_.first());
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp>
+const void*
+__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
+{
+    if (__ti == typeid(_Fp))
+        return &__f_.first();
+    return (const void*)0;
+}
+
+template<class _Fp, class _Alloc, class _Rp>
+const std::type_info&
+__func<_Fp, _Alloc, _Rp()>::target_type() const
+{
+    return typeid(_Fp);
+}
+
+#endif // _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+class __func<_Fp, _Alloc, _Rp(_A0)>
+    : public  __base<_Rp(_A0)>
+{
+    __compressed_pair<_Fp, _Alloc> __f_;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
+    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
+        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
+    virtual __base<_Rp(_A0)>* __clone() const;
+    virtual void __clone(__base<_Rp(_A0)>*) const;
+    virtual void destroy();
+    virtual void destroy_deallocate();
+    virtual _Rp operator()(_A0);
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const;
+    virtual const std::type_info& target_type() const;
+#endif // _LIBCPP_NO_RTTI
+};
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+__base<_Rp(_A0)>*
+__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    _Ap __a(__f_.second());
+    typedef __allocator_destructor<_Ap> _Dp;
+    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+    ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
+    return __hold.release();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+void
+__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const
+{
+    ::new ((void*)__p) __func(__f_.first(), __f_.second());
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+void
+__func<_Fp, _Alloc, _Rp(_A0)>::destroy()
+{
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+void
+__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    _Ap __a(__f_.second());
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+    __a.deallocate(this, 1);
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+_Rp
+__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0)
+{
+    typedef __invoke_void_return_wrapper<_Rp> _Invoker;
+    return _Invoker::__call(__f_.first(), __a0);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+const void*
+__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const
+{
+    if (__ti == typeid(_Fp))
+        return &__f_.first();
+    return (const void*)0;
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+const std::type_info&
+__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const
+{
+    return typeid(_Fp);
+}
+
+#endif // _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+class __func<_Fp, _Alloc, _Rp(_A0, _A1)>
+    : public  __base<_Rp(_A0, _A1)>
+{
+    __compressed_pair<_Fp, _Alloc> __f_;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
+    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
+        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
+    virtual __base<_Rp(_A0, _A1)>* __clone() const;
+    virtual void __clone(__base<_Rp(_A0, _A1)>*) const;
+    virtual void destroy();
+    virtual void destroy_deallocate();
+    virtual _Rp operator()(_A0, _A1);
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const;
+    virtual const std::type_info& target_type() const;
+#endif // _LIBCPP_NO_RTTI
+};
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+__base<_Rp(_A0, _A1)>*
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    _Ap __a(__f_.second());
+    typedef __allocator_destructor<_Ap> _Dp;
+    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+    ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
+    return __hold.release();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+void
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const
+{
+    ::new ((void*)__p) __func(__f_.first(), __f_.second());
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+void
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy()
+{
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+void
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    _Ap __a(__f_.second());
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+    __a.deallocate(this, 1);
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+_Rp
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)
+{
+    typedef __invoke_void_return_wrapper<_Rp> _Invoker;
+    return _Invoker::__call(__f_.first(), __a0, __a1);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+const void*
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const
+{
+    if (__ti == typeid(_Fp))
+        return &__f_.first();
+    return (const void*)0;
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+const std::type_info&
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const
+{
+    return typeid(_Fp);
+}
+
+#endif // _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>
+    : public  __base<_Rp(_A0, _A1, _A2)>
+{
+    __compressed_pair<_Fp, _Alloc> __f_;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
+    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
+        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
+    virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const;
+    virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const;
+    virtual void destroy();
+    virtual void destroy_deallocate();
+    virtual _Rp operator()(_A0, _A1, _A2);
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const;
+    virtual const std::type_info& target_type() const;
+#endif // _LIBCPP_NO_RTTI
+};
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+__base<_Rp(_A0, _A1, _A2)>*
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    _Ap __a(__f_.second());
+    typedef __allocator_destructor<_Ap> _Dp;
+    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+    ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
+    return __hold.release();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+void
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const
+{
+    ::new ((void*)__p) __func(__f_.first(), __f_.second());
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+void
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy()
+{
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+void
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    _Ap __a(__f_.second());
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+    __a.deallocate(this, 1);
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+_Rp
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2)
+{
+    typedef __invoke_void_return_wrapper<_Rp> _Invoker;
+    return _Invoker::__call(__f_.first(), __a0, __a1, __a2);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+const void*
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const
+{
+    if (__ti == typeid(_Fp))
+        return &__f_.first();
+    return (const void*)0;
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+const std::type_info&
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const
+{
+    return typeid(_Fp);
+}
+
+#endif // _LIBCPP_NO_RTTI
+
+}  // __function
+
+template<class _Rp>
+class _LIBCPP_TEMPLATE_VIS function<_Rp()>
+{
+    typedef __function::__base<_Rp()> __base;
+    aligned_storage<3*sizeof(void*)>::type __buf_;
+    __base* __f_;
+
+public:
+    typedef _Rp result_type;
+
+    // 20.7.16.2.1, construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
+    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
+    function(const function&);
+    template<class _Fp>
+      function(_Fp,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
+    template<class _Alloc>
+      function(allocator_arg_t, const _Alloc&, const function&);
+    template<class _Fp, class _Alloc>
+      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    function& operator=(const function&);
+    function& operator=(nullptr_t);
+    template<class _Fp>
+      typename enable_if
+      <
+        !is_integral<_Fp>::value,
+        function&
+      >::type
+      operator=(_Fp);
+
+    ~function();
+
+    // 20.7.16.2.2, function modifiers:
+    void swap(function&);
+    template<class _Fp, class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      void assign(_Fp __f, const _Alloc& __a)
+        {function(allocator_arg, __a, __f).swap(*this);}
+
+    // 20.7.16.2.3, function capacity:
+    _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;}
+
+private:
+    // deleted overloads close possible hole in the type system
+    template<class _R2>
+      bool operator==(const function<_R2()>&) const;// = delete;
+    template<class _R2>
+      bool operator!=(const function<_R2()>&) const;// = delete;
+public:
+    // 20.7.16.2.4, function invocation:
+    _Rp operator()() const;
+
+#ifndef _LIBCPP_NO_RTTI
+    // 20.7.16.2.5, function target access:
+    const std::type_info& target_type() const;
+    template <typename _Tp> _Tp* target();
+    template <typename _Tp> const _Tp* target() const;
+#endif // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp>
+function<_Rp()>::function(const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp>
+template<class _Alloc>
+function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp>
+template <class _Fp>
+function<_Rp()>::function(_Fp __f,
+                                     typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    if (__function::__not_null(__f))
+    {
+        typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new ((void*)__f_) _FF(__f);
+        }
+        else
+        {
+            typedef allocator<_FF> _Ap;
+            _Ap __a;
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp>
+template <class _Fp, class _Alloc>
+function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
+                                     typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    if (__function::__not_null(__f))
+    {
+        typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new ((void*)__f_) _FF(__f, __a0);
+        }
+        else
+        {
+            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
+            _Ap __a(__a0);
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp>
+function<_Rp()>&
+function<_Rp()>::operator=(const function& __f)
+{
+    if (__f)
+        function(__f).swap(*this);
+    else
+        *this = nullptr;
+    return *this;
+}
+
+template<class _Rp>
+function<_Rp()>&
+function<_Rp()>::operator=(nullptr_t)
+{
+    __base* __t = __f_;
+    __f_ = 0;
+    if (__t == (__base*)&__buf_)
+        __t->destroy();
+    else if (__t)
+        __t->destroy_deallocate();
+    return *this;
+}
+
+template<class _Rp>
+template <class _Fp>
+typename enable_if
+<
+    !is_integral<_Fp>::value,
+    function<_Rp()>&
+>::type
+function<_Rp()>::operator=(_Fp __f)
+{
+    function(_VSTD::move(__f)).swap(*this);
+    return *this;
+}
+
+template<class _Rp>
+function<_Rp()>::~function()
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+}
+
+template<class _Rp>
+void
+function<_Rp()>::swap(function& __f)
+{
+    if (_VSTD::addressof(__f) == this)
+      return;
+    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
+    {
+        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+        __base* __t = (__base*)&__tempbuf;
+        __f_->__clone(__t);
+        __f_->destroy();
+        __f_ = 0;
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = 0;
+        __f_ = (__base*)&__buf_;
+        __t->__clone((__base*)&__f.__buf_);
+        __t->destroy();
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f_ == (__base*)&__buf_)
+    {
+        __f_->__clone((__base*)&__f.__buf_);
+        __f_->destroy();
+        __f_ = __f.__f_;
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = __f_;
+        __f_ = (__base*)&__buf_;
+    }
+    else
+        _VSTD::swap(__f_, __f.__f_);
+}
+
+template<class _Rp>
+_Rp
+function<_Rp()>::operator()() const
+{
+    if (__f_ == 0)
+        __throw_bad_function_call();
+    return (*__f_)();
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Rp>
+const std::type_info&
+function<_Rp()>::target_type() const
+{
+    if (__f_ == 0)
+        return typeid(void);
+    return __f_->target_type();
+}
+
+template<class _Rp>
+template <typename _Tp>
+_Tp*
+function<_Rp()>::target()
+{
+    if (__f_ == 0)
+        return (_Tp*)0;
+    return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
+}
+
+template<class _Rp>
+template <typename _Tp>
+const _Tp*
+function<_Rp()>::target() const
+{
+    if (__f_ == 0)
+        return (const _Tp*)0;
+    return (const _Tp*)__f_->target(typeid(_Tp));
+}
+
+#endif // _LIBCPP_NO_RTTI
+
+template<class _Rp, class _A0>
+class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)>
+    : public unary_function<_A0, _Rp>
+{
+    typedef __function::__base<_Rp(_A0)> __base;
+    aligned_storage<3*sizeof(void*)>::type __buf_;
+    __base* __f_;
+
+public:
+    typedef _Rp result_type;
+
+    // 20.7.16.2.1, construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
+    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
+    function(const function&);
+    template<class _Fp>
+      function(_Fp,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
+    template<class _Alloc>
+      function(allocator_arg_t, const _Alloc&, const function&);
+    template<class _Fp, class _Alloc>
+      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    function& operator=(const function&);
+    function& operator=(nullptr_t);
+    template<class _Fp>
+      typename enable_if
+      <
+        !is_integral<_Fp>::value,
+        function&
+      >::type
+      operator=(_Fp);
+
+    ~function();
+
+    // 20.7.16.2.2, function modifiers:
+    void swap(function&);
+    template<class _Fp, class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      void assign(_Fp __f, const _Alloc& __a)
+        {function(allocator_arg, __a, __f).swap(*this);}
+
+    // 20.7.16.2.3, function capacity:
+    _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;}
+
+private:
+    // deleted overloads close possible hole in the type system
+    template<class _R2, class _B0>
+      bool operator==(const function<_R2(_B0)>&) const;// = delete;
+    template<class _R2, class _B0>
+      bool operator!=(const function<_R2(_B0)>&) const;// = delete;
+public:
+    // 20.7.16.2.4, function invocation:
+    _Rp operator()(_A0) const;
+
+#ifndef _LIBCPP_NO_RTTI
+    // 20.7.16.2.5, function target access:
+    const std::type_info& target_type() const;
+    template <typename _Tp> _Tp* target();
+    template <typename _Tp> const _Tp* target() const;
+#endif // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp, class _A0>
+function<_Rp(_A0)>::function(const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class _A0>
+template<class _Alloc>
+function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class _A0>
+template <class _Fp>
+function<_Rp(_A0)>::function(_Fp __f,
+                                     typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    if (__function::__not_null(__f))
+    {
+        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new ((void*)__f_) _FF(__f);
+        }
+        else
+        {
+            typedef allocator<_FF> _Ap;
+            _Ap __a;
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class _A0>
+template <class _Fp, class _Alloc>
+function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
+                                     typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    if (__function::__not_null(__f))
+    {
+        typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new ((void*)__f_) _FF(__f, __a0);
+        }
+        else
+        {
+            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
+            _Ap __a(__a0);
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class _A0>
+function<_Rp(_A0)>&
+function<_Rp(_A0)>::operator=(const function& __f)
+{
+    if (__f)
+        function(__f).swap(*this);
+    else
+        *this = nullptr;
+    return *this;
+}
+
+template<class _Rp, class _A0>
+function<_Rp(_A0)>&
+function<_Rp(_A0)>::operator=(nullptr_t)
+{
+    __base* __t = __f_;
+    __f_ = 0;
+    if (__t == (__base*)&__buf_)
+        __t->destroy();
+    else if (__t)
+        __t->destroy_deallocate();
+    return *this;
+}
+
+template<class _Rp, class _A0>
+template <class _Fp>
+typename enable_if
+<
+    !is_integral<_Fp>::value,
+    function<_Rp(_A0)>&
+>::type
+function<_Rp(_A0)>::operator=(_Fp __f)
+{
+    function(_VSTD::move(__f)).swap(*this);
+    return *this;
+}
+
+template<class _Rp, class _A0>
+function<_Rp(_A0)>::~function()
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+}
+
+template<class _Rp, class _A0>
+void
+function<_Rp(_A0)>::swap(function& __f)
+{
+    if (_VSTD::addressof(__f) == this)
+      return;
+    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
+    {
+        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+        __base* __t = (__base*)&__tempbuf;
+        __f_->__clone(__t);
+        __f_->destroy();
+        __f_ = 0;
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = 0;
+        __f_ = (__base*)&__buf_;
+        __t->__clone((__base*)&__f.__buf_);
+        __t->destroy();
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f_ == (__base*)&__buf_)
+    {
+        __f_->__clone((__base*)&__f.__buf_);
+        __f_->destroy();
+        __f_ = __f.__f_;
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = __f_;
+        __f_ = (__base*)&__buf_;
+    }
+    else
+        _VSTD::swap(__f_, __f.__f_);
+}
+
+template<class _Rp, class _A0>
+_Rp
+function<_Rp(_A0)>::operator()(_A0 __a0) const
+{
+    if (__f_ == 0)
+        __throw_bad_function_call();
+    return (*__f_)(__a0);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Rp, class _A0>
+const std::type_info&
+function<_Rp(_A0)>::target_type() const
+{
+    if (__f_ == 0)
+        return typeid(void);
+    return __f_->target_type();
+}
+
+template<class _Rp, class _A0>
+template <typename _Tp>
+_Tp*
+function<_Rp(_A0)>::target()
+{
+    if (__f_ == 0)
+        return (_Tp*)0;
+    return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
+}
+
+template<class _Rp, class _A0>
+template <typename _Tp>
+const _Tp*
+function<_Rp(_A0)>::target() const
+{
+    if (__f_ == 0)
+        return (const _Tp*)0;
+    return (const _Tp*)__f_->target(typeid(_Tp));
+}
+
+#endif // _LIBCPP_NO_RTTI
+
+template<class _Rp, class _A0, class _A1>
+class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)>
+    : public binary_function<_A0, _A1, _Rp>
+{
+    typedef __function::__base<_Rp(_A0, _A1)> __base;
+    aligned_storage<3*sizeof(void*)>::type __buf_;
+    __base* __f_;
+
+public:
+    typedef _Rp result_type;
+
+    // 20.7.16.2.1, construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
+    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
+    function(const function&);
+    template<class _Fp>
+      function(_Fp,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
+    template<class _Alloc>
+      function(allocator_arg_t, const _Alloc&, const function&);
+    template<class _Fp, class _Alloc>
+      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    function& operator=(const function&);
+    function& operator=(nullptr_t);
+    template<class _Fp>
+      typename enable_if
+      <
+        !is_integral<_Fp>::value,
+        function&
+      >::type
+      operator=(_Fp);
+
+    ~function();
+
+    // 20.7.16.2.2, function modifiers:
+    void swap(function&);
+    template<class _Fp, class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      void assign(_Fp __f, const _Alloc& __a)
+        {function(allocator_arg, __a, __f).swap(*this);}
+
+    // 20.7.16.2.3, function capacity:
+    _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;}
+
+private:
+    // deleted overloads close possible hole in the type system
+    template<class _R2, class _B0, class _B1>
+      bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete;
+    template<class _R2, class _B0, class _B1>
+      bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete;
+public:
+    // 20.7.16.2.4, function invocation:
+    _Rp operator()(_A0, _A1) const;
+
+#ifndef _LIBCPP_NO_RTTI
+    // 20.7.16.2.5, function target access:
+    const std::type_info& target_type() const;
+    template <typename _Tp> _Tp* target();
+    template <typename _Tp> const _Tp* target() const;
+#endif // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp, class _A0, class _A1>
+function<_Rp(_A0, _A1)>::function(const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class _A0, class _A1>
+template<class _Alloc>
+function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class _A0, class _A1>
+template <class _Fp>
+function<_Rp(_A0, _A1)>::function(_Fp __f,
+                                 typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    if (__function::__not_null(__f))
+    {
+        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new ((void*)__f_) _FF(__f);
+        }
+        else
+        {
+            typedef allocator<_FF> _Ap;
+            _Ap __a;
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class _A0, class _A1>
+template <class _Fp, class _Alloc>
+function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
+                                 typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    if (__function::__not_null(__f))
+    {
+        typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new ((void*)__f_) _FF(__f, __a0);
+        }
+        else
+        {
+            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
+            _Ap __a(__a0);
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class _A0, class _A1>
+function<_Rp(_A0, _A1)>&
+function<_Rp(_A0, _A1)>::operator=(const function& __f)
+{
+    if (__f)
+        function(__f).swap(*this);
+    else
+        *this = nullptr;
+    return *this;
+}
+
+template<class _Rp, class _A0, class _A1>
+function<_Rp(_A0, _A1)>&
+function<_Rp(_A0, _A1)>::operator=(nullptr_t)
+{
+    __base* __t = __f_;
+    __f_ = 0;
+    if (__t == (__base*)&__buf_)
+        __t->destroy();
+    else if (__t)
+        __t->destroy_deallocate();
+    return *this;
+}
+
+template<class _Rp, class _A0, class _A1>
+template <class _Fp>
+typename enable_if
+<
+    !is_integral<_Fp>::value,
+    function<_Rp(_A0, _A1)>&
+>::type
+function<_Rp(_A0, _A1)>::operator=(_Fp __f)
+{
+    function(_VSTD::move(__f)).swap(*this);
+    return *this;
+}
+
+template<class _Rp, class _A0, class _A1>
+function<_Rp(_A0, _A1)>::~function()
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+}
+
+template<class _Rp, class _A0, class _A1>
+void
+function<_Rp(_A0, _A1)>::swap(function& __f)
+{
+    if (_VSTD::addressof(__f) == this)
+      return;
+    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
+    {
+        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+        __base* __t = (__base*)&__tempbuf;
+        __f_->__clone(__t);
+        __f_->destroy();
+        __f_ = 0;
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = 0;
+        __f_ = (__base*)&__buf_;
+        __t->__clone((__base*)&__f.__buf_);
+        __t->destroy();
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f_ == (__base*)&__buf_)
+    {
+        __f_->__clone((__base*)&__f.__buf_);
+        __f_->destroy();
+        __f_ = __f.__f_;
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = __f_;
+        __f_ = (__base*)&__buf_;
+    }
+    else
+        _VSTD::swap(__f_, __f.__f_);
+}
+
+template<class _Rp, class _A0, class _A1>
+_Rp
+function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const
+{
+    if (__f_ == 0)
+        __throw_bad_function_call();
+    return (*__f_)(__a0, __a1);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Rp, class _A0, class _A1>
+const std::type_info&
+function<_Rp(_A0, _A1)>::target_type() const
+{
+    if (__f_ == 0)
+        return typeid(void);
+    return __f_->target_type();
+}
+
+template<class _Rp, class _A0, class _A1>
+template <typename _Tp>
+_Tp*
+function<_Rp(_A0, _A1)>::target()
+{
+    if (__f_ == 0)
+        return (_Tp*)0;
+    return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
+}
+
+template<class _Rp, class _A0, class _A1>
+template <typename _Tp>
+const _Tp*
+function<_Rp(_A0, _A1)>::target() const
+{
+    if (__f_ == 0)
+        return (const _Tp*)0;
+    return (const _Tp*)__f_->target(typeid(_Tp));
+}
+
+#endif // _LIBCPP_NO_RTTI
+
+template<class _Rp, class _A0, class _A1, class _A2>
+class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)>
+{
+    typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
+    aligned_storage<3*sizeof(void*)>::type __buf_;
+    __base* __f_;
+
+public:
+    typedef _Rp result_type;
+
+    // 20.7.16.2.1, construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
+    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
+    function(const function&);
+    template<class _Fp>
+      function(_Fp,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
+    template<class _Alloc>
+      function(allocator_arg_t, const _Alloc&, const function&);
+    template<class _Fp, class _Alloc>
+      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    function& operator=(const function&);
+    function& operator=(nullptr_t);
+    template<class _Fp>
+      typename enable_if
+      <
+        !is_integral<_Fp>::value,
+        function&
+      >::type
+      operator=(_Fp);
+
+    ~function();
+
+    // 20.7.16.2.2, function modifiers:
+    void swap(function&);
+    template<class _Fp, class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      void assign(_Fp __f, const _Alloc& __a)
+        {function(allocator_arg, __a, __f).swap(*this);}
+
+    // 20.7.16.2.3, function capacity:
+    _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;}
+
+private:
+    // deleted overloads close possible hole in the type system
+    template<class _R2, class _B0, class _B1, class _B2>
+      bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
+    template<class _R2, class _B0, class _B1, class _B2>
+      bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
+public:
+    // 20.7.16.2.4, function invocation:
+    _Rp operator()(_A0, _A1, _A2) const;
+
+#ifndef _LIBCPP_NO_RTTI
+    // 20.7.16.2.5, function target access:
+    const std::type_info& target_type() const;
+    template <typename _Tp> _Tp* target();
+    template <typename _Tp> const _Tp* target() const;
+#endif // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp, class _A0, class _A1, class _A2>
+function<_Rp(_A0, _A1, _A2)>::function(const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+template<class _Alloc>
+function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,
+                                      const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+template <class _Fp>
+function<_Rp(_A0, _A1, _A2)>::function(_Fp __f,
+                                     typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    if (__function::__not_null(__f))
+    {
+        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new ((void*)__f_) _FF(__f);
+        }
+        else
+        {
+            typedef allocator<_FF> _Ap;
+            _Ap __a;
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+template <class _Fp, class _Alloc>
+function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
+                                     typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    if (__function::__not_null(__f))
+    {
+        typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new ((void*)__f_) _FF(__f, __a0);
+        }
+        else
+        {
+            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
+            _Ap __a(__a0);
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+function<_Rp(_A0, _A1, _A2)>&
+function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)
+{
+    if (__f)
+        function(__f).swap(*this);
+    else
+        *this = nullptr;
+    return *this;
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+function<_Rp(_A0, _A1, _A2)>&
+function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)
+{
+    __base* __t = __f_;
+    __f_ = 0;
+    if (__t == (__base*)&__buf_)
+        __t->destroy();
+    else if (__t)
+        __t->destroy_deallocate();
+    return *this;
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+template <class _Fp>
+typename enable_if
+<
+    !is_integral<_Fp>::value,
+    function<_Rp(_A0, _A1, _A2)>&
+>::type
+function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f)
+{
+    function(_VSTD::move(__f)).swap(*this);
+    return *this;
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+function<_Rp(_A0, _A1, _A2)>::~function()
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+void
+function<_Rp(_A0, _A1, _A2)>::swap(function& __f)
+{
+    if (_VSTD::addressof(__f) == this)
+      return;
+    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
+    {
+        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+        __base* __t = (__base*)&__tempbuf;
+        __f_->__clone(__t);
+        __f_->destroy();
+        __f_ = 0;
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = 0;
+        __f_ = (__base*)&__buf_;
+        __t->__clone((__base*)&__f.__buf_);
+        __t->destroy();
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f_ == (__base*)&__buf_)
+    {
+        __f_->__clone((__base*)&__f.__buf_);
+        __f_->destroy();
+        __f_ = __f.__f_;
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = __f_;
+        __f_ = (__base*)&__buf_;
+    }
+    else
+        _VSTD::swap(__f_, __f.__f_);
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+_Rp
+function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const
+{
+    if (__f_ == 0)
+        __throw_bad_function_call();
+    return (*__f_)(__a0, __a1, __a2);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Rp, class _A0, class _A1, class _A2>
+const std::type_info&
+function<_Rp(_A0, _A1, _A2)>::target_type() const
+{
+    if (__f_ == 0)
+        return typeid(void);
+    return __f_->target_type();
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+template <typename _Tp>
+_Tp*
+function<_Rp(_A0, _A1, _A2)>::target()
+{
+    if (__f_ == 0)
+        return (_Tp*)0;
+    return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+template <typename _Tp>
+const _Tp*
+function<_Rp(_A0, _A1, _A2)>::target() const
+{
+    if (__f_ == 0)
+        return (const _Tp*)0;
+    return (const _Tp*)__f_->target(typeid(_Tp));
+}
+
+#endif // _LIBCPP_NO_RTTI
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const function<_Fp>& __f, nullptr_t) {return !__f;}
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(nullptr_t, const function<_Fp>& __f) {return !__f;}
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;}
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;}
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(function<_Fp>& __x, function<_Fp>& __y)
+{return __x.swap(__y);}
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_FUNCTION_H
diff --git a/include/__functional/hash.h b/include/__functional/hash.h
new file mode 100644
index 0000000..ebcbbad
--- /dev/null
+++ b/include/__functional/hash.h
@@ -0,0 +1,873 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_HASH_H
+#define _LIBCPP___FUNCTIONAL_HASH_H
+
+#include <__config>
+#include <__functional/unary_function.h>
+#include <__tuple>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
+#include <__utility/swap.h>
+#include <cstdint>
+#include <cstring>
+#include <cstddef>
+#include <limits>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+_Size
+__loadword(const void* __p)
+{
+    _Size __r;
+    _VSTD::memcpy(&__r, __p, sizeof(__r));
+    return __r;
+}
+
+// We use murmur2 when size_t is 32 bits, and cityhash64 when size_t
+// is 64 bits.  This is because cityhash64 uses 64bit x 64bit
+// multiplication, which can be very slow on 32-bit systems.
+template <class _Size, size_t = sizeof(_Size)*__CHAR_BIT__>
+struct __murmur2_or_cityhash;
+
+template <class _Size>
+struct __murmur2_or_cityhash<_Size, 32>
+{
+    inline _Size operator()(const void* __key, _Size __len)
+         _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK;
+};
+
+// murmur2
+template <class _Size>
+_Size
+__murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len)
+{
+    const _Size __m = 0x5bd1e995;
+    const _Size __r = 24;
+    _Size __h = __len;
+    const unsigned char* __data = static_cast<const unsigned char*>(__key);
+    for (; __len >= 4; __data += 4, __len -= 4)
+    {
+        _Size __k = __loadword<_Size>(__data);
+        __k *= __m;
+        __k ^= __k >> __r;
+        __k *= __m;
+        __h *= __m;
+        __h ^= __k;
+    }
+    switch (__len)
+    {
+    case 3:
+        __h ^= static_cast<_Size>(__data[2] << 16);
+        _LIBCPP_FALLTHROUGH();
+    case 2:
+        __h ^= static_cast<_Size>(__data[1] << 8);
+        _LIBCPP_FALLTHROUGH();
+    case 1:
+        __h ^= __data[0];
+        __h *= __m;
+    }
+    __h ^= __h >> 13;
+    __h *= __m;
+    __h ^= __h >> 15;
+    return __h;
+}
+
+template <class _Size>
+struct __murmur2_or_cityhash<_Size, 64>
+{
+    inline _Size operator()(const void* __key, _Size __len)  _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK;
+
+ private:
+  // Some primes between 2^63 and 2^64.
+  static const _Size __k0 = 0xc3a5c85c97cb3127ULL;
+  static const _Size __k1 = 0xb492b66fbe98f273ULL;
+  static const _Size __k2 = 0x9ae16a3b2f90404fULL;
+  static const _Size __k3 = 0xc949d7c7509e6557ULL;
+
+  static _Size __rotate(_Size __val, int __shift) {
+    return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift)));
+  }
+
+  static _Size __rotate_by_at_least_1(_Size __val, int __shift) {
+    return (__val >> __shift) | (__val << (64 - __shift));
+  }
+
+  static _Size __shift_mix(_Size __val) {
+    return __val ^ (__val >> 47);
+  }
+
+  static _Size __hash_len_16(_Size __u, _Size __v)
+     _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+  {
+    const _Size __mul = 0x9ddfea08eb382d69ULL;
+    _Size __a = (__u ^ __v) * __mul;
+    __a ^= (__a >> 47);
+    _Size __b = (__v ^ __a) * __mul;
+    __b ^= (__b >> 47);
+    __b *= __mul;
+    return __b;
+  }
+
+  static _Size __hash_len_0_to_16(const char* __s, _Size __len)
+     _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+  {
+    if (__len > 8) {
+      const _Size __a = __loadword<_Size>(__s);
+      const _Size __b = __loadword<_Size>(__s + __len - 8);
+      return __hash_len_16(__a, __rotate_by_at_least_1(__b + __len, __len)) ^ __b;
+    }
+    if (__len >= 4) {
+      const uint32_t __a = __loadword<uint32_t>(__s);
+      const uint32_t __b = __loadword<uint32_t>(__s + __len - 4);
+      return __hash_len_16(__len + (__a << 3), __b);
+    }
+    if (__len > 0) {
+      const unsigned char __a = static_cast<unsigned char>(__s[0]);
+      const unsigned char __b = static_cast<unsigned char>(__s[__len >> 1]);
+      const unsigned char __c = static_cast<unsigned char>(__s[__len - 1]);
+      const uint32_t __y = static_cast<uint32_t>(__a) +
+                           (static_cast<uint32_t>(__b) << 8);
+      const uint32_t __z = __len + (static_cast<uint32_t>(__c) << 2);
+      return __shift_mix(__y * __k2 ^ __z * __k3) * __k2;
+    }
+    return __k2;
+  }
+
+  static _Size __hash_len_17_to_32(const char *__s, _Size __len)
+     _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+  {
+    const _Size __a = __loadword<_Size>(__s) * __k1;
+    const _Size __b = __loadword<_Size>(__s + 8);
+    const _Size __c = __loadword<_Size>(__s + __len - 8) * __k2;
+    const _Size __d = __loadword<_Size>(__s + __len - 16) * __k0;
+    return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d,
+                         __a + __rotate(__b ^ __k3, 20) - __c + __len);
+  }
+
+  // Return a 16-byte hash for 48 bytes.  Quick and dirty.
+  // Callers do best to use "random-looking" values for a and b.
+  static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
+      _Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b)
+        _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+  {
+    __a += __w;
+    __b = __rotate(__b + __a + __z, 21);
+    const _Size __c = __a;
+    __a += __x;
+    __a += __y;
+    __b += __rotate(__a, 44);
+    return pair<_Size, _Size>(__a + __z, __b + __c);
+  }
+
+  // Return a 16-byte hash for s[0] ... s[31], a, and b.  Quick and dirty.
+  static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
+      const char* __s, _Size __a, _Size __b)
+    _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+  {
+    return __weak_hash_len_32_with_seeds(__loadword<_Size>(__s),
+                                         __loadword<_Size>(__s + 8),
+                                         __loadword<_Size>(__s + 16),
+                                         __loadword<_Size>(__s + 24),
+                                         __a,
+                                         __b);
+  }
+
+  // Return an 8-byte hash for 33 to 64 bytes.
+  static _Size __hash_len_33_to_64(const char *__s, size_t __len)
+    _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+  {
+    _Size __z = __loadword<_Size>(__s + 24);
+    _Size __a = __loadword<_Size>(__s) +
+                (__len + __loadword<_Size>(__s + __len - 16)) * __k0;
+    _Size __b = __rotate(__a + __z, 52);
+    _Size __c = __rotate(__a, 37);
+    __a += __loadword<_Size>(__s + 8);
+    __c += __rotate(__a, 7);
+    __a += __loadword<_Size>(__s + 16);
+    _Size __vf = __a + __z;
+    _Size __vs = __b + __rotate(__a, 31) + __c;
+    __a = __loadword<_Size>(__s + 16) + __loadword<_Size>(__s + __len - 32);
+    __z += __loadword<_Size>(__s + __len - 8);
+    __b = __rotate(__a + __z, 52);
+    __c = __rotate(__a, 37);
+    __a += __loadword<_Size>(__s + __len - 24);
+    __c += __rotate(__a, 7);
+    __a += __loadword<_Size>(__s + __len - 16);
+    _Size __wf = __a + __z;
+    _Size __ws = __b + __rotate(__a, 31) + __c;
+    _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0);
+    return __shift_mix(__r * __k0 + __vs) * __k2;
+  }
+};
+
+// cityhash64
+template <class _Size>
+_Size
+__murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len)
+{
+  const char* __s = static_cast<const char*>(__key);
+  if (__len <= 32) {
+    if (__len <= 16) {
+      return __hash_len_0_to_16(__s, __len);
+    } else {
+      return __hash_len_17_to_32(__s, __len);
+    }
+  } else if (__len <= 64) {
+    return __hash_len_33_to_64(__s, __len);
+  }
+
+  // For strings over 64 bytes we hash the end first, and then as we
+  // loop we keep 56 bytes of state: v, w, x, y, and z.
+  _Size __x = __loadword<_Size>(__s + __len - 40);
+  _Size __y = __loadword<_Size>(__s + __len - 16) +
+              __loadword<_Size>(__s + __len - 56);
+  _Size __z = __hash_len_16(__loadword<_Size>(__s + __len - 48) + __len,
+                          __loadword<_Size>(__s + __len - 24));
+  pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);
+  pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);
+  __x = __x * __k1 + __loadword<_Size>(__s);
+
+  // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
+  __len = (__len - 1) & ~static_cast<_Size>(63);
+  do {
+    __x = __rotate(__x + __y + __v.first + __loadword<_Size>(__s + 8), 37) * __k1;
+    __y = __rotate(__y + __v.second + __loadword<_Size>(__s + 48), 42) * __k1;
+    __x ^= __w.second;
+    __y += __v.first + __loadword<_Size>(__s + 40);
+    __z = __rotate(__z + __w.first, 33) * __k1;
+    __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first);
+    __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second,
+                                        __y + __loadword<_Size>(__s + 16));
+    _VSTD::swap(__z, __x);
+    __s += 64;
+    __len -= 64;
+  } while (__len != 0);
+  return __hash_len_16(
+      __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z,
+      __hash_len_16(__v.second, __w.second) + __x);
+}
+
+template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)>
+struct __scalar_hash;
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Tp>
+struct __scalar_hash<_Tp, 0>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<_Tp, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp __v) const _NOEXCEPT
+    {
+        union
+        {
+            _Tp    __t;
+            size_t __a;
+        } __u;
+        __u.__a = 0;
+        __u.__t = __v;
+        return __u.__a;
+    }
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Tp>
+struct __scalar_hash<_Tp, 1>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<_Tp, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp __v) const _NOEXCEPT
+    {
+        union
+        {
+            _Tp    __t;
+            size_t __a;
+        } __u;
+        __u.__t = __v;
+        return __u.__a;
+    }
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Tp>
+struct __scalar_hash<_Tp, 2>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<_Tp, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp __v) const _NOEXCEPT
+    {
+        union
+        {
+            _Tp __t;
+            struct
+            {
+                size_t __a;
+                size_t __b;
+            } __s;
+        } __u;
+        __u.__t = __v;
+        return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
+    }
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Tp>
+struct __scalar_hash<_Tp, 3>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<_Tp, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp __v) const _NOEXCEPT
+    {
+        union
+        {
+            _Tp __t;
+            struct
+            {
+                size_t __a;
+                size_t __b;
+                size_t __c;
+            } __s;
+        } __u;
+        __u.__t = __v;
+        return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
+    }
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Tp>
+struct __scalar_hash<_Tp, 4>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<_Tp, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp __v) const _NOEXCEPT
+    {
+        union
+        {
+            _Tp __t;
+            struct
+            {
+                size_t __a;
+                size_t __b;
+                size_t __c;
+                size_t __d;
+            } __s;
+        } __u;
+        __u.__t = __v;
+        return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
+    }
+};
+
+struct _PairT {
+  size_t first;
+  size_t second;
+};
+
+_LIBCPP_INLINE_VISIBILITY
+inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT {
+    typedef __scalar_hash<_PairT> _HashT;
+    const _PairT __p = {__lhs, __rhs};
+    return _HashT()(__p);
+}
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS hash<_Tp*>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<_Tp*, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp* argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp* __v) const _NOEXCEPT
+    {
+        union
+        {
+            _Tp* __t;
+            size_t __a;
+        } __u;
+        __u.__t = __v;
+        return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
+    }
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<bool>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<bool, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(bool __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<char>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<char, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef char argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<signed char>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<signed char, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef signed char argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(signed char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<unsigned char>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<unsigned char, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned char argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<char8_t>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<char8_t, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef char8_t argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+#endif // !_LIBCPP_HAS_NO_CHAR8_T
+
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<char16_t>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<char16_t, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef char16_t argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<char32_t>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<char32_t, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef char32_t argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<wchar_t>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<wchar_t, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef wchar_t argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<short>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<short, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef short argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<unsigned short>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<unsigned short, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned short argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<int>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<int, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef int argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<unsigned int>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<unsigned int, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned int argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<long>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<long, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef long argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<unsigned long>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<unsigned long, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned long argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<long long>
+    : public __scalar_hash<long long>
+{
+};
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<unsigned long long>
+    : public __scalar_hash<unsigned long long>
+{
+};
+
+#ifndef _LIBCPP_HAS_NO_INT128
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<__int128_t>
+    : public __scalar_hash<__int128_t>
+{
+};
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<__uint128_t>
+    : public __scalar_hash<__uint128_t>
+{
+};
+
+#endif
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<float>
+    : public __scalar_hash<float>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(float __v) const _NOEXCEPT
+    {
+        // -0.0 and 0.0 should return same hash
+       if (__v == 0.0f)
+           return 0;
+        return __scalar_hash<float>::operator()(__v);
+    }
+};
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<double>
+    : public __scalar_hash<double>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(double __v) const _NOEXCEPT
+    {
+        // -0.0 and 0.0 should return same hash
+       if (__v == 0.0)
+           return 0;
+        return __scalar_hash<double>::operator()(__v);
+    }
+};
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<long double>
+    : public __scalar_hash<long double>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(long double __v) const _NOEXCEPT
+    {
+        // -0.0 and 0.0 should return same hash
+        if (__v == 0.0L)
+            return 0;
+#if defined(__i386__) || (defined(__x86_64__) && defined(__ILP32__))
+        // Zero out padding bits
+        union
+        {
+            long double __t;
+            struct
+            {
+                size_t __a;
+                size_t __b;
+                size_t __c;
+                size_t __d;
+            } __s;
+        } __u;
+        __u.__s.__a = 0;
+        __u.__s.__b = 0;
+        __u.__s.__c = 0;
+        __u.__s.__d = 0;
+        __u.__t = __v;
+        return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d;
+#elif defined(__x86_64__)
+        // Zero out padding bits
+        union
+        {
+            long double __t;
+            struct
+            {
+                size_t __a;
+                size_t __b;
+            } __s;
+        } __u;
+        __u.__s.__a = 0;
+        __u.__s.__b = 0;
+        __u.__t = __v;
+        return __u.__s.__a ^ __u.__s.__b;
+#else
+        return __scalar_hash<long double>::operator()(__v);
+#endif
+    }
+};
+
+#if _LIBCPP_STD_VER > 11
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Tp, bool = is_enum<_Tp>::value>
+struct _LIBCPP_TEMPLATE_VIS __enum_hash
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public unary_function<_Tp, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp __v) const _NOEXCEPT
+    {
+        typedef typename underlying_type<_Tp>::type type;
+        return hash<type>{}(static_cast<type>(__v));
+    }
+};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS __enum_hash<_Tp, false> {
+    __enum_hash() = delete;
+    __enum_hash(__enum_hash const&) = delete;
+    __enum_hash& operator=(__enum_hash const&) = delete;
+};
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp>
+{
+};
+#endif
+
+#if _LIBCPP_STD_VER > 14
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<nullptr_t>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+  : public unary_function<nullptr_t, size_t>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef nullptr_t argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(nullptr_t) const _NOEXCEPT {
+        return 662607004ull;
+    }
+};
+#endif
+
+#ifndef _LIBCPP_CXX03_LANG
+template <class _Key, class _Hash>
+using __check_hash_requirements _LIBCPP_NODEBUG_TYPE  = integral_constant<bool,
+    is_copy_constructible<_Hash>::value &&
+    is_move_constructible<_Hash>::value &&
+    __invokable_r<size_t, _Hash, _Key const&>::value
+>;
+
+template <class _Key, class _Hash = hash<_Key> >
+using __has_enabled_hash _LIBCPP_NODEBUG_TYPE = integral_constant<bool,
+    __check_hash_requirements<_Key, _Hash>::value &&
+    is_default_constructible<_Hash>::value
+>;
+
+#if _LIBCPP_STD_VER > 14
+template <class _Type, class>
+using __enable_hash_helper_imp _LIBCPP_NODEBUG_TYPE  = _Type;
+
+template <class _Type, class ..._Keys>
+using __enable_hash_helper _LIBCPP_NODEBUG_TYPE  = __enable_hash_helper_imp<_Type,
+  typename enable_if<__all<__has_enabled_hash<_Keys>::value...>::value>::type
+>;
+#else
+template <class _Type, class ...>
+using __enable_hash_helper _LIBCPP_NODEBUG_TYPE = _Type;
+#endif
+
+#endif // !_LIBCPP_CXX03_LANG
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___FUNCTIONAL_HASH_H
diff --git a/include/__functional/identity.h b/include/__functional/identity.h
new file mode 100644
index 0000000..6b8346b
--- /dev/null
+++ b/include/__functional/identity.h
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_IDENTITY_H
+#define _LIBCPP___FUNCTIONAL_IDENTITY_H
+
+#include <__config>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+struct identity {
+    template<class _Tp>
+    _LIBCPP_NODISCARD_EXT constexpr _Tp&& operator()(_Tp&& __t) const noexcept
+    {
+        return _VSTD::forward<_Tp>(__t);
+    }
+
+    using is_transparent = void;
+};
+#endif // _LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_IDENTITY_H
diff --git a/include/__functional/invoke.h b/include/__functional/invoke.h
new file mode 100644
index 0000000..0e167c7
--- /dev/null
+++ b/include/__functional/invoke.h
@@ -0,0 +1,100 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_INVOKE_H
+#define _LIBCPP___FUNCTIONAL_INVOKE_H
+
+#include <__config>
+#include <__functional/weak_result_type.h>
+#include <__utility/forward.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Ret, bool = is_void<_Ret>::value>
+struct __invoke_void_return_wrapper
+{
+#ifndef _LIBCPP_CXX03_LANG
+    template <class ..._Args>
+    static _Ret __call(_Args&&... __args) {
+        return _VSTD::__invoke(_VSTD::forward<_Args>(__args)...);
+    }
+#else
+    template <class _Fn>
+    static _Ret __call(_Fn __f) {
+        return _VSTD::__invoke(__f);
+    }
+
+    template <class _Fn, class _A0>
+    static _Ret __call(_Fn __f, _A0& __a0) {
+        return _VSTD::__invoke(__f, __a0);
+    }
+
+    template <class _Fn, class _A0, class _A1>
+    static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) {
+        return _VSTD::__invoke(__f, __a0, __a1);
+    }
+
+    template <class _Fn, class _A0, class _A1, class _A2>
+    static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){
+        return _VSTD::__invoke(__f, __a0, __a1, __a2);
+    }
+#endif
+};
+
+template <class _Ret>
+struct __invoke_void_return_wrapper<_Ret, true>
+{
+#ifndef _LIBCPP_CXX03_LANG
+    template <class ..._Args>
+    static void __call(_Args&&... __args) {
+        _VSTD::__invoke(_VSTD::forward<_Args>(__args)...);
+    }
+#else
+    template <class _Fn>
+    static void __call(_Fn __f) {
+        _VSTD::__invoke(__f);
+    }
+
+    template <class _Fn, class _A0>
+    static void __call(_Fn __f, _A0& __a0) {
+        _VSTD::__invoke(__f, __a0);
+    }
+
+    template <class _Fn, class _A0, class _A1>
+    static void __call(_Fn __f, _A0& __a0, _A1& __a1) {
+        _VSTD::__invoke(__f, __a0, __a1);
+    }
+
+    template <class _Fn, class _A0, class _A1, class _A2>
+    static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) {
+        _VSTD::__invoke(__f, __a0, __a1, __a2);
+    }
+#endif
+};
+
+#if _LIBCPP_STD_VER > 14
+
+template <class _Fn, class ..._Args>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 invoke_result_t<_Fn, _Args...>
+invoke(_Fn&& __f, _Args&&... __args)
+    noexcept(is_nothrow_invocable_v<_Fn, _Args...>)
+{
+    return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
+}
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_INVOKE_H
diff --git a/include/__functional/is_transparent.h b/include/__functional/is_transparent.h
new file mode 100644
index 0000000..4a72aa8
--- /dev/null
+++ b/include/__functional/is_transparent.h
@@ -0,0 +1,36 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_IS_TRANSPARENT
+#define _LIBCPP___FUNCTIONAL_IS_TRANSPARENT
+
+#include <__config>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 11
+
+template <class _Tp, class, class = void>
+struct __is_transparent : false_type {};
+
+template <class _Tp, class _Up>
+struct __is_transparent<_Tp, _Up,
+                        typename __void_t<typename _Tp::is_transparent>::type>
+   : true_type {};
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_IS_TRANSPARENT
diff --git a/include/__functional/mem_fn.h b/include/__functional/mem_fn.h
new file mode 100644
index 0000000..1fa070a
--- /dev/null
+++ b/include/__functional/mem_fn.h
@@ -0,0 +1,161 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_MEM_FN_H
+#define _LIBCPP___FUNCTIONAL_MEM_FN_H
+
+#include <__config>
+#include <__functional/weak_result_type.h>
+#include <__functional/binary_function.h>
+#include <__functional/invoke.h>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+class __mem_fn
+#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public __weak_result_type<_Tp>
+#endif
+{
+public:
+    // types
+    typedef _Tp type;
+private:
+    type __f_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    __mem_fn(type __f) _NOEXCEPT : __f_(__f) {}
+
+#ifndef _LIBCPP_CXX03_LANG
+    // invoke
+    template <class... _ArgTypes>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    typename __invoke_return<type, _ArgTypes...>::type
+    operator() (_ArgTypes&&... __args) const {
+        return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);
+    }
+#else
+
+    template <class _A0>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return0<type, _A0>::type
+    operator() (_A0& __a0) const {
+        return _VSTD::__invoke(__f_, __a0);
+    }
+
+    template <class _A0>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return0<type, _A0 const>::type
+    operator() (_A0 const& __a0) const {
+        return _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__invoke(__f_, __a0, __a1, __a2);
+    }
+#endif
+};
+
+template<class _Rp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+__mem_fn<_Rp _Tp::*>
+mem_fn(_Rp _Tp::* __pm) _NOEXCEPT
+{
+    return __mem_fn<_Rp _Tp::*>(__pm);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_MEM_FN_H
diff --git a/include/__functional/mem_fun_ref.h b/include/__functional/mem_fun_ref.h
new file mode 100644
index 0000000..4616da0
--- /dev/null
+++ b/include/__functional/mem_fun_ref.h
@@ -0,0 +1,173 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H
+#define _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H
+
+#include <__config>
+#include <__functional/unary_function.h>
+#include <__functional/binary_function.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
+
+template<class _Sp, class _Tp>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t
+    : public unary_function<_Tp*, _Sp>
+{
+    _Sp (_Tp::*__p_)();
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit mem_fun_t(_Sp (_Tp::*__p)())
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p) const
+        {return (__p->*__p_)();}
+};
+
+template<class _Sp, class _Tp, class _Ap>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t
+    : public binary_function<_Tp*, _Ap, _Sp>
+{
+    _Sp (_Tp::*__p_)(_Ap);
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_t(_Sp (_Tp::*__p)(_Ap))
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p, _Ap __x) const
+        {return (__p->*__p_)(__x);}
+};
+
+template<class _Sp, class _Tp>
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
+mem_fun_t<_Sp,_Tp>
+mem_fun(_Sp (_Tp::*__f)())
+    {return mem_fun_t<_Sp,_Tp>(__f);}
+
+template<class _Sp, class _Tp, class _Ap>
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
+mem_fun1_t<_Sp,_Tp,_Ap>
+mem_fun(_Sp (_Tp::*__f)(_Ap))
+    {return mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
+
+template<class _Sp, class _Tp>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t
+    : public unary_function<_Tp, _Sp>
+{
+    _Sp (_Tp::*__p_)();
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit mem_fun_ref_t(_Sp (_Tp::*__p)())
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p) const
+        {return (__p.*__p_)();}
+};
+
+template<class _Sp, class _Tp, class _Ap>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t
+    : public binary_function<_Tp, _Ap, _Sp>
+{
+    _Sp (_Tp::*__p_)(_Ap);
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap))
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p, _Ap __x) const
+        {return (__p.*__p_)(__x);}
+};
+
+template<class _Sp, class _Tp>
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
+mem_fun_ref_t<_Sp,_Tp>
+mem_fun_ref(_Sp (_Tp::*__f)())
+    {return mem_fun_ref_t<_Sp,_Tp>(__f);}
+
+template<class _Sp, class _Tp, class _Ap>
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
+mem_fun1_ref_t<_Sp,_Tp,_Ap>
+mem_fun_ref(_Sp (_Tp::*__f)(_Ap))
+    {return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
+
+template <class _Sp, class _Tp>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t
+    : public unary_function<const _Tp*, _Sp>
+{
+    _Sp (_Tp::*__p_)() const;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_t(_Sp (_Tp::*__p)() const)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p) const
+        {return (__p->*__p_)();}
+};
+
+template <class _Sp, class _Tp, class _Ap>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t
+    : public binary_function<const _Tp*, _Ap, _Sp>
+{
+    _Sp (_Tp::*__p_)(_Ap) const;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_t(_Sp (_Tp::*__p)(_Ap) const)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p, _Ap __x) const
+        {return (__p->*__p_)(__x);}
+};
+
+template <class _Sp, class _Tp>
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
+const_mem_fun_t<_Sp,_Tp>
+mem_fun(_Sp (_Tp::*__f)() const)
+    {return const_mem_fun_t<_Sp,_Tp>(__f);}
+
+template <class _Sp, class _Tp, class _Ap>
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
+const_mem_fun1_t<_Sp,_Tp,_Ap>
+mem_fun(_Sp (_Tp::*__f)(_Ap) const)
+    {return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
+
+template <class _Sp, class _Tp>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t
+    : public unary_function<_Tp, _Sp>
+{
+    _Sp (_Tp::*__p_)() const;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_ref_t(_Sp (_Tp::*__p)() const)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p) const
+        {return (__p.*__p_)();}
+};
+
+template <class _Sp, class _Tp, class _Ap>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t
+    : public binary_function<_Tp, _Ap, _Sp>
+{
+    _Sp (_Tp::*__p_)(_Ap) const;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap) const)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p, _Ap __x) const
+        {return (__p.*__p_)(__x);}
+};
+
+template <class _Sp, class _Tp>
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
+const_mem_fun_ref_t<_Sp,_Tp>
+mem_fun_ref(_Sp (_Tp::*__f)() const)
+    {return const_mem_fun_ref_t<_Sp,_Tp>(__f);}
+
+template <class _Sp, class _Tp, class _Ap>
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
+const_mem_fun1_ref_t<_Sp,_Tp,_Ap>
+mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const)
+    {return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
+
+#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H
diff --git a/include/__functional/not_fn.h b/include/__functional/not_fn.h
new file mode 100644
index 0000000..632be5f
--- /dev/null
+++ b/include/__functional/not_fn.h
@@ -0,0 +1,47 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_NOT_FN_H
+#define _LIBCPP___FUNCTIONAL_NOT_FN_H
+
+#include <__config>
+#include <__functional/perfect_forward.h>
+#include <__functional/invoke.h>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+struct __not_fn_op
+{
+    template<class... _Args>
+    static _LIBCPP_CONSTEXPR_AFTER_CXX17 auto __call(_Args&&... __args)
+    noexcept(noexcept(!_VSTD::invoke(_VSTD::forward<_Args>(__args)...)))
+    -> decltype(      !_VSTD::invoke(_VSTD::forward<_Args>(__args)...))
+    { return          !_VSTD::invoke(_VSTD::forward<_Args>(__args)...); }
+};
+
+template<class _Fn,
+         class = _EnableIf<is_constructible_v<decay_t<_Fn>, _Fn> &&
+                           is_move_constructible_v<_Fn>>>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 auto not_fn(_Fn&& __f)
+{
+    return __perfect_forward<__not_fn_op, _Fn>(_VSTD::forward<_Fn>(__f));
+}
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_NOT_FN_H
diff --git a/include/__functional/operations.h b/include/__functional/operations.h
new file mode 100644
index 0000000..667d179
--- /dev/null
+++ b/include/__functional/operations.h
@@ -0,0 +1,729 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_OPERATIONS_H
+#define _LIBCPP___FUNCTIONAL_OPERATIONS_H
+
+#include <__config>
+#include <__functional/binary_function.h>
+#include <__functional/unary_function.h>
+#include <__utility/forward.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Arithmetic operations
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS plus
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x + __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS plus<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS minus
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x - __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS minus<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS multiplies
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x * __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS multiplies<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS divides
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x / __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS divides<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS modulus
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x % __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS modulus<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS negate
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : unary_function<_Tp, _Tp>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return -__x;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS negate<void>
+{
+    template <class _Tp>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_Tp&& __x) const
+    _NOEXCEPT_(noexcept(- _VSTD::forward<_Tp>(__x)))
+    -> decltype        (- _VSTD::forward<_Tp>(__x))
+        { return        - _VSTD::forward<_Tp>(__x); }
+    typedef void is_transparent;
+};
+#endif
+
+// Bitwise operations
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS bit_and
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x & __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS bit_and<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+#if _LIBCPP_STD_VER > 11
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Tp = void>
+struct _LIBCPP_TEMPLATE_VIS bit_not
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : unary_function<_Tp, _Tp>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return ~__x;}
+};
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS bit_not<void>
+{
+    template <class _Tp>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_Tp&& __x) const
+    _NOEXCEPT_(noexcept(~_VSTD::forward<_Tp>(__x)))
+    -> decltype        (~_VSTD::forward<_Tp>(__x))
+        { return        ~_VSTD::forward<_Tp>(__x); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS bit_or
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x | __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS bit_or<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS bit_xor
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x ^ __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS bit_xor<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+// Comparison operations
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS equal_to
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x == __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS equal_to<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS not_equal_to
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x != __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS not_equal_to<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS less
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x < __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS less<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS less_equal
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x <= __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS less_equal<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS greater_equal
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x >= __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS greater_equal<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS greater
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x > __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS greater<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+// Logical operations
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS logical_and
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x && __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS logical_and<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS logical_not
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : unary_function<_Tp, bool>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x) const
+        {return !__x;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS logical_not<void>
+{
+    template <class _Tp>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_Tp&& __x) const
+    _NOEXCEPT_(noexcept(!_VSTD::forward<_Tp>(__x)))
+    -> decltype        (!_VSTD::forward<_Tp>(__x))
+        { return        !_VSTD::forward<_Tp>(__x); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS logical_or
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+    typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x || __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TEMPLATE_VIS logical_or<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u)))
+    -> decltype        (_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u))
+        { return        _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_OPERATIONS_H
diff --git a/include/__functional/perfect_forward.h b/include/__functional/perfect_forward.h
new file mode 100644
index 0000000..a5678e1
--- /dev/null
+++ b/include/__functional/perfect_forward.h
@@ -0,0 +1,88 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H
+#define _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H
+
+#include <__config>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+template<class _Op, class _Tuple,
+         class _Idxs = typename __make_tuple_indices<tuple_size<_Tuple>::value>::type>
+struct __perfect_forward_impl;
+
+template<class _Op, class... _Bound, size_t... _Idxs>
+struct __perfect_forward_impl<_Op, __tuple_types<_Bound...>, __tuple_indices<_Idxs...>>
+{
+    tuple<_Bound...> __bound_;
+
+    template<class... _Args>
+    _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) &
+    noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...)))
+    -> decltype(      _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...))
+    {return           _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...);}
+
+    template<class... _Args>
+    _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) const&
+    noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...)))
+    -> decltype(      _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...))
+    {return           _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...);}
+
+    template<class... _Args>
+    _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) &&
+    noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))...,
+                                  _VSTD::forward<_Args>(__args)...)))
+    -> decltype(      _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))...,
+                                  _VSTD::forward<_Args>(__args)...))
+    {return           _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))...,
+                                  _VSTD::forward<_Args>(__args)...);}
+
+    template<class... _Args>
+    _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) const&&
+    noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))...,
+                                  _VSTD::forward<_Args>(__args)...)))
+    -> decltype(      _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))...,
+                                  _VSTD::forward<_Args>(__args)...))
+    {return           _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))...,
+                                  _VSTD::forward<_Args>(__args)...);}
+
+    template<class _Fn = typename tuple_element<0, tuple<_Bound...>>::type,
+             class = _EnableIf<is_copy_constructible_v<_Fn>>>
+    constexpr __perfect_forward_impl(__perfect_forward_impl const& __other)
+        : __bound_(__other.__bound_) {}
+
+    template<class _Fn = typename tuple_element<0, tuple<_Bound...>>::type,
+             class = _EnableIf<is_move_constructible_v<_Fn>>>
+    constexpr __perfect_forward_impl(__perfect_forward_impl && __other)
+        : __bound_(_VSTD::move(__other.__bound_)) {}
+
+    template<class... _BoundArgs>
+    explicit constexpr __perfect_forward_impl(_BoundArgs&&... __bound) :
+        __bound_(_VSTD::forward<_BoundArgs>(__bound)...) { }
+};
+
+template<class _Op, class... _Args>
+using __perfect_forward =
+    __perfect_forward_impl<_Op, __tuple_types<decay_t<_Args>...>>;
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H
diff --git a/include/__functional/pointer_to_binary_function.h b/include/__functional/pointer_to_binary_function.h
new file mode 100644
index 0000000..d4a6c16
--- /dev/null
+++ b/include/__functional/pointer_to_binary_function.h
@@ -0,0 +1,46 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H
+#define _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H
+
+#include <__config>
+#include <__functional/binary_function.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
+
+template <class _Arg1, class _Arg2, class _Result>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function
+    : public binary_function<_Arg1, _Arg2, _Result>
+{
+    _Result (*__f_)(_Arg1, _Arg2);
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit pointer_to_binary_function(_Result (*__f)(_Arg1, _Arg2))
+        : __f_(__f) {}
+    _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg1 __x, _Arg2 __y) const
+        {return __f_(__x, __y);}
+};
+
+template <class _Arg1, class _Arg2, class _Result>
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
+pointer_to_binary_function<_Arg1,_Arg2,_Result>
+ptr_fun(_Result (*__f)(_Arg1,_Arg2))
+    {return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);}
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H
diff --git a/include/__functional/pointer_to_unary_function.h b/include/__functional/pointer_to_unary_function.h
new file mode 100644
index 0000000..0ac4561
--- /dev/null
+++ b/include/__functional/pointer_to_unary_function.h
@@ -0,0 +1,46 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H
+#define _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H
+
+#include <__config>
+#include <__functional/unary_function.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
+
+template <class _Arg, class _Result>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function
+    : public unary_function<_Arg, _Result>
+{
+    _Result (*__f_)(_Arg);
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit pointer_to_unary_function(_Result (*__f)(_Arg))
+        : __f_(__f) {}
+    _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg __x) const
+        {return __f_(__x);}
+};
+
+template <class _Arg, class _Result>
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
+pointer_to_unary_function<_Arg,_Result>
+ptr_fun(_Result (*__f)(_Arg))
+    {return pointer_to_unary_function<_Arg,_Result>(__f);}
+
+#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H
diff --git a/include/__functional/ranges_operations.h b/include/__functional/ranges_operations.h
new file mode 100644
index 0000000..777c535
--- /dev/null
+++ b/include/__functional/ranges_operations.h
@@ -0,0 +1,97 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H
+#define _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H
+
+#include <__config>
+#include <concepts>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+namespace ranges {
+
+struct equal_to {
+  template <class _Tp, class _Up>
+  requires equality_comparable_with<_Tp, _Up>
+  [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+      noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)))) {
+    return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u);
+  }
+
+  using is_transparent = void;
+};
+
+struct not_equal_to {
+  template <class _Tp, class _Up>
+  requires equality_comparable_with<_Tp, _Up>
+  [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+      noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u))))) {
+    return !(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u));
+  }
+
+  using is_transparent = void;
+};
+
+struct less {
+  template <class _Tp, class _Up>
+  requires totally_ordered_with<_Tp, _Up>
+  [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+      noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)))) {
+    return _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u);
+  }
+
+  using is_transparent = void;
+};
+
+struct less_equal {
+  template <class _Tp, class _Up>
+  requires totally_ordered_with<_Tp, _Up>
+  [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+      noexcept(noexcept(bool(!(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t))))) {
+    return !(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t));
+  }
+
+  using is_transparent = void;
+};
+
+struct greater {
+  template <class _Tp, class _Up>
+  requires totally_ordered_with<_Tp, _Up>
+  [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+      noexcept(noexcept(bool(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)))) {
+    return _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t);
+  }
+
+  using is_transparent = void;
+};
+
+struct greater_equal {
+  template <class _Tp, class _Up>
+  requires totally_ordered_with<_Tp, _Up>
+  [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const
+      noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u))))) {
+    return !(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u));
+  }
+
+  using is_transparent = void;
+};
+
+} // namespace ranges
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H
diff --git a/include/__functional/reference_wrapper.h b/include/__functional/reference_wrapper.h
new file mode 100644
index 0000000..09f4a64
--- /dev/null
+++ b/include/__functional/reference_wrapper.h
@@ -0,0 +1,223 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
+#define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
+
+#include <__config>
+#include <__functional/weak_result_type.h>
+#include <__memory/addressof.h>
+#include <__utility/forward.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+class _LIBCPP_TEMPLATE_VIS reference_wrapper
+#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : public __weak_result_type<_Tp>
+#endif
+{
+public:
+    // types
+    typedef _Tp type;
+private:
+    type* __f_;
+
+#ifndef _LIBCPP_CXX03_LANG
+    static void __fun(_Tp&) _NOEXCEPT;
+    static void __fun(_Tp&&) = delete;
+#endif
+
+public:
+    // construct/copy/destroy
+#ifdef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    reference_wrapper(type& __f) _NOEXCEPT
+        : __f_(_VSTD::addressof(__f)) {}
+#else
+    template <class _Up, class = _EnableIf<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(declval<_Up>())) >>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(declval<_Up>()))) {
+        type& __f = static_cast<_Up&&>(__u);
+        __f_ = _VSTD::addressof(__f);
+    }
+#endif
+
+    // access
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    operator type&() const _NOEXCEPT {return *__f_;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    type& get() const _NOEXCEPT {return *__f_;}
+
+#ifndef _LIBCPP_CXX03_LANG
+    // invoke
+    template <class... _ArgTypes>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    typename __invoke_of<type&, _ArgTypes...>::type
+    operator() (_ArgTypes&&... __args) const {
+        return _VSTD::__invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
+    }
+#else
+
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return<type>::type
+    operator() () const {
+        return _VSTD::__invoke(get());
+    }
+
+    template <class _A0>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return0<type, _A0>::type
+    operator() (_A0& __a0) const {
+        return _VSTD::__invoke(get(), __a0);
+    }
+
+    template <class _A0>
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return0<type, _A0 const>::type
+    operator() (_A0 const& __a0) const {
+        return _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__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 _VSTD::__invoke(get(), __a0, __a1, __a2);
+    }
+#endif // _LIBCPP_CXX03_LANG
+};
+
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+template <class _Tp>
+reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
+#endif
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+reference_wrapper<_Tp>
+ref(_Tp& __t) _NOEXCEPT
+{
+    return reference_wrapper<_Tp>(__t);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+reference_wrapper<_Tp>
+ref(reference_wrapper<_Tp> __t) _NOEXCEPT
+{
+    return _VSTD::ref(__t.get());
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+reference_wrapper<const _Tp>
+cref(const _Tp& __t) _NOEXCEPT
+{
+    return reference_wrapper<const _Tp>(__t);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+reference_wrapper<const _Tp>
+cref(reference_wrapper<_Tp> __t) _NOEXCEPT
+{
+    return _VSTD::cref(__t.get());
+}
+
+#ifndef _LIBCPP_CXX03_LANG
+template <class _Tp> void ref(const _Tp&&) = delete;
+template <class _Tp> void cref(const _Tp&&) = delete;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
diff --git a/include/__functional/unary_function.h b/include/__functional/unary_function.h
new file mode 100644
index 0000000..8084ef4
--- /dev/null
+++ b/include/__functional/unary_function.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H
+#define _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Arg, class _Result>
+struct _LIBCPP_TEMPLATE_VIS unary_function
+{
+    typedef _Arg    argument_type;
+    typedef _Result result_type;
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H
diff --git a/include/__functional/unary_negate.h b/include/__functional/unary_negate.h
new file mode 100644
index 0000000..71257cf
--- /dev/null
+++ b/include/__functional/unary_negate.h
@@ -0,0 +1,47 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H
+#define _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H
+
+#include <__config>
+#include <__functional/unary_function.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS)
+
+template <class _Predicate>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 unary_negate
+    : public unary_function<typename _Predicate::argument_type, bool>
+{
+    _Predicate __pred_;
+public:
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    explicit unary_negate(const _Predicate& __pred)
+        : __pred_(__pred) {}
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const typename _Predicate::argument_type& __x) const
+        {return !__pred_(__x);}
+};
+
+template <class _Predicate>
+_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+unary_negate<_Predicate>
+not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);}
+
+#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H
diff --git a/include/__functional/unwrap_ref.h b/include/__functional/unwrap_ref.h
new file mode 100644
index 0000000..4d091ec
--- /dev/null
+++ b/include/__functional/unwrap_ref.h
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_UNWRAP_REF_H
+#define _LIBCPP___FUNCTIONAL_UNWRAP_REF_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct __unwrap_reference { typedef _LIBCPP_NODEBUG_TYPE _Tp type; };
+
+template <class _Tp>
+class reference_wrapper;
+
+template <class _Tp>
+struct __unwrap_reference<reference_wrapper<_Tp> > { typedef _LIBCPP_NODEBUG_TYPE _Tp& type; };
+
+template <class _Tp>
+struct decay;
+
+#if _LIBCPP_STD_VER > 17
+template <class _Tp>
+struct unwrap_reference : __unwrap_reference<_Tp> { };
+
+template <class _Tp>
+using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
+
+template <class _Tp>
+struct unwrap_ref_decay : unwrap_reference<typename decay<_Tp>::type> { };
+
+template <class _Tp>
+using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
+#endif // > C++17
+
+template <class _Tp>
+struct __unwrap_ref_decay
+#if _LIBCPP_STD_VER > 17
+    : unwrap_ref_decay<_Tp>
+#else
+    : __unwrap_reference<typename decay<_Tp>::type>
+#endif
+{ };
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___FUNCTIONAL_UNWRAP_REF_H
diff --git a/include/__functional/weak_result_type.h b/include/__functional/weak_result_type.h
new file mode 100644
index 0000000..2ee85ac
--- /dev/null
+++ b/include/__functional/weak_result_type.h
@@ -0,0 +1,481 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H
+#define _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H
+
+#include <__config>
+#include <__functional/binary_function.h>
+#include <__functional/unary_function.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct __has_result_type
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::result_type* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+// __weak_result_type
+
+template <class _Tp>
+struct __derives_from_unary_function
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    static __two __test(...);
+    template <class _Ap, class _Rp>
+        static unary_function<_Ap, _Rp>
+        __test(const volatile unary_function<_Ap, _Rp>*);
+public:
+    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
+    typedef decltype(__test((_Tp*)0)) type;
+};
+
+template <class _Tp>
+struct __derives_from_binary_function
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    static __two __test(...);
+    template <class _A1, class _A2, class _Rp>
+        static binary_function<_A1, _A2, _Rp>
+        __test(const volatile binary_function<_A1, _A2, _Rp>*);
+public:
+    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
+    typedef decltype(__test((_Tp*)0)) type;
+};
+
+template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
+struct __maybe_derive_from_unary_function  // bool is true
+    : public __derives_from_unary_function<_Tp>::type
+{
+};
+
+template <class _Tp>
+struct __maybe_derive_from_unary_function<_Tp, false>
+{
+};
+
+template <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
+struct __maybe_derive_from_binary_function  // bool is true
+    : public __derives_from_binary_function<_Tp>::type
+{
+};
+
+template <class _Tp>
+struct __maybe_derive_from_binary_function<_Tp, false>
+{
+};
+
+template <class _Tp, bool = __has_result_type<_Tp>::value>
+struct __weak_result_type_imp // bool is true
+    : public __maybe_derive_from_unary_function<_Tp>,
+      public __maybe_derive_from_binary_function<_Tp>
+{
+    typedef _LIBCPP_NODEBUG_TYPE typename _Tp::result_type result_type;
+};
+
+template <class _Tp>
+struct __weak_result_type_imp<_Tp, false>
+    : public __maybe_derive_from_unary_function<_Tp>,
+      public __maybe_derive_from_binary_function<_Tp>
+{
+};
+
+template <class _Tp>
+struct __weak_result_type
+    : public __weak_result_type_imp<_Tp>
+{
+};
+
+// 0 argument case
+
+template <class _Rp>
+struct __weak_result_type<_Rp ()>
+{
+    typedef _LIBCPP_NODEBUG_TYPE  _Rp result_type;
+};
+
+template <class _Rp>
+struct __weak_result_type<_Rp (&)()>
+{
+    typedef _LIBCPP_NODEBUG_TYPE  _Rp result_type;
+};
+
+template <class _Rp>
+struct __weak_result_type<_Rp (*)()>
+{
+    typedef _LIBCPP_NODEBUG_TYPE  _Rp result_type;
+};
+
+// 1 argument case
+
+template <class _Rp, class _A1>
+struct __weak_result_type<_Rp (_A1)>
+    : public unary_function<_A1, _Rp>
+{
+};
+
+template <class _Rp, class _A1>
+struct __weak_result_type<_Rp (&)(_A1)>
+    : public unary_function<_A1, _Rp>
+{
+};
+
+template <class _Rp, class _A1>
+struct __weak_result_type<_Rp (*)(_A1)>
+    : public unary_function<_A1, _Rp>
+{
+};
+
+template <class _Rp, class _Cp>
+struct __weak_result_type<_Rp (_Cp::*)()>
+    : public unary_function<_Cp*, _Rp>
+{
+};
+
+template <class _Rp, class _Cp>
+struct __weak_result_type<_Rp (_Cp::*)() const>
+    : public unary_function<const _Cp*, _Rp>
+{
+};
+
+template <class _Rp, class _Cp>
+struct __weak_result_type<_Rp (_Cp::*)() volatile>
+    : public unary_function<volatile _Cp*, _Rp>
+{
+};
+
+template <class _Rp, class _Cp>
+struct __weak_result_type<_Rp (_Cp::*)() const volatile>
+    : public unary_function<const volatile _Cp*, _Rp>
+{
+};
+
+// 2 argument case
+
+template <class _Rp, class _A1, class _A2>
+struct __weak_result_type<_Rp (_A1, _A2)>
+    : public binary_function<_A1, _A2, _Rp>
+{
+};
+
+template <class _Rp, class _A1, class _A2>
+struct __weak_result_type<_Rp (*)(_A1, _A2)>
+    : public binary_function<_A1, _A2, _Rp>
+{
+};
+
+template <class _Rp, class _A1, class _A2>
+struct __weak_result_type<_Rp (&)(_A1, _A2)>
+    : public binary_function<_A1, _A2, _Rp>
+{
+};
+
+template <class _Rp, class _Cp, class _A1>
+struct __weak_result_type<_Rp (_Cp::*)(_A1)>
+    : public binary_function<_Cp*, _A1, _Rp>
+{
+};
+
+template <class _Rp, class _Cp, class _A1>
+struct __weak_result_type<_Rp (_Cp::*)(_A1) const>
+    : public binary_function<const _Cp*, _A1, _Rp>
+{
+};
+
+template <class _Rp, class _Cp, class _A1>
+struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile>
+    : public binary_function<volatile _Cp*, _A1, _Rp>
+{
+};
+
+template <class _Rp, class _Cp, class _A1>
+struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile>
+    : public binary_function<const volatile _Cp*, _A1, _Rp>
+{
+};
+
+
+#ifndef _LIBCPP_CXX03_LANG
+// 3 or more arguments
+
+template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
+struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
+struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
+struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
+struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
+struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
+struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
+struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Tp, class ..._Args>
+struct __invoke_return
+{
+    typedef decltype(_VSTD::__invoke(declval<_Tp>(), declval<_Args>()...)) type;
+};
+
+#else // defined(_LIBCPP_CXX03_LANG)
+
+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(*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 _Fn, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __enable_invoke<_Fn, _T1>::_Bullet1
+__invoke(_Fn __f, _T1& __t1) {
+    return (__t1.*__f)();
+}
+
+template <class _Fn, class _T1, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __enable_invoke<_Fn, _T1>::_Bullet1
+__invoke(_Fn __f, _T1& __t1, _A0& __a0) {
+    return (__t1.*__f)(__a0);
+}
+
+template <class _Fn, class _T1, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __enable_invoke<_Fn, _T1>::_Bullet1
+__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
+    return (__t1.*__f)(__a0, __a1);
+}
+
+template <class _Fn, class _T1, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+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 _Fn, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __enable_invoke<_Fn, _T1>::_Bullet2
+__invoke(_Fn __f, _T1& __t1) {
+    return ((*__t1).*__f)();
+}
+
+template <class _Fn, class _T1, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __enable_invoke<_Fn, _T1>::_Bullet2
+__invoke(_Fn __f, _T1& __t1, _A0& __a0) {
+    return ((*__t1).*__f)(__a0);
+}
+
+template <class _Fn, class _T1, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __enable_invoke<_Fn, _T1>::_Bullet2
+__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
+    return ((*__t1).*__f)(__a0, __a1);
+}
+
+template <class _Fn, class _T1, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+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 _Fn, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __enable_invoke<_Fn, _T1>::_Bullet3
+__invoke(_Fn __f, _T1& __t1) {
+    return __t1.*__f;
+}
+
+template <class _Fn, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __enable_invoke<_Fn, _T1>::_Bullet4
+__invoke(_Fn __f, _T1& __t1) {
+    return (*__t1).*__f;
+}
+
+// fifth bullet
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+decltype(declval<_Fp&>()())
+__invoke(_Fp& __f)
+{
+    return __f();
+}
+
+template <class _Fp, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+decltype(declval<_Fp&>()(declval<_A0&>()))
+__invoke(_Fp& __f, _A0& __a0)
+{
+    return __f(__a0);
+}
+
+template <class _Fp, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>()))
+__invoke(_Fp& __f, _A0& __a0, _A1& __a1)
+{
+    return __f(__a0, __a1);
+}
+
+template <class _Fp, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>(), declval<_A2&>()))
+__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2)
+{
+    return __f(__a0, __a1, __a2);
+}
+
+template <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value>
+struct __invoke_return
+{
+    typedef typename __weak_result_type<_Fp>::result_type type;
+};
+
+template <class _Fp>
+struct __invoke_return<_Fp, false>
+{
+    typedef decltype(_VSTD::__invoke(declval<_Fp&>())) type;
+};
+
+template <class _Tp, class _A0>
+struct __invoke_return0
+{
+    typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>())) type;
+};
+
+template <class _Rp, class _Tp, class _A0>
+struct __invoke_return0<_Rp _Tp::*, _A0>
+{
+    typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type;
+};
+
+template <class _Tp, class _A0, class _A1>
+struct __invoke_return1
+{
+    typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(),
+                                                      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>
+struct __invoke_return2
+{
+    typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(),
+                                                      declval<_A1&>(),
+                                                      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 // !defined(_LIBCPP_CXX03_LANG)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H
diff --git a/include/__functional_03 b/include/__functional_03
deleted file mode 100644
index d8a9f05..0000000
--- a/include/__functional_03
+++ /dev/null
@@ -1,2135 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP_FUNCTIONAL_03
-#define _LIBCPP_FUNCTIONAL_03
-
-// manual variadic expansion for <functional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
-template <class _Tp>
-class __mem_fn
-    : public __weak_result_type<_Tp>
-{
-public:
-    // types
-    typedef _Tp type;
-private:
-    type __f_;
-
-public:
-    _LIBCPP_INLINE_VISIBILITY __mem_fn(type __f) : __f_(__f) {}
-
-    // invoke
-
-    typename __invoke_return<type>::type
-       operator() () const
-       {
-           return __invoke(__f_);
-       }
-
-    template <class _A0>
-       typename __invoke_return0<type, _A0>::type
-          operator() (_A0& __a0) const
-          {
-              return __invoke(__f_, __a0);
-          }
-
-    template <class _A0, class _A1>
-       typename __invoke_return1<type, _A0, _A1>::type
-          operator() (_A0& __a0, _A1& __a1) const
-          {
-              return __invoke(__f_, __a0, __a1);
-          }
-
-    template <class _A0, class _A1, class _A2>
-       typename __invoke_return2<type, _A0, _A1, _A2>::type
-          operator() (_A0& __a0, _A1& __a1, _A2& __a2) const
-          {
-              return __invoke(__f_, __a0, __a1, __a2);
-          }
-};
-
-template<class _Rp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp _Tp::*>
-mem_fn(_Rp _Tp::* __pm)
-{
-    return __mem_fn<_Rp _Tp::*>(__pm);
-}
-
-template<class _Rp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)()>
-mem_fn(_Rp (_Tp::* __pm)())
-{
-    return __mem_fn<_Rp (_Tp::*)()>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0)>
-mem_fn(_Rp (_Tp::* __pm)(_A0))
-{
-    return __mem_fn<_Rp (_Tp::*)(_A0)>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1)>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1))
-{
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1)>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2))
-{
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>(__pm);
-}
-
-template<class _Rp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)() const>
-mem_fn(_Rp (_Tp::* __pm)() const)
-{
-    return __mem_fn<_Rp (_Tp::*)() const>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0) const>
-mem_fn(_Rp (_Tp::* __pm)(_A0) const)
-{
-    return __mem_fn<_Rp (_Tp::*)(_A0) const>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1) const>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) const)
-{
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1) const>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) const)
-{
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const>(__pm);
-}
-
-template<class _Rp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)() volatile>
-mem_fn(_Rp (_Tp::* __pm)() volatile)
-{
-    return __mem_fn<_Rp (_Tp::*)() volatile>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0) volatile>
-mem_fn(_Rp (_Tp::* __pm)(_A0) volatile)
-{
-    return __mem_fn<_Rp (_Tp::*)(_A0) volatile>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1) volatile>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) volatile)
-{
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1) volatile>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) volatile>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) volatile)
-{
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) volatile>(__pm);
-}
-
-template<class _Rp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)() const volatile>
-mem_fn(_Rp (_Tp::* __pm)() const volatile)
-{
-    return __mem_fn<_Rp (_Tp::*)() const volatile>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0) const volatile>
-mem_fn(_Rp (_Tp::* __pm)(_A0) const volatile)
-{
-    return __mem_fn<_Rp (_Tp::*)(_A0) const volatile>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1) const volatile>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) const volatile)
-{
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1) const volatile>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const volatile>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) const volatile)
-{
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const volatile>(__pm);
-}
-
-// bad_function_call
-
-class _LIBCPP_EXCEPTION_ABI bad_function_call
-    : public exception
-{
-};
-
-template<class _Fp> class _LIBCPP_TYPE_VIS_ONLY function; // undefined
-
-namespace __function
-{
-
-template<class _Fp>
-struct __maybe_derive_from_unary_function
-{
-};
-
-template<class _Rp, class _A1>
-struct __maybe_derive_from_unary_function<_Rp(_A1)>
-    : public unary_function<_A1, _Rp>
-{
-};
-
-template<class _Fp>
-struct __maybe_derive_from_binary_function
-{
-};
-
-template<class _Rp, class _A1, class _A2>
-struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
-    : public binary_function<_A1, _A2, _Rp>
-{
-};
-
-template<class _Fp> class __base;
-
-template<class _Rp>
-class __base<_Rp()>
-{
-    __base(const __base&);
-    __base& operator=(const __base&);
-public:
-    __base() {}
-    virtual ~__base() {}
-    virtual __base* __clone() const = 0;
-    virtual void __clone(__base*) const = 0;
-    virtual void destroy() = 0;
-    virtual void destroy_deallocate() = 0;
-    virtual _Rp operator()() = 0;
-#ifndef _LIBCPP_NO_RTTI
-    virtual const void* target(const type_info&) const = 0;
-    virtual const std::type_info& target_type() const = 0;
-#endif  // _LIBCPP_NO_RTTI
-};
-
-template<class _Rp, class _A0>
-class __base<_Rp(_A0)>
-{
-    __base(const __base&);
-    __base& operator=(const __base&);
-public:
-    __base() {}
-    virtual ~__base() {}
-    virtual __base* __clone() const = 0;
-    virtual void __clone(__base*) const = 0;
-    virtual void destroy() = 0;
-    virtual void destroy_deallocate() = 0;
-    virtual _Rp operator()(_A0) = 0;
-#ifndef _LIBCPP_NO_RTTI
-    virtual const void* target(const type_info&) const = 0;
-    virtual const std::type_info& target_type() const = 0;
-#endif  // _LIBCPP_NO_RTTI
-};
-
-template<class _Rp, class _A0, class _A1>
-class __base<_Rp(_A0, _A1)>
-{
-    __base(const __base&);
-    __base& operator=(const __base&);
-public:
-    __base() {}
-    virtual ~__base() {}
-    virtual __base* __clone() const = 0;
-    virtual void __clone(__base*) const = 0;
-    virtual void destroy() = 0;
-    virtual void destroy_deallocate() = 0;
-    virtual _Rp operator()(_A0, _A1) = 0;
-#ifndef _LIBCPP_NO_RTTI
-    virtual const void* target(const type_info&) const = 0;
-    virtual const std::type_info& target_type() const = 0;
-#endif  // _LIBCPP_NO_RTTI
-};
-
-template<class _Rp, class _A0, class _A1, class _A2>
-class __base<_Rp(_A0, _A1, _A2)>
-{
-    __base(const __base&);
-    __base& operator=(const __base&);
-public:
-    __base() {}
-    virtual ~__base() {}
-    virtual __base* __clone() const = 0;
-    virtual void __clone(__base*) const = 0;
-    virtual void destroy() = 0;
-    virtual void destroy_deallocate() = 0;
-    virtual _Rp operator()(_A0, _A1, _A2) = 0;
-#ifndef _LIBCPP_NO_RTTI
-    virtual const void* target(const type_info&) const = 0;
-    virtual const std::type_info& target_type() const = 0;
-#endif  // _LIBCPP_NO_RTTI
-};
-
-template<class _FD, class _Alloc, class _FB> class __func;
-
-template<class _Fp, class _Alloc, class _Rp>
-class __func<_Fp, _Alloc, _Rp()>
-    : public  __base<_Rp()>
-{
-    __compressed_pair<_Fp, _Alloc> __f_;
-public:
-    explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
-    explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
-    virtual __base<_Rp()>* __clone() const;
-    virtual void __clone(__base<_Rp()>*) const;
-    virtual void destroy();
-    virtual void destroy_deallocate();
-    virtual _Rp operator()();
-#ifndef _LIBCPP_NO_RTTI
-    virtual const void* target(const type_info&) const;
-    virtual const std::type_info& target_type() const;
-#endif  // _LIBCPP_NO_RTTI
-};
-
-template<class _Fp, class _Alloc, class _Rp>
-__base<_Rp()>*
-__func<_Fp, _Alloc, _Rp()>::__clone() const
-{
-    typedef typename _Alloc::template rebind<__func>::other _Ap;
-    _Ap __a(__f_.second());
-    typedef __allocator_destructor<_Ap> _Dp;
-    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
-    return __hold.release();
-}
-
-template<class _Fp, class _Alloc, class _Rp>
-void
-__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const
-{
-    ::new (__p) __func(__f_.first(), __f_.second());
-}
-
-template<class _Fp, class _Alloc, class _Rp>
-void
-__func<_Fp, _Alloc, _Rp()>::destroy()
-{
-    __f_.~__compressed_pair<_Fp, _Alloc>();
-}
-
-template<class _Fp, class _Alloc, class _Rp>
-void
-__func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
-{
-    typedef typename _Alloc::template rebind<__func>::other _Ap;
-    _Ap __a(__f_.second());
-    __f_.~__compressed_pair<_Fp, _Alloc>();
-    __a.deallocate(this, 1);
-}
-
-template<class _Fp, class _Alloc, class _Rp>
-_Rp
-__func<_Fp, _Alloc, _Rp()>::operator()()
-{
-    return __invoke(__f_.first());
-}
-
-#ifndef _LIBCPP_NO_RTTI
-
-template<class _Fp, class _Alloc, class _Rp>
-const void*
-__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
-{
-    if (__ti == typeid(_Fp))
-        return &__f_.first();
-    return (const void*)0;
-}
-
-template<class _Fp, class _Alloc, class _Rp>
-const std::type_info&
-__func<_Fp, _Alloc, _Rp()>::target_type() const
-{
-    return typeid(_Fp);
-}
-
-#endif  // _LIBCPP_NO_RTTI
-
-template<class _Fp, class _Alloc, class _Rp, class _A0>
-class __func<_Fp, _Alloc, _Rp(_A0)>
-    : public  __base<_Rp(_A0)>
-{
-    __compressed_pair<_Fp, _Alloc> __f_;
-public:
-    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
-    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
-        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
-    virtual __base<_Rp(_A0)>* __clone() const;
-    virtual void __clone(__base<_Rp(_A0)>*) const;
-    virtual void destroy();
-    virtual void destroy_deallocate();
-    virtual _Rp operator()(_A0);
-#ifndef _LIBCPP_NO_RTTI
-    virtual const void* target(const type_info&) const;
-    virtual const std::type_info& target_type() const;
-#endif  // _LIBCPP_NO_RTTI
-};
-
-template<class _Fp, class _Alloc, class _Rp, class _A0>
-__base<_Rp(_A0)>*
-__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
-{
-    typedef typename _Alloc::template rebind<__func>::other _Ap;
-    _Ap __a(__f_.second());
-    typedef __allocator_destructor<_Ap> _Dp;
-    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
-    return __hold.release();
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0>
-void
-__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const
-{
-    ::new (__p) __func(__f_.first(), __f_.second());
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0>
-void
-__func<_Fp, _Alloc, _Rp(_A0)>::destroy()
-{
-    __f_.~__compressed_pair<_Fp, _Alloc>();
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0>
-void
-__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
-{
-    typedef typename _Alloc::template rebind<__func>::other _Ap;
-    _Ap __a(__f_.second());
-    __f_.~__compressed_pair<_Fp, _Alloc>();
-    __a.deallocate(this, 1);
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0>
-_Rp
-__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0)
-{
-    return __invoke(__f_.first(), __a0);
-}
-
-#ifndef _LIBCPP_NO_RTTI
-
-template<class _Fp, class _Alloc, class _Rp, class _A0>
-const void*
-__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const
-{
-    if (__ti == typeid(_Fp))
-        return &__f_.first();
-    return (const void*)0;
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0>
-const std::type_info&
-__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const
-{
-    return typeid(_Fp);
-}
-
-#endif  // _LIBCPP_NO_RTTI
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
-class __func<_Fp, _Alloc, _Rp(_A0, _A1)>
-    : public  __base<_Rp(_A0, _A1)>
-{
-    __compressed_pair<_Fp, _Alloc> __f_;
-public:
-    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
-    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
-        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
-    virtual __base<_Rp(_A0, _A1)>* __clone() const;
-    virtual void __clone(__base<_Rp(_A0, _A1)>*) const;
-    virtual void destroy();
-    virtual void destroy_deallocate();
-    virtual _Rp operator()(_A0, _A1);
-#ifndef _LIBCPP_NO_RTTI
-    virtual const void* target(const type_info&) const;
-    virtual const std::type_info& target_type() const;
-#endif  // _LIBCPP_NO_RTTI
-};
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
-__base<_Rp(_A0, _A1)>*
-__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
-{
-    typedef typename _Alloc::template rebind<__func>::other _Ap;
-    _Ap __a(__f_.second());
-    typedef __allocator_destructor<_Ap> _Dp;
-    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
-    return __hold.release();
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
-void
-__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const
-{
-    ::new (__p) __func(__f_.first(), __f_.second());
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
-void
-__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy()
-{
-    __f_.~__compressed_pair<_Fp, _Alloc>();
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
-void
-__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
-{
-    typedef typename _Alloc::template rebind<__func>::other _Ap;
-    _Ap __a(__f_.second());
-    __f_.~__compressed_pair<_Fp, _Alloc>();
-    __a.deallocate(this, 1);
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
-_Rp
-__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)
-{
-    return __invoke(__f_.first(), __a0, __a1);
-}
-
-#ifndef _LIBCPP_NO_RTTI
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
-const void*
-__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const
-{
-    if (__ti == typeid(_Fp))
-        return &__f_.first();
-    return (const void*)0;
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
-const std::type_info&
-__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const
-{
-    return typeid(_Fp);
-}
-
-#endif  // _LIBCPP_NO_RTTI
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
-class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>
-    : public  __base<_Rp(_A0, _A1, _A2)>
-{
-    __compressed_pair<_Fp, _Alloc> __f_;
-public:
-    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
-    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
-        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
-    virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const;
-    virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const;
-    virtual void destroy();
-    virtual void destroy_deallocate();
-    virtual _Rp operator()(_A0, _A1, _A2);
-#ifndef _LIBCPP_NO_RTTI
-    virtual const void* target(const type_info&) const;
-    virtual const std::type_info& target_type() const;
-#endif  // _LIBCPP_NO_RTTI
-};
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
-__base<_Rp(_A0, _A1, _A2)>*
-__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const
-{
-    typedef typename _Alloc::template rebind<__func>::other _Ap;
-    _Ap __a(__f_.second());
-    typedef __allocator_destructor<_Ap> _Dp;
-    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
-    return __hold.release();
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
-void
-__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const
-{
-    ::new (__p) __func(__f_.first(), __f_.second());
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
-void
-__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy()
-{
-    __f_.~__compressed_pair<_Fp, _Alloc>();
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
-void
-__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
-{
-    typedef typename _Alloc::template rebind<__func>::other _Ap;
-    _Ap __a(__f_.second());
-    __f_.~__compressed_pair<_Fp, _Alloc>();
-    __a.deallocate(this, 1);
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
-_Rp
-__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2)
-{
-    return __invoke(__f_.first(), __a0, __a1, __a2);
-}
-
-#ifndef _LIBCPP_NO_RTTI
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
-const void*
-__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const
-{
-    if (__ti == typeid(_Fp))
-        return &__f_.first();
-    return (const void*)0;
-}
-
-template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
-const std::type_info&
-__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const
-{
-    return typeid(_Fp);
-}
-
-#endif  // _LIBCPP_NO_RTTI
-
-}  // __function
-
-template<class _Rp>
-class _LIBCPP_TYPE_VIS_ONLY function<_Rp()>
-{
-    typedef __function::__base<_Rp()> __base;
-    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;
-
-    // 20.7.16.2.1, construct/copy/destroy:
-    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
-    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
-    function(const function&);
-    template<class _Fp>
-      function(_Fp,
-               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
-
-    template<class _Alloc>
-      _LIBCPP_INLINE_VISIBILITY
-      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
-    template<class _Alloc>
-      _LIBCPP_INLINE_VISIBILITY
-      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
-    template<class _Alloc>
-      function(allocator_arg_t, const _Alloc&, const function&);
-    template<class _Fp, class _Alloc>
-      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
-               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
-
-    function& operator=(const function&);
-    function& operator=(nullptr_t);
-    template<class _Fp>
-      typename enable_if
-      <
-        !is_integral<_Fp>::value,
-        function&
-      >::type
-      operator=(_Fp);
-
-    ~function();
-
-    // 20.7.16.2.2, function modifiers:
-    void swap(function&);
-    template<class _Fp, class _Alloc>
-      _LIBCPP_INLINE_VISIBILITY
-      void assign(_Fp __f, const _Alloc& __a)
-        {function(allocator_arg, __a, __f).swap(*this);}
-
-    // 20.7.16.2.3, function capacity:
-    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
-
-private:
-    // deleted overloads close possible hole in the type system
-    template<class _R2>
-      bool operator==(const function<_R2()>&) const;// = delete;
-    template<class _R2>
-      bool operator!=(const function<_R2()>&) const;// = delete;
-public:
-    // 20.7.16.2.4, function invocation:
-    _Rp operator()() const;
-
-#ifndef _LIBCPP_NO_RTTI
-    // 20.7.16.2.5, function target access:
-    const std::type_info& target_type() const;
-    template <typename _Tp> _Tp* target();
-    template <typename _Tp> const _Tp* target() const;
-#endif  // _LIBCPP_NO_RTTI
-};
-
-template<class _Rp>
-function<_Rp()>::function(const function& __f)
-{
-    if (__f.__f_ == 0)
-        __f_ = 0;
-    else if (__f.__f_ == (const __base*)&__f.__buf_)
-    {
-        __f_ = (__base*)&__buf_;
-        __f.__f_->__clone(__f_);
-    }
-    else
-        __f_ = __f.__f_->__clone();
-}
-
-template<class _Rp>
-template<class _Alloc>
-function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f)
-{
-    if (__f.__f_ == 0)
-        __f_ = 0;
-    else if (__f.__f_ == (const __base*)&__f.__buf_)
-    {
-        __f_ = (__base*)&__buf_;
-        __f.__f_->__clone(__f_);
-    }
-    else
-        __f_ = __f.__f_->__clone();
-}
-
-template<class _Rp>
-template <class _Fp>
-function<_Rp()>::function(_Fp __f,
-                                     typename enable_if<!is_integral<_Fp>::value>::type*)
-    : __f_(0)
-{
-    if (__not_null(__f))
-    {
-        typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;
-        if (sizeof(_FF) <= sizeof(__buf_))
-        {
-            __f_ = (__base*)&__buf_;
-            ::new (__f_) _FF(__f);
-        }
-        else
-        {
-            typedef allocator<_FF> _Ap;
-            _Ap __a;
-            typedef __allocator_destructor<_Ap> _Dp;
-            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
-            __f_ = __hold.release();
-        }
-    }
-}
-
-template<class _Rp>
-template <class _Fp, class _Alloc>
-function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
-                                     typename enable_if<!is_integral<_Fp>::value>::type*)
-    : __f_(0)
-{
-    typedef allocator_traits<_Alloc> __alloc_traits;
-    if (__not_null(__f))
-    {
-        typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;
-        if (sizeof(_FF) <= sizeof(__buf_))
-        {
-            __f_ = (__base*)&__buf_;
-            ::new (__f_) _FF(__f);
-        }
-        else
-        {
-            typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-                rebind_alloc<_FF>
-#else
-                rebind_alloc<_FF>::other
-#endif
-                                                         _Ap;
-            _Ap __a(__a0);
-            typedef __allocator_destructor<_Ap> _Dp;
-            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-            ::new (__hold.get()) _FF(__f, _Alloc(__a));
-            __f_ = __hold.release();
-        }
-    }
-}
-
-template<class _Rp>
-function<_Rp()>&
-function<_Rp()>::operator=(const function& __f)
-{
-    function(__f).swap(*this);
-    return *this;
-}
-
-template<class _Rp>
-function<_Rp()>&
-function<_Rp()>::operator=(nullptr_t)
-{
-    if (__f_ == (__base*)&__buf_)
-        __f_->destroy();
-    else if (__f_)
-        __f_->destroy_deallocate();
-    __f_ = 0;
-}
-
-template<class _Rp>
-template <class _Fp>
-typename enable_if
-<
-    !is_integral<_Fp>::value,
-    function<_Rp()>&
->::type
-function<_Rp()>::operator=(_Fp __f)
-{
-    function(_VSTD::move(__f)).swap(*this);
-    return *this;
-}
-
-template<class _Rp>
-function<_Rp()>::~function()
-{
-    if (__f_ == (__base*)&__buf_)
-        __f_->destroy();
-    else if (__f_)
-        __f_->destroy_deallocate();
-}
-
-template<class _Rp>
-void
-function<_Rp()>::swap(function& __f)
-{
-    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
-    {
-        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
-        __base* __t = (__base*)&__tempbuf;
-        __f_->__clone(__t);
-        __f_->destroy();
-        __f_ = 0;
-        __f.__f_->__clone((__base*)&__buf_);
-        __f.__f_->destroy();
-        __f.__f_ = 0;
-        __f_ = (__base*)&__buf_;
-        __t->__clone((__base*)&__f.__buf_);
-        __t->destroy();
-        __f.__f_ = (__base*)&__f.__buf_;
-    }
-    else if (__f_ == (__base*)&__buf_)
-    {
-        __f_->__clone((__base*)&__f.__buf_);
-        __f_->destroy();
-        __f_ = __f.__f_;
-        __f.__f_ = (__base*)&__f.__buf_;
-    }
-    else if (__f.__f_ == (__base*)&__f.__buf_)
-    {
-        __f.__f_->__clone((__base*)&__buf_);
-        __f.__f_->destroy();
-        __f.__f_ = __f_;
-        __f_ = (__base*)&__buf_;
-    }
-    else
-        _VSTD::swap(__f_, __f.__f_);
-}
-
-template<class _Rp>
-_Rp
-function<_Rp()>::operator()() const
-{
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (__f_ == 0)
-        throw bad_function_call();
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    return (*__f_)();
-}
-
-#ifndef _LIBCPP_NO_RTTI
-
-template<class _Rp>
-const std::type_info&
-function<_Rp()>::target_type() const
-{
-    if (__f_ == 0)
-        return typeid(void);
-    return __f_->target_type();
-}
-
-template<class _Rp>
-template <typename _Tp>
-_Tp*
-function<_Rp()>::target()
-{
-    if (__f_ == 0)
-        return (_Tp*)0;
-    return (_Tp*)__f_->target(typeid(_Tp));
-}
-
-template<class _Rp>
-template <typename _Tp>
-const _Tp*
-function<_Rp()>::target() const
-{
-    if (__f_ == 0)
-        return (const _Tp*)0;
-    return (const _Tp*)__f_->target(typeid(_Tp));
-}
-
-#endif  // _LIBCPP_NO_RTTI
-
-template<class _Rp, class _A0>
-class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0)>
-    : public unary_function<_A0, _Rp>
-{
-    typedef __function::__base<_Rp(_A0)> __base;
-    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;
-
-    // 20.7.16.2.1, construct/copy/destroy:
-    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
-    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
-    function(const function&);
-    template<class _Fp>
-      function(_Fp,
-               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
-
-    template<class _Alloc>
-      _LIBCPP_INLINE_VISIBILITY
-      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
-    template<class _Alloc>
-      _LIBCPP_INLINE_VISIBILITY
-      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
-    template<class _Alloc>
-      function(allocator_arg_t, const _Alloc&, const function&);
-    template<class _Fp, class _Alloc>
-      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
-               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
-
-    function& operator=(const function&);
-    function& operator=(nullptr_t);
-    template<class _Fp>
-      typename enable_if
-      <
-        !is_integral<_Fp>::value,
-        function&
-      >::type
-      operator=(_Fp);
-
-    ~function();
-
-    // 20.7.16.2.2, function modifiers:
-    void swap(function&);
-    template<class _Fp, class _Alloc>
-      _LIBCPP_INLINE_VISIBILITY
-      void assign(_Fp __f, const _Alloc& __a)
-        {function(allocator_arg, __a, __f).swap(*this);}
-
-    // 20.7.16.2.3, function capacity:
-    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
-
-private:
-    // deleted overloads close possible hole in the type system
-    template<class _R2, class _B0>
-      bool operator==(const function<_R2(_B0)>&) const;// = delete;
-    template<class _R2, class _B0>
-      bool operator!=(const function<_R2(_B0)>&) const;// = delete;
-public:
-    // 20.7.16.2.4, function invocation:
-    _Rp operator()(_A0) const;
-
-#ifndef _LIBCPP_NO_RTTI
-    // 20.7.16.2.5, function target access:
-    const std::type_info& target_type() const;
-    template <typename _Tp> _Tp* target();
-    template <typename _Tp> const _Tp* target() const;
-#endif  // _LIBCPP_NO_RTTI
-};
-
-template<class _Rp, class _A0>
-function<_Rp(_A0)>::function(const function& __f)
-{
-    if (__f.__f_ == 0)
-        __f_ = 0;
-    else if (__f.__f_ == (const __base*)&__f.__buf_)
-    {
-        __f_ = (__base*)&__buf_;
-        __f.__f_->__clone(__f_);
-    }
-    else
-        __f_ = __f.__f_->__clone();
-}
-
-template<class _Rp, class _A0>
-template<class _Alloc>
-function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)
-{
-    if (__f.__f_ == 0)
-        __f_ = 0;
-    else if (__f.__f_ == (const __base*)&__f.__buf_)
-    {
-        __f_ = (__base*)&__buf_;
-        __f.__f_->__clone(__f_);
-    }
-    else
-        __f_ = __f.__f_->__clone();
-}
-
-template<class _Rp, class _A0>
-template <class _Fp>
-function<_Rp(_A0)>::function(_Fp __f,
-                                     typename enable_if<!is_integral<_Fp>::value>::type*)
-    : __f_(0)
-{
-    if (__not_null(__f))
-    {
-        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;
-        if (sizeof(_FF) <= sizeof(__buf_))
-        {
-            __f_ = (__base*)&__buf_;
-            ::new (__f_) _FF(__f);
-        }
-        else
-        {
-            typedef allocator<_FF> _Ap;
-            _Ap __a;
-            typedef __allocator_destructor<_Ap> _Dp;
-            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
-            __f_ = __hold.release();
-        }
-    }
-}
-
-template<class _Rp, class _A0>
-template <class _Fp, class _Alloc>
-function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
-                                     typename enable_if<!is_integral<_Fp>::value>::type*)
-    : __f_(0)
-{
-    typedef allocator_traits<_Alloc> __alloc_traits;
-    if (__not_null(__f))
-    {
-        typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;
-        if (sizeof(_FF) <= sizeof(__buf_))
-        {
-            __f_ = (__base*)&__buf_;
-            ::new (__f_) _FF(__f);
-        }
-        else
-        {
-            typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-                rebind_alloc<_FF>
-#else
-                rebind_alloc<_FF>::other
-#endif
-                                                         _Ap;
-            _Ap __a(__a0);
-            typedef __allocator_destructor<_Ap> _Dp;
-            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-            ::new (__hold.get()) _FF(__f, _Alloc(__a));
-            __f_ = __hold.release();
-        }
-    }
-}
-
-template<class _Rp, class _A0>
-function<_Rp(_A0)>&
-function<_Rp(_A0)>::operator=(const function& __f)
-{
-    function(__f).swap(*this);
-    return *this;
-}
-
-template<class _Rp, class _A0>
-function<_Rp(_A0)>&
-function<_Rp(_A0)>::operator=(nullptr_t)
-{
-    if (__f_ == (__base*)&__buf_)
-        __f_->destroy();
-    else if (__f_)
-        __f_->destroy_deallocate();
-    __f_ = 0;
-}
-
-template<class _Rp, class _A0>
-template <class _Fp>
-typename enable_if
-<
-    !is_integral<_Fp>::value,
-    function<_Rp(_A0)>&
->::type
-function<_Rp(_A0)>::operator=(_Fp __f)
-{
-    function(_VSTD::move(__f)).swap(*this);
-    return *this;
-}
-
-template<class _Rp, class _A0>
-function<_Rp(_A0)>::~function()
-{
-    if (__f_ == (__base*)&__buf_)
-        __f_->destroy();
-    else if (__f_)
-        __f_->destroy_deallocate();
-}
-
-template<class _Rp, class _A0>
-void
-function<_Rp(_A0)>::swap(function& __f)
-{
-    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
-    {
-        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
-        __base* __t = (__base*)&__tempbuf;
-        __f_->__clone(__t);
-        __f_->destroy();
-        __f_ = 0;
-        __f.__f_->__clone((__base*)&__buf_);
-        __f.__f_->destroy();
-        __f.__f_ = 0;
-        __f_ = (__base*)&__buf_;
-        __t->__clone((__base*)&__f.__buf_);
-        __t->destroy();
-        __f.__f_ = (__base*)&__f.__buf_;
-    }
-    else if (__f_ == (__base*)&__buf_)
-    {
-        __f_->__clone((__base*)&__f.__buf_);
-        __f_->destroy();
-        __f_ = __f.__f_;
-        __f.__f_ = (__base*)&__f.__buf_;
-    }
-    else if (__f.__f_ == (__base*)&__f.__buf_)
-    {
-        __f.__f_->__clone((__base*)&__buf_);
-        __f.__f_->destroy();
-        __f.__f_ = __f_;
-        __f_ = (__base*)&__buf_;
-    }
-    else
-        _VSTD::swap(__f_, __f.__f_);
-}
-
-template<class _Rp, class _A0>
-_Rp
-function<_Rp(_A0)>::operator()(_A0 __a0) const
-{
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (__f_ == 0)
-        throw bad_function_call();
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    return (*__f_)(__a0);
-}
-
-#ifndef _LIBCPP_NO_RTTI
-
-template<class _Rp, class _A0>
-const std::type_info&
-function<_Rp(_A0)>::target_type() const
-{
-    if (__f_ == 0)
-        return typeid(void);
-    return __f_->target_type();
-}
-
-template<class _Rp, class _A0>
-template <typename _Tp>
-_Tp*
-function<_Rp(_A0)>::target()
-{
-    if (__f_ == 0)
-        return (_Tp*)0;
-    return (_Tp*)__f_->target(typeid(_Tp));
-}
-
-template<class _Rp, class _A0>
-template <typename _Tp>
-const _Tp*
-function<_Rp(_A0)>::target() const
-{
-    if (__f_ == 0)
-        return (const _Tp*)0;
-    return (const _Tp*)__f_->target(typeid(_Tp));
-}
-
-#endif  // _LIBCPP_NO_RTTI
-
-template<class _Rp, class _A0, class _A1>
-class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1)>
-    : public binary_function<_A0, _A1, _Rp>
-{
-    typedef __function::__base<_Rp(_A0, _A1)> __base;
-    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;
-
-    // 20.7.16.2.1, construct/copy/destroy:
-    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
-    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
-    function(const function&);
-    template<class _Fp>
-      function(_Fp,
-               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
-
-    template<class _Alloc>
-      _LIBCPP_INLINE_VISIBILITY
-      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
-    template<class _Alloc>
-      _LIBCPP_INLINE_VISIBILITY
-      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
-    template<class _Alloc>
-      function(allocator_arg_t, const _Alloc&, const function&);
-    template<class _Fp, class _Alloc>
-      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
-               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
-
-    function& operator=(const function&);
-    function& operator=(nullptr_t);
-    template<class _Fp>
-      typename enable_if
-      <
-        !is_integral<_Fp>::value,
-        function&
-      >::type
-      operator=(_Fp);
-
-    ~function();
-
-    // 20.7.16.2.2, function modifiers:
-    void swap(function&);
-    template<class _Fp, class _Alloc>
-      _LIBCPP_INLINE_VISIBILITY
-      void assign(_Fp __f, const _Alloc& __a)
-        {function(allocator_arg, __a, __f).swap(*this);}
-
-    // 20.7.16.2.3, function capacity:
-    operator bool() const {return __f_;}
-
-private:
-    // deleted overloads close possible hole in the type system
-    template<class _R2, class _B0, class _B1>
-      bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete;
-    template<class _R2, class _B0, class _B1>
-      bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete;
-public:
-    // 20.7.16.2.4, function invocation:
-    _Rp operator()(_A0, _A1) const;
-
-#ifndef _LIBCPP_NO_RTTI
-    // 20.7.16.2.5, function target access:
-    const std::type_info& target_type() const;
-    template <typename _Tp> _Tp* target();
-    template <typename _Tp> const _Tp* target() const;
-#endif  // _LIBCPP_NO_RTTI
-};
-
-template<class _Rp, class _A0, class _A1>
-function<_Rp(_A0, _A1)>::function(const function& __f)
-{
-    if (__f.__f_ == 0)
-        __f_ = 0;
-    else if (__f.__f_ == (const __base*)&__f.__buf_)
-    {
-        __f_ = (__base*)&__buf_;
-        __f.__f_->__clone(__f_);
-    }
-    else
-        __f_ = __f.__f_->__clone();
-}
-
-template<class _Rp, class _A0, class _A1>
-template<class _Alloc>
-function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)
-{
-    if (__f.__f_ == 0)
-        __f_ = 0;
-    else if (__f.__f_ == (const __base*)&__f.__buf_)
-    {
-        __f_ = (__base*)&__buf_;
-        __f.__f_->__clone(__f_);
-    }
-    else
-        __f_ = __f.__f_->__clone();
-}
-
-template<class _Rp, class _A0, class _A1>
-template <class _Fp>
-function<_Rp(_A0, _A1)>::function(_Fp __f,
-                                 typename enable_if<!is_integral<_Fp>::value>::type*)
-    : __f_(0)
-{
-    if (__not_null(__f))
-    {
-        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;
-        if (sizeof(_FF) <= sizeof(__buf_))
-        {
-            __f_ = (__base*)&__buf_;
-            ::new (__f_) _FF(__f);
-        }
-        else
-        {
-            typedef allocator<_FF> _Ap;
-            _Ap __a;
-            typedef __allocator_destructor<_Ap> _Dp;
-            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
-            __f_ = __hold.release();
-        }
-    }
-}
-
-template<class _Rp, class _A0, class _A1>
-template <class _Fp, class _Alloc>
-function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
-                                 typename enable_if<!is_integral<_Fp>::value>::type*)
-    : __f_(0)
-{
-    typedef allocator_traits<_Alloc> __alloc_traits;
-    if (__not_null(__f))
-    {
-        typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;
-        if (sizeof(_FF) <= sizeof(__buf_))
-        {
-            __f_ = (__base*)&__buf_;
-            ::new (__f_) _FF(__f);
-        }
-        else
-        {
-            typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-                rebind_alloc<_FF>
-#else
-                rebind_alloc<_FF>::other
-#endif
-                                                         _Ap;
-            _Ap __a(__a0);
-            typedef __allocator_destructor<_Ap> _Dp;
-            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-            ::new (__hold.get()) _FF(__f, _Alloc(__a));
-            __f_ = __hold.release();
-        }
-    }
-}
-
-template<class _Rp, class _A0, class _A1>
-function<_Rp(_A0, _A1)>&
-function<_Rp(_A0, _A1)>::operator=(const function& __f)
-{
-    function(__f).swap(*this);
-    return *this;
-}
-
-template<class _Rp, class _A0, class _A1>
-function<_Rp(_A0, _A1)>&
-function<_Rp(_A0, _A1)>::operator=(nullptr_t)
-{
-    if (__f_ == (__base*)&__buf_)
-        __f_->destroy();
-    else if (__f_)
-        __f_->destroy_deallocate();
-    __f_ = 0;
-}
-
-template<class _Rp, class _A0, class _A1>
-template <class _Fp>
-typename enable_if
-<
-    !is_integral<_Fp>::value,
-    function<_Rp(_A0, _A1)>&
->::type
-function<_Rp(_A0, _A1)>::operator=(_Fp __f)
-{
-    function(_VSTD::move(__f)).swap(*this);
-    return *this;
-}
-
-template<class _Rp, class _A0, class _A1>
-function<_Rp(_A0, _A1)>::~function()
-{
-    if (__f_ == (__base*)&__buf_)
-        __f_->destroy();
-    else if (__f_)
-        __f_->destroy_deallocate();
-}
-
-template<class _Rp, class _A0, class _A1>
-void
-function<_Rp(_A0, _A1)>::swap(function& __f)
-{
-    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
-    {
-        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
-        __base* __t = (__base*)&__tempbuf;
-        __f_->__clone(__t);
-        __f_->destroy();
-        __f_ = 0;
-        __f.__f_->__clone((__base*)&__buf_);
-        __f.__f_->destroy();
-        __f.__f_ = 0;
-        __f_ = (__base*)&__buf_;
-        __t->__clone((__base*)&__f.__buf_);
-        __t->destroy();
-        __f.__f_ = (__base*)&__f.__buf_;
-    }
-    else if (__f_ == (__base*)&__buf_)
-    {
-        __f_->__clone((__base*)&__f.__buf_);
-        __f_->destroy();
-        __f_ = __f.__f_;
-        __f.__f_ = (__base*)&__f.__buf_;
-    }
-    else if (__f.__f_ == (__base*)&__f.__buf_)
-    {
-        __f.__f_->__clone((__base*)&__buf_);
-        __f.__f_->destroy();
-        __f.__f_ = __f_;
-        __f_ = (__base*)&__buf_;
-    }
-    else
-        _VSTD::swap(__f_, __f.__f_);
-}
-
-template<class _Rp, class _A0, class _A1>
-_Rp
-function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const
-{
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (__f_ == 0)
-        throw bad_function_call();
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    return (*__f_)(__a0, __a1);
-}
-
-#ifndef _LIBCPP_NO_RTTI
-
-template<class _Rp, class _A0, class _A1>
-const std::type_info&
-function<_Rp(_A0, _A1)>::target_type() const
-{
-    if (__f_ == 0)
-        return typeid(void);
-    return __f_->target_type();
-}
-
-template<class _Rp, class _A0, class _A1>
-template <typename _Tp>
-_Tp*
-function<_Rp(_A0, _A1)>::target()
-{
-    if (__f_ == 0)
-        return (_Tp*)0;
-    return (_Tp*)__f_->target(typeid(_Tp));
-}
-
-template<class _Rp, class _A0, class _A1>
-template <typename _Tp>
-const _Tp*
-function<_Rp(_A0, _A1)>::target() const
-{
-    if (__f_ == 0)
-        return (const _Tp*)0;
-    return (const _Tp*)__f_->target(typeid(_Tp));
-}
-
-#endif  // _LIBCPP_NO_RTTI
-
-template<class _Rp, class _A0, class _A1, class _A2>
-class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1, _A2)>
-{
-    typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
-    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;
-
-    // 20.7.16.2.1, construct/copy/destroy:
-    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
-    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
-    function(const function&);
-    template<class _Fp>
-      function(_Fp,
-               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
-
-    template<class _Alloc>
-      _LIBCPP_INLINE_VISIBILITY
-      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
-    template<class _Alloc>
-      _LIBCPP_INLINE_VISIBILITY
-      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
-    template<class _Alloc>
-      function(allocator_arg_t, const _Alloc&, const function&);
-    template<class _Fp, class _Alloc>
-      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
-               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
-
-    function& operator=(const function&);
-    function& operator=(nullptr_t);
-    template<class _Fp>
-      typename enable_if
-      <
-        !is_integral<_Fp>::value,
-        function&
-      >::type
-      operator=(_Fp);
-
-    ~function();
-
-    // 20.7.16.2.2, function modifiers:
-    void swap(function&);
-    template<class _Fp, class _Alloc>
-      _LIBCPP_INLINE_VISIBILITY
-      void assign(_Fp __f, const _Alloc& __a)
-        {function(allocator_arg, __a, __f).swap(*this);}
-
-    // 20.7.16.2.3, function capacity:
-    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
-
-private:
-    // deleted overloads close possible hole in the type system
-    template<class _R2, class _B0, class _B1, class _B2>
-      bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
-    template<class _R2, class _B0, class _B1, class _B2>
-      bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
-public:
-    // 20.7.16.2.4, function invocation:
-    _Rp operator()(_A0, _A1, _A2) const;
-
-#ifndef _LIBCPP_NO_RTTI
-    // 20.7.16.2.5, function target access:
-    const std::type_info& target_type() const;
-    template <typename _Tp> _Tp* target();
-    template <typename _Tp> const _Tp* target() const;
-#endif  // _LIBCPP_NO_RTTI
-};
-
-template<class _Rp, class _A0, class _A1, class _A2>
-function<_Rp(_A0, _A1, _A2)>::function(const function& __f)
-{
-    if (__f.__f_ == 0)
-        __f_ = 0;
-    else if (__f.__f_ == (const __base*)&__f.__buf_)
-    {
-        __f_ = (__base*)&__buf_;
-        __f.__f_->__clone(__f_);
-    }
-    else
-        __f_ = __f.__f_->__clone();
-}
-
-template<class _Rp, class _A0, class _A1, class _A2>
-template<class _Alloc>
-function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,
-                                      const function& __f)
-{
-    if (__f.__f_ == 0)
-        __f_ = 0;
-    else if (__f.__f_ == (const __base*)&__f.__buf_)
-    {
-        __f_ = (__base*)&__buf_;
-        __f.__f_->__clone(__f_);
-    }
-    else
-        __f_ = __f.__f_->__clone();
-}
-
-template<class _Rp, class _A0, class _A1, class _A2>
-template <class _Fp>
-function<_Rp(_A0, _A1, _A2)>::function(_Fp __f,
-                                     typename enable_if<!is_integral<_Fp>::value>::type*)
-    : __f_(0)
-{
-    if (__not_null(__f))
-    {
-        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;
-        if (sizeof(_FF) <= sizeof(__buf_))
-        {
-            __f_ = (__base*)&__buf_;
-            ::new (__f_) _FF(__f);
-        }
-        else
-        {
-            typedef allocator<_FF> _Ap;
-            _Ap __a;
-            typedef __allocator_destructor<_Ap> _Dp;
-            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
-            __f_ = __hold.release();
-        }
-    }
-}
-
-template<class _Rp, class _A0, class _A1, class _A2>
-template <class _Fp, class _Alloc>
-function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
-                                     typename enable_if<!is_integral<_Fp>::value>::type*)
-    : __f_(0)
-{
-    typedef allocator_traits<_Alloc> __alloc_traits;
-    if (__not_null(__f))
-    {
-        typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;
-        if (sizeof(_FF) <= sizeof(__buf_))
-        {
-            __f_ = (__base*)&__buf_;
-            ::new (__f_) _FF(__f);
-        }
-        else
-        {
-            typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-                rebind_alloc<_FF>
-#else
-                rebind_alloc<_FF>::other
-#endif
-                                                         _Ap;
-            _Ap __a(__a0);
-            typedef __allocator_destructor<_Ap> _Dp;
-            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-            ::new (__hold.get()) _FF(__f, _Alloc(__a));
-            __f_ = __hold.release();
-        }
-    }
-}
-
-template<class _Rp, class _A0, class _A1, class _A2>
-function<_Rp(_A0, _A1, _A2)>&
-function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)
-{
-    function(__f).swap(*this);
-    return *this;
-}
-
-template<class _Rp, class _A0, class _A1, class _A2>
-function<_Rp(_A0, _A1, _A2)>&
-function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)
-{
-    if (__f_ == (__base*)&__buf_)
-        __f_->destroy();
-    else if (__f_)
-        __f_->destroy_deallocate();
-    __f_ = 0;
-}
-
-template<class _Rp, class _A0, class _A1, class _A2>
-template <class _Fp>
-typename enable_if
-<
-    !is_integral<_Fp>::value,
-    function<_Rp(_A0, _A1, _A2)>&
->::type
-function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f)
-{
-    function(_VSTD::move(__f)).swap(*this);
-    return *this;
-}
-
-template<class _Rp, class _A0, class _A1, class _A2>
-function<_Rp(_A0, _A1, _A2)>::~function()
-{
-    if (__f_ == (__base*)&__buf_)
-        __f_->destroy();
-    else if (__f_)
-        __f_->destroy_deallocate();
-}
-
-template<class _Rp, class _A0, class _A1, class _A2>
-void
-function<_Rp(_A0, _A1, _A2)>::swap(function& __f)
-{
-    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
-    {
-        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
-        __base* __t = (__base*)&__tempbuf;
-        __f_->__clone(__t);
-        __f_->destroy();
-        __f_ = 0;
-        __f.__f_->__clone((__base*)&__buf_);
-        __f.__f_->destroy();
-        __f.__f_ = 0;
-        __f_ = (__base*)&__buf_;
-        __t->__clone((__base*)&__f.__buf_);
-        __t->destroy();
-        __f.__f_ = (__base*)&__f.__buf_;
-    }
-    else if (__f_ == (__base*)&__buf_)
-    {
-        __f_->__clone((__base*)&__f.__buf_);
-        __f_->destroy();
-        __f_ = __f.__f_;
-        __f.__f_ = (__base*)&__f.__buf_;
-    }
-    else if (__f.__f_ == (__base*)&__f.__buf_)
-    {
-        __f.__f_->__clone((__base*)&__buf_);
-        __f.__f_->destroy();
-        __f.__f_ = __f_;
-        __f_ = (__base*)&__buf_;
-    }
-    else
-        _VSTD::swap(__f_, __f.__f_);
-}
-
-template<class _Rp, class _A0, class _A1, class _A2>
-_Rp
-function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const
-{
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (__f_ == 0)
-        throw bad_function_call();
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    return (*__f_)(__a0, __a1, __a2);
-}
-
-#ifndef _LIBCPP_NO_RTTI
-
-template<class _Rp, class _A0, class _A1, class _A2>
-const std::type_info&
-function<_Rp(_A0, _A1, _A2)>::target_type() const
-{
-    if (__f_ == 0)
-        return typeid(void);
-    return __f_->target_type();
-}
-
-template<class _Rp, class _A0, class _A1, class _A2>
-template <typename _Tp>
-_Tp*
-function<_Rp(_A0, _A1, _A2)>::target()
-{
-    if (__f_ == 0)
-        return (_Tp*)0;
-    return (_Tp*)__f_->target(typeid(_Tp));
-}
-
-template<class _Rp, class _A0, class _A1, class _A2>
-template <typename _Tp>
-const _Tp*
-function<_Rp(_A0, _A1, _A2)>::target() const
-{
-    if (__f_ == 0)
-        return (const _Tp*)0;
-    return (const _Tp*)__f_->target(typeid(_Tp));
-}
-
-#endif  // _LIBCPP_NO_RTTI
-
-template <class _Fp>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator==(const function<_Fp>& __f, nullptr_t) {return !__f;}
-
-template <class _Fp>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator==(nullptr_t, const function<_Fp>& __f) {return !__f;}
-
-template <class _Fp>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;}
-
-template <class _Fp>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;}
-
-template <class _Fp>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-swap(function<_Fp>& __x, function<_Fp>& __y)
-{return __x.swap(__y);}
-
-template<class _Tp> struct __is_bind_expression : public false_type {};
-template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_bind_expression
-    : public __is_bind_expression<typename remove_cv<_Tp>::type> {};
-
-template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {};
-template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_placeholder
-    : public __is_placeholder<typename remove_cv<_Tp>::type> {};
-
-namespace placeholders
-{
-
-template <int _Np> struct __ph {};
-
-extern __ph<1>   _1;
-extern __ph<2>   _2;
-extern __ph<3>   _3;
-extern __ph<4>   _4;
-extern __ph<5>   _5;
-extern __ph<6>   _6;
-extern __ph<7>   _7;
-extern __ph<8>   _8;
-extern __ph<9>   _9;
-extern __ph<10> _10;
-
-}  // placeholders
-
-template<int _Np>
-struct __is_placeholder<placeholders::__ph<_Np> >
-    : public integral_constant<int, _Np> {};
-
-template <class _Tp, class _Uj>
-inline _LIBCPP_INLINE_VISIBILITY
-_Tp&
-__mu(reference_wrapper<_Tp> __t, _Uj&)
-{
-    return __t.get();
-}
-/*
-template <bool _IsBindExpr, class _Ti, class ..._Uj>
-struct __mu_return1 {};
-
-template <class _Ti, class ..._Uj>
-struct __mu_return1<true, _Ti, _Uj...>
-{
-    typedef typename result_of<_Ti(_Uj...)>::type type;
-};
-
-template <class _Ti, class ..._Uj, size_t ..._Indx>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __mu_return1<true, _Ti, _Uj...>::type
-__mu_expand(_Ti& __ti, tuple<_Uj...>&& __uj, __tuple_indices<_Indx...>)
-{
-    __ti(_VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj))...);
-}
-
-template <class _Ti, class ..._Uj>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_bind_expression<_Ti>::value,
-    typename __mu_return1<is_bind_expression<_Ti>::value, _Ti, _Uj...>::type
->::type
-__mu(_Ti& __ti, tuple<_Uj...>& __uj)
-{
-    typedef typename __make_tuple_indices<sizeof...(_Uj)>::type __indices;
-    return  __mu_expand(__ti, __uj, __indices());
-}
-
-template <bool IsPh, class _Ti, class _Uj>
-struct __mu_return2 {};
-
-template <class _Ti, class _Uj>
-struct __mu_return2<true, _Ti, _Uj>
-{
-    typedef typename tuple_element<is_placeholder<_Ti>::value - 1, _Uj>::type type;
-};
-
-template <class _Ti, class _Uj>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    0 < is_placeholder<_Ti>::value,
-    typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type
->::type
-__mu(_Ti&, _Uj& __uj)
-{
-    const size_t _Indx = is_placeholder<_Ti>::value - 1;
-    // compiler bug workaround
-    typename tuple_element<_Indx, _Uj>::type __t = _VSTD::get<_Indx>(__uj);
-    return __t;
-//    return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj));
-}
-
-template <class _Ti, class _Uj>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_bind_expression<_Ti>::value &&
-    is_placeholder<_Ti>::value == 0 &&
-    !__is_reference_wrapper<_Ti>::value,
-    _Ti&
->::type
-__mu(_Ti& __ti, _Uj& __uj)
-{
-    return __ti;
-}
-
-template <class _Ti, bool IsBindEx, bool IsPh, class _TupleUj>
-struct ____mu_return;
-
-template <class _Ti, class ..._Uj>
-struct ____mu_return<_Ti, true, false, tuple<_Uj...> >
-{
-    typedef typename result_of<_Ti(_Uj...)>::type type;
-};
-
-template <class _Ti, class _TupleUj>
-struct ____mu_return<_Ti, false, true, _TupleUj>
-{
-    typedef typename tuple_element<is_placeholder<_Ti>::value - 1,
-                                   _TupleUj>::type&& type;
-};
-
-template <class _Ti, class _TupleUj>
-struct ____mu_return<_Ti, false, false, _TupleUj>
-{
-    typedef _Ti& type;
-};
-
-template <class _Ti, class _TupleUj>
-struct __mu_return
-    : public ____mu_return<_Ti,
-                           is_bind_expression<_Ti>::value,
-                           0 < is_placeholder<_Ti>::value,
-                           _TupleUj>
-{
-};
-
-template <class _Ti, class _TupleUj>
-struct __mu_return<reference_wrapper<_Ti>, _TupleUj>
-{
-    typedef _Ti& type;
-};
-
-template <class _Fp, class _BoundArgs, class _TupleUj>
-struct __bind_return;
-
-template <class _Fp, class ..._BoundArgs, class _TupleUj>
-struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>
-{
-    typedef typename __ref_return
-    <
-        _Fp&,
-        typename __mu_return
-        <
-            _BoundArgs,
-            _TupleUj
-        >::type...
-    >::type type;
-};
-
-template <class _Fp, class ..._BoundArgs, class _TupleUj>
-struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj>
-{
-    typedef typename __ref_return
-    <
-        _Fp&,
-        typename __mu_return
-        <
-            const _BoundArgs,
-            _TupleUj
-        >::type...
-    >::type type;
-};
-
-template <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __bind_return<_Fp, _BoundArgs, _Args>::type
-__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
-                _Args&& __args)
-{
-    return __invoke(__f, __mu(_VSTD::get<_Indx>(__bound_args), __args)...);
-}
-
-template<class _Fp, class ..._BoundArgs>
-class __bind
-{
-    _Fp __f_;
-    tuple<_BoundArgs...> __bound_args_;
-
-    typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices;
-public:
-    template <class _Gp, class ..._BA>
-      explicit __bind(_Gp&& __f, _BA&& ...__bound_args)
-        : __f_(_VSTD::forward<_Gp>(__f)),
-          __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {}
-
-    template <class ..._Args>
-        typename __bind_return<_Fp, tuple<_BoundArgs...>, tuple<_Args&&...> >::type
-        operator()(_Args&& ...__args)
-        {
-            // compiler bug workaround
-            return __apply_functor(__f_, __bound_args_, __indices(),
-                                  tuple<_Args&&...>(__args...));
-        }
-
-    template <class ..._Args>
-        typename __bind_return<_Fp, tuple<_BoundArgs...>, tuple<_Args&&...> >::type
-        operator()(_Args&& ...__args) const
-        {
-            return __apply_functor(__f_, __bound_args_, __indices(),
-                                   tuple<_Args&&...>(__args...));
-        }
-};
-
-template<class _Fp, class ..._BoundArgs>
-struct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {};
-
-template<class _Rp, class _Fp, class ..._BoundArgs>
-class __bind_r
-    : public __bind<_Fp, _BoundArgs...>
-{
-    typedef __bind<_Fp, _BoundArgs...> base;
-public:
-    typedef _Rp result_type;
-
-    template <class _Gp, class ..._BA>
-      explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args)
-        : base(_VSTD::forward<_Gp>(__f),
-               _VSTD::forward<_BA>(__bound_args)...) {}
-
-    template <class ..._Args>
-        result_type
-        operator()(_Args&& ...__args)
-        {
-            return base::operator()(_VSTD::forward<_Args>(__args)...);
-        }
-
-    template <class ..._Args>
-        result_type
-        operator()(_Args&& ...__args) const
-        {
-            return base::operator()(_VSTD::forward<_Args>(__args)...);
-        }
-};
-
-template<class _Rp, class _Fp, class ..._BoundArgs>
-struct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};
-
-template<class _Fp, class ..._BoundArgs>
-inline _LIBCPP_INLINE_VISIBILITY
-__bind<typename decay<_Fp>::type, typename decay<_BoundArgs>::type...>
-bind(_Fp&& __f, _BoundArgs&&... __bound_args)
-{
-    typedef __bind<typename decay<_Fp>::type, typename decay<_BoundArgs>::type...> type;
-    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
-}
-
-template<class _Rp, class _Fp, class ..._BoundArgs>
-inline _LIBCPP_INLINE_VISIBILITY
-__bind_r<_Rp, typename decay<_Fp>::type, typename decay<_BoundArgs>::type...>
-bind(_Fp&& __f, _BoundArgs&&... __bound_args)
-{
-    typedef __bind_r<_Rp, typename decay<_Fp>::type, typename decay<_BoundArgs>::type...> type;
-    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
-}
-*/
-
-#endif  // _LIBCPP_FUNCTIONAL_03
diff --git a/include/__functional_base b/include/__functional_base
index 6766793..ccc3f3a 100644
--- a/include/__functional_base
+++ b/include/__functional_base
@@ -1,10 +1,9 @@
 // -*- 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.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,604 +11,22 @@
 #define _LIBCPP_FUNCTIONAL_BASE
 
 #include <__config>
-#include <type_traits>
-#include <typeinfo>
+#include <__functional/binary_function.h>
+#include <__functional/invoke.h>
+#include <__functional/operations.h>
+#include <__functional/reference_wrapper.h>
+#include <__functional/unary_function.h>
+#include <__functional/weak_result_type.h>
+#include <__memory/allocator_arg_t.h>
+#include <__memory/uses_allocator.h>
 #include <exception>
 #include <new>
+#include <type_traits>
+#include <typeinfo>
+#include <utility>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
 
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Arg, class _Result>
-struct _LIBCPP_TYPE_VIS_ONLY unary_function
-{
-    typedef _Arg    argument_type;
-    typedef _Result result_type;
-};
-
-template <class _Arg1, class _Arg2, class _Result>
-struct _LIBCPP_TYPE_VIS_ONLY binary_function
-{
-    typedef _Arg1   first_argument_type;
-    typedef _Arg2   second_argument_type;
-    typedef _Result result_type;
-};
-
-template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash;
-
-template <class _Tp>
-struct __has_result_type
-{
-private:
-    struct __two {char __lx; char __lxx;};
-    template <class _Up> static __two __test(...);
-    template <class _Up> static char __test(typename _Up::result_type* = 0);
-public:
-    static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp = void>
-#else
-template <class _Tp>
-#endif
-struct _LIBCPP_TYPE_VIS_ONLY less : binary_function<_Tp, _Tp, bool>
-{
-    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 
-    bool operator()(const _Tp& __x, const _Tp& __y) const
-        {return __x < __y;}
-};
-
-#if _LIBCPP_STD_VER > 11
-template <>
-struct _LIBCPP_TYPE_VIS_ONLY less<void>
-{
-    template <class _T1, class _T2> 
-    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
-    auto operator()(_T1&& __t, _T2&& __u) const
-        { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); }
-    typedef void is_transparent;
-};
-#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
-
-#ifdef _LIBCPP_HAS_NO_VARIADICS
-
-#include <__functional_base_03>
-
-#else  // _LIBCPP_HAS_NO_VARIADICS
-
-// __weak_result_type
-
-template <class _Tp>
-struct __derives_from_unary_function
-{
-private:
-    struct __two {char __lx; char __lxx;};
-    static __two __test(...);
-    template <class _Ap, class _Rp>
-        static unary_function<_Ap, _Rp>
-        __test(const volatile unary_function<_Ap, _Rp>*);
-public:
-    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
-    typedef decltype(__test((_Tp*)0)) type;
-};
-
-template <class _Tp>
-struct __derives_from_binary_function
-{
-private:
-    struct __two {char __lx; char __lxx;};
-    static __two __test(...);
-    template <class _A1, class _A2, class _Rp>
-        static binary_function<_A1, _A2, _Rp>
-        __test(const volatile binary_function<_A1, _A2, _Rp>*);
-public:
-    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
-    typedef decltype(__test((_Tp*)0)) type;
-};
-
-template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
-struct __maybe_derive_from_unary_function  // bool is true
-    : public __derives_from_unary_function<_Tp>::type
-{
-};
-
-template <class _Tp>
-struct __maybe_derive_from_unary_function<_Tp, false>
-{
-};
-
-template <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
-struct __maybe_derive_from_binary_function  // bool is true
-    : public __derives_from_binary_function<_Tp>::type
-{
-};
-
-template <class _Tp>
-struct __maybe_derive_from_binary_function<_Tp, false>
-{
-};
-
-template <class _Tp, bool = __has_result_type<_Tp>::value>
-struct __weak_result_type_imp // bool is true
-    : public __maybe_derive_from_unary_function<_Tp>,
-      public __maybe_derive_from_binary_function<_Tp>
-{
-    typedef typename _Tp::result_type result_type;
-};
-
-template <class _Tp>
-struct __weak_result_type_imp<_Tp, false>
-    : public __maybe_derive_from_unary_function<_Tp>,
-      public __maybe_derive_from_binary_function<_Tp>
-{
-};
-
-template <class _Tp>
-struct __weak_result_type
-    : public __weak_result_type_imp<_Tp>
-{
-};
-
-// 0 argument case
-
-template <class _Rp>
-struct __weak_result_type<_Rp ()>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp>
-struct __weak_result_type<_Rp (&)()>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp>
-struct __weak_result_type<_Rp (*)()>
-{
-    typedef _Rp result_type;
-};
-
-// 1 argument case
-
-template <class _Rp, class _A1>
-struct __weak_result_type<_Rp (_A1)>
-    : public unary_function<_A1, _Rp>
-{
-};
-
-template <class _Rp, class _A1>
-struct __weak_result_type<_Rp (&)(_A1)>
-    : public unary_function<_A1, _Rp>
-{
-};
-
-template <class _Rp, class _A1>
-struct __weak_result_type<_Rp (*)(_A1)>
-    : public unary_function<_A1, _Rp>
-{
-};
-
-template <class _Rp, class _Cp>
-struct __weak_result_type<_Rp (_Cp::*)()>
-    : public unary_function<_Cp*, _Rp>
-{
-};
-
-template <class _Rp, class _Cp>
-struct __weak_result_type<_Rp (_Cp::*)() const>
-    : public unary_function<const _Cp*, _Rp>
-{
-};
-
-template <class _Rp, class _Cp>
-struct __weak_result_type<_Rp (_Cp::*)() volatile>
-    : public unary_function<volatile _Cp*, _Rp>
-{
-};
-
-template <class _Rp, class _Cp>
-struct __weak_result_type<_Rp (_Cp::*)() const volatile>
-    : public unary_function<const volatile _Cp*, _Rp>
-{
-};
-
-// 2 argument case
-
-template <class _Rp, class _A1, class _A2>
-struct __weak_result_type<_Rp (_A1, _A2)>
-    : public binary_function<_A1, _A2, _Rp>
-{
-};
-
-template <class _Rp, class _A1, class _A2>
-struct __weak_result_type<_Rp (*)(_A1, _A2)>
-    : public binary_function<_A1, _A2, _Rp>
-{
-};
-
-template <class _Rp, class _A1, class _A2>
-struct __weak_result_type<_Rp (&)(_A1, _A2)>
-    : public binary_function<_A1, _A2, _Rp>
-{
-};
-
-template <class _Rp, class _Cp, class _A1>
-struct __weak_result_type<_Rp (_Cp::*)(_A1)>
-    : public binary_function<_Cp*, _A1, _Rp>
-{
-};
-
-template <class _Rp, class _Cp, class _A1>
-struct __weak_result_type<_Rp (_Cp::*)(_A1) const>
-    : public binary_function<const _Cp*, _A1, _Rp>
-{
-};
-
-template <class _Rp, class _Cp, class _A1>
-struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile>
-    : public binary_function<volatile _Cp*, _A1, _Rp>
-{
-};
-
-template <class _Rp, class _Cp, class _A1>
-struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile>
-    : public binary_function<const volatile _Cp*, _A1, _Rp>
-{
-};
-
-// 3 or more arguments
-
-template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
-struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
-struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
-struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
-struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
-struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
-struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
-struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>
-{
-    typedef _Rp result_type;
-};
-
-// __invoke
-
-// 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;
-};
-
-template <class _Tp>
-class _LIBCPP_TYPE_VIS_ONLY reference_wrapper
-    : public __weak_result_type<_Tp>
-{
-public:
-    // types
-    typedef _Tp type;
-private:
-    type* __f_;
-
-public:
-    // construct/copy/destroy
-    _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT
-        : __f_(_VSTD::addressof(__f)) {}
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
-#endif
-
-    // access
-    _LIBCPP_INLINE_VISIBILITY operator type&    () const _NOEXCEPT {return *__f_;}
-    _LIBCPP_INLINE_VISIBILITY          type& get() const _NOEXCEPT {return *__f_;}
-
-    // invoke
-    template <class... _ArgTypes>
-       _LIBCPP_INLINE_VISIBILITY
-       typename __invoke_of<type&, _ArgTypes...>::type
-          operator() (_ArgTypes&&... __args) const
-          {
-              return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
-          }
-};
-
-template <class _Tp> struct __is_reference_wrapper_impl : public false_type {};
-template <class _Tp> struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {};
-template <class _Tp> struct __is_reference_wrapper
-    : public __is_reference_wrapper_impl<typename remove_cv<_Tp>::type> {};
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-reference_wrapper<_Tp>
-ref(_Tp& __t) _NOEXCEPT
-{
-    return reference_wrapper<_Tp>(__t);
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-reference_wrapper<_Tp>
-ref(reference_wrapper<_Tp> __t) _NOEXCEPT
-{
-    return ref(__t.get());
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-reference_wrapper<const _Tp>
-cref(const _Tp& __t) _NOEXCEPT
-{
-    return reference_wrapper<const _Tp>(__t);
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-reference_wrapper<const _Tp>
-cref(reference_wrapper<_Tp> __t) _NOEXCEPT
-{
-    return cref(__t.get());
-}
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
-
-template <class _Tp> void ref(const _Tp&&) = delete;
-template <class _Tp> void cref(const _Tp&&) = delete;
-
-#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
-
-template <class _Tp> void ref(const _Tp&&);// = delete;
-template <class _Tp> void cref(const _Tp&&);// = delete;
-
-#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
-
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-#endif  // _LIBCPP_HAS_NO_VARIADICS
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp1, class _Tp2 = void>
-struct __is_transparent
-{
-private:
-    struct __two {char __lx; char __lxx;};
-    template <class _Up> static __two __test(...);
-    template <class _Up> static char __test(typename _Up::is_transparent* = 0);
-public:
-    static const bool value = sizeof(__test<_Tp1>(0)) == 1;
-};
-#endif
-
-// allocator_arg_t
-
-struct _LIBCPP_TYPE_VIS_ONLY allocator_arg_t { };
-
-#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY)
-extern const allocator_arg_t allocator_arg;
-#else
-constexpr allocator_arg_t allocator_arg = allocator_arg_t();
-#endif
-
-// uses_allocator
-
-template <class _Tp>
-struct __has_allocator_type
-{
-private:
-    struct __two {char __lx; char __lxx;};
-    template <class _Up> static __two __test(...);
-    template <class _Up> static char __test(typename _Up::allocator_type* = 0);
-public:
-    static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
-
-template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
-struct __uses_allocator
-    : public integral_constant<bool,
-        is_convertible<_Alloc, typename _Tp::allocator_type>::value>
-{
-};
-
-template <class _Tp, class _Alloc>
-struct __uses_allocator<_Tp, _Alloc, false>
-    : public false_type
-{
-};
-
-template <class _Tp, class _Alloc>
-struct _LIBCPP_TYPE_VIS_ONLY uses_allocator
-    : public __uses_allocator<_Tp, _Alloc>
-{
-};
-
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-
-// allocator construction
-
-template <class _Tp, class _Alloc, class ..._Args>
-struct __uses_alloc_ctor_imp
-{
-    static const bool __ua = uses_allocator<_Tp, _Alloc>::value;
-    static const bool __ic =
-        is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
-    static const int value = __ua ? 2 - __ic : 0;
-};
-
-template <class _Tp, class _Alloc, class ..._Args>
-struct __uses_alloc_ctor
-    : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
-    {};
-
-template <class _Tp, class _Allocator, class... _Args>
-inline _LIBCPP_INLINE_VISIBILITY
-void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args )
-{
-    new (__storage) _Tp (_VSTD::forward<_Args>(__args)...);
-}
-
-template <class _Tp, class _Allocator, class... _Args>
-inline _LIBCPP_INLINE_VISIBILITY
-void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
-{
-    new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
-}
-
-template <class _Tp, class _Allocator, class... _Args>
-inline _LIBCPP_INLINE_VISIBILITY
-void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
-{
-    new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
-}
-
-template <class _Tp, class _Allocator, class... _Args>
-inline _LIBCPP_INLINE_VISIBILITY
-void __user_alloc_construct (_Tp *__storage, const _Allocator &__a, _Args &&... __args)
-{ 
-    __user_alloc_construct_impl( 
-             __uses_alloc_ctor<_Tp, _Allocator>(), 
-             __storage, __a, _VSTD::forward<_Args>(__args)...
-        );
-}
-#endif  // _LIBCPP_HAS_NO_VARIADICS
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif  // _LIBCPP_FUNCTIONAL_BASE
+#endif // _LIBCPP_FUNCTIONAL_BASE
diff --git a/include/__functional_base_03 b/include/__functional_base_03
deleted file mode 100644
index 22c06ad..0000000
--- a/include/__functional_base_03
+++ /dev/null
@@ -1,1087 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP_FUNCTIONAL_BASE_03
-#define _LIBCPP_FUNCTIONAL_BASE_03
-
-// manual variadic expansion for <functional>
-
-// __weak_result_type
-
-template <class _Tp>
-struct __derives_from_unary_function
-{
-private:
-    struct __two {char __lx; char __lxx;};
-    static __two __test(...);
-    template <class _Ap, class _Rp>
-        static unary_function<_Ap, _Rp>
-        __test(const volatile unary_function<_Ap, _Rp>*);
-public:
-    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
-    typedef decltype(__test((_Tp*)0)) type;
-};
-
-template <class _Tp>
-struct __derives_from_binary_function
-{
-private:
-    struct __two {char __lx; char __lxx;};
-    static __two __test(...);
-    template <class _A1, class _A2, class _Rp>
-        static binary_function<_A1, _A2, _Rp>
-        __test(const volatile binary_function<_A1, _A2, _Rp>*);
-public:
-    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
-    typedef decltype(__test((_Tp*)0)) type;
-};
-
-template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
-struct __maybe_derive_from_unary_function  // bool is true
-    : public __derives_from_unary_function<_Tp>::type
-{
-};
-
-template <class _Tp>
-struct __maybe_derive_from_unary_function<_Tp, false>
-{
-};
-
-template <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
-struct __maybe_derive_from_binary_function  // bool is true
-    : public __derives_from_binary_function<_Tp>::type
-{
-};
-
-template <class _Tp>
-struct __maybe_derive_from_binary_function<_Tp, false>
-{
-};
-
-template <class _Tp, bool = __has_result_type<_Tp>::value>
-struct __weak_result_type_imp // bool is true
-    : public __maybe_derive_from_unary_function<_Tp>,
-      public __maybe_derive_from_binary_function<_Tp>
-{
-    typedef typename _Tp::result_type result_type;
-};
-
-template <class _Tp>
-struct __weak_result_type_imp<_Tp, false>
-    : public __maybe_derive_from_unary_function<_Tp>,
-      public __maybe_derive_from_binary_function<_Tp>
-{
-};
-
-template <class _Tp>
-struct __weak_result_type
-    : public __weak_result_type_imp<typename remove_reference<_Tp>::type>
-{
-};
-
-// 0 argument case
-
-template <class _Rp>
-struct __weak_result_type<_Rp ()>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp>
-struct __weak_result_type<_Rp (&)()>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp>
-struct __weak_result_type<_Rp (*)()>
-{
-    typedef _Rp result_type;
-};
-
-// 1 argument case
-
-template <class _Rp, class _A1>
-struct __weak_result_type<_Rp (_A1)>
-    : public unary_function<_A1, _Rp>
-{
-};
-
-template <class _Rp, class _A1>
-struct __weak_result_type<_Rp (&)(_A1)>
-    : public unary_function<_A1, _Rp>
-{
-};
-
-template <class _Rp, class _A1>
-struct __weak_result_type<_Rp (*)(_A1)>
-    : public unary_function<_A1, _Rp>
-{
-};
-
-template <class _Rp, class _Cp>
-struct __weak_result_type<_Rp (_Cp::*)()>
-    : public unary_function<_Cp*, _Rp>
-{
-};
-
-template <class _Rp, class _Cp>
-struct __weak_result_type<_Rp (_Cp::*)() const>
-    : public unary_function<const _Cp*, _Rp>
-{
-};
-
-template <class _Rp, class _Cp>
-struct __weak_result_type<_Rp (_Cp::*)() volatile>
-    : public unary_function<volatile _Cp*, _Rp>
-{
-};
-
-template <class _Rp, class _Cp>
-struct __weak_result_type<_Rp (_Cp::*)() const volatile>
-    : public unary_function<const volatile _Cp*, _Rp>
-{
-};
-
-// 2 argument case
-
-template <class _Rp, class _A1, class _A2>
-struct __weak_result_type<_Rp (_A1, _A2)>
-    : public binary_function<_A1, _A2, _Rp>
-{
-};
-
-template <class _Rp, class _A1, class _A2>
-struct __weak_result_type<_Rp (*)(_A1, _A2)>
-    : public binary_function<_A1, _A2, _Rp>
-{
-};
-
-template <class _Rp, class _A1, class _A2>
-struct __weak_result_type<_Rp (&)(_A1, _A2)>
-    : public binary_function<_A1, _A2, _Rp>
-{
-};
-
-template <class _Rp, class _Cp, class _A1>
-struct __weak_result_type<_Rp (_Cp::*)(_A1)>
-    : public binary_function<_Cp*, _A1, _Rp>
-{
-};
-
-template <class _Rp, class _Cp, class _A1>
-struct __weak_result_type<_Rp (_Cp::*)(_A1) const>
-    : public binary_function<const _Cp*, _A1, _Rp>
-{
-};
-
-template <class _Rp, class _Cp, class _A1>
-struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile>
-    : public binary_function<volatile _Cp*, _A1, _Rp>
-{
-};
-
-template <class _Rp, class _Cp, class _A1>
-struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile>
-    : public binary_function<const volatile _Cp*, _A1, _Rp>
-{
-};
-
-// 3 or more arguments
-
-template <class _Rp, class _A1, class _A2, class _A3>
-struct __weak_result_type<_Rp (_A1, _A2, _A3)>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp, class _A1, class _A2, class _A3>
-struct __weak_result_type<_Rp (&)(_A1, _A2, _A3)>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp, class _A1, class _A2, class _A3>
-struct __weak_result_type<_Rp (*)(_A1, _A2, _A3)>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp, class _Cp, class _A1, class _A2>
-struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2)>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp, class _Cp, class _A1, class _A2>
-struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2) const>
-{
-    typedef _Rp result_type;
-};
-
-template <class _Rp, class _Cp, class _A1, class _A2>
-struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2) volatile>
-{
-    typedef _Rp result_type;
-};
-
-// __invoke
-
-// __ref_return0
-//
-// template <class _Tp, bool _HasResultType>
-// struct ________ref_return0  // _HasResultType is true
-// {
-//     typedef typename _Tp::result_type type;
-// };
-//
-// template <class _Tp>
-// struct ________ref_return0<_Tp, false>
-// {
-//     typedef void type;
-// };
-//
-// template <class _Tp, bool _IsClass>
-// struct ____ref_return0  // _IsClass is true
-//     : public ________ref_return0<_Tp, __has_result_type<typename remove_cv<_Tp>::type>::value>
-// {
-// };
-//
-// template <class _Tp, bool _HasResultType>
-// struct ______ref_return0  // _HasResultType is true
-// {
-//     typedef typename __callable_type<_Tp>::result_type type;
-// };
-//
-// template <class _Tp>
-// struct ______ref_return0<_Tp, false>  // pointer to member data
-// {
-//     typedef void type;
-// };
-//
-// template <class _Tp>
-// struct ____ref_return0<_Tp, false>
-//     : public ______ref_return0<typename remove_cv<_Tp>::type,
-//                  __has_result_type<__callable_type<typename remove_cv<_Tp>::type> >::value>
-// {
-// };
-//
-// template <class _Tp>
-// struct __ref_return0
-//     : public ____ref_return0<typename remove_reference<_Tp>::type,
-//                    is_class<typename remove_reference<_Tp>::type>::value>
-// {
-// };
-//
-// __ref_return1
-//
-// template <class _Tp, bool _IsClass, class _A0>
-// struct ____ref_return1  // _IsClass is true
-// {
-//     typedef typename result_of<_Tp(_A0)>::type type;
-// };
-//
-// template <class _Tp, bool _HasResultType, class _A0>
-// struct ______ref_return1  // _HasResultType is true
-// {
-//     typedef typename __callable_type<_Tp>::result_type type;
-// };
-//
-// template <class _Tp, class _A0, bool>
-// struct __ref_return1_member_data1;
-//
-// template <class _Rp, class _Cp, class _A0>
-// struct __ref_return1_member_data1<_Rp _Cp::*, _A0, true>
-// {
-//     typedef typename __apply_cv<_A0, _Rp>::type& type;
-// };
-//
-// template <class _Rp, class _Cp, class _A0>
-// struct __ref_return1_member_data1<_Rp _Cp::*, _A0, false>
-// {
-//     static _A0 __a;
-//     typedef typename __apply_cv<decltype(*__a), _Rp>::type& type;
-// };
-//
-// template <class _Tp, class _A0>
-// struct __ref_return1_member_data;
-//
-// template <class _Rp, class _Cp, class _A0>
-// struct __ref_return1_member_data<_Rp _Cp::*, _A0>
-//     : public __ref_return1_member_data1<_Rp _Cp::*, _A0,
-//                 is_same<typename remove_cv<_Cp>::type,
-//                         typename remove_cv<typename remove_reference<_A0>::type>::type>::value>
-// {
-// };
-//
-// template <class _Tp, class _A0>
-// struct ______ref_return1<_Tp, false, _A0>  // pointer to member data
-//     : public __ref_return1_member_data<typename remove_cv<_Tp>::type, _A0>
-// {
-// };
-//
-// template <class _Tp, class _A0>
-// struct ____ref_return1<_Tp, false, _A0>
-//     : public ______ref_return1<typename remove_cv<_Tp>::type,
-//                  __has_result_type<__callable_type<typename remove_cv<_Tp>::type> >::value, _A0>
-// {
-// };
-//
-// template <class _Tp, class _A0>
-// struct __ref_return1
-//     : public ____ref_return1<typename remove_reference<_Tp>::type,
-//                    is_class<typename remove_reference<_Tp>::type>::value, _A0>
-// {
-// };
-//
-// __ref_return2
-//
-// template <class _Tp, bool _IsClass, class _A0, class _A1>
-// struct ____ref_return2  // _IsClass is true
-// {
-//     typedef typename result_of<_Tp(_A0, _A1)>::type type;
-// };
-//
-// template <class _Tp, bool _HasResultType, class _A0, class _A1>
-// struct ______ref_return2  // _HasResultType is true
-// {
-//     typedef typename __callable_type<_Tp>::result_type type;
-// };
-//
-// template <class _Tp>
-// struct ______ref_return2<_Tp, false, class _A0, class _A1>  // pointer to member data
-// {
-//     static_assert(sizeof(_Tp) == 0, "An attempt has been made to `call` a pointer"
-//                          " to member data with too many arguments.");
-// };
-//
-// template <class _Tp, class _A0, class _A1>
-// struct ____ref_return2<_Tp, false, _A0, _A1>
-//     : public ______ref_return2<typename remove_cv<_Tp>::type,
-//                  __has_result_type<__callable_type<typename remove_cv<_Tp>::type> >::value, _A0, _A1>
-// {
-// };
-//
-// template <class _Tp, class _A0, class _A1>
-// struct __ref_return2
-//     : public ____ref_return2<typename remove_reference<_Tp>::type,
-//                    is_class<typename remove_reference<_Tp>::type>::value, _A0, _A1>
-// {
-// };
-//
-// __ref_return3
-//
-// template <class _Tp, bool _IsClass, class _A0, class _A1, class _A2>
-// struct ____ref_return3  // _IsClass is true
-// {
-//     typedef typename result_of<_Tp(_A0, _A1, _A2)>::type type;
-// };
-//
-// template <class _Tp, bool _HasResultType, class _A0, class _A1, class _A2>
-// struct ______ref_return3  // _HasResultType is true
-// {
-//     typedef typename __callable_type<_Tp>::result_type type;
-// };
-//
-// template <class _Tp>
-// struct ______ref_return3<_Tp, false, class _A0, class _A1, class _A2>  // pointer to member data
-// {
-//     static_assert(sizeof(_Tp) == 0, "An attempt has been made to `call` a pointer"
-//                          " to member data with too many arguments.");
-// };
-//
-// template <class _Tp, class _A0, class _A1, class _A2>
-// struct ____ref_return3<_Tp, false, _A0, _A1, _A2>
-//     : public ______ref_return3<typename remove_cv<_Tp>::type,
-//                  __has_result_type<__callable_type<typename remove_cv<_Tp>::type> >::value, _A0, _A1, _A2>
-// {
-// };
-//
-// template <class _Tp, class _A0, class _A1, class _A2>
-// struct __ref_return3
-//     : public ____ref_return3<typename remove_reference<_Tp>::type,
-//                    is_class<typename remove_reference<_Tp>::type>::value, _A0, _A1, _A2>
-// {
-// };
-
-// first bullet
-
-template <class _Rp, class _Tp, class _T1>
-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)
-{
-    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), _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), _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), _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, _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)
-{
-    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), _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), _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), _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, _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_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    typename __apply_cv<_T1, _Rp>::type&
->::type
-__invoke(_Rp _Tp::* __f, _T1& __t1)
-{
-    return __t1.*__f;
-}
-
-template <class _Rp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-__invoke(_Rp _Tp::*)
-{
-}
-
-// template <class _Dp, class _Rp, class _Tp, class _T1>
-// inline _LIBCPP_INLINE_VISIBILITY
-// typename enable_if
-// <
-//     is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-//     typename __ref_return1<_Rp _Tp::*, _T1>::type
-// >::type
-// __invoke(_Rp _Tp::* __f, _T1& __t1)
-// {
-//     return __t1.*__f;
-// }
-
-// forth bullet
-
-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>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __4th_helper<_T1, _Rp,
-                      !is_base_of<_Tp,
-                                  typename remove_reference<_T1>::type
-                                 >::value
-                     >::type&
-__invoke(_Rp _Tp::* __f, _T1& __t1)
-{
-    return (*__t1).*__f;
-}
-
-// template <class _Dp, class _Rp, class _Tp, class _T1>
-// inline _LIBCPP_INLINE_VISIBILITY
-// typename enable_if
-// <
-//     !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-//     typename __ref_return1<_Rp _Tp::*, _T1>::type
-// >::type
-// __invoke(_Rp _Tp::* __f, _T1 __t1)
-// {
-//     return (*__t1).*__f;
-// }
-
-// fifth bullet
-
-template <class _Fp>
-inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp>()())
-__invoke(_Fp __f)
-{
-    return __f();
-}
-
-template <class _Fp, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp>()(declval<_A0&>()))
-__invoke(_Fp __f, _A0& __a0)
-{
-    return __f(__a0);
-}
-
-template <class _Fp, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp>()(declval<_A0&>(), declval<_A1&>()))
-__invoke(_Fp __f, _A0& __a0, _A1& __a1)
-{
-    return __f(__a0, __a1);
-}
-
-template <class _Fp, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp>()(declval<_A0&>(), declval<_A1&>(), declval<_A2&>()))
-__invoke(_Fp __f, _A0& __a0, _A1& __a1, _A2& __a2)
-{
-    return __f(__a0, __a1, __a2);
-}
-
-// template <class _Rp, class _Fp>
-// inline _LIBCPP_INLINE_VISIBILITY
-// _Rp
-// __invoke(_Fp& __f)
-// {
-//     return __f();
-// }
-//
-// template <class _Rp, class _Fp, class _A0>
-// inline _LIBCPP_INLINE_VISIBILITY
-// typename enable_if
-// <
-//     !is_member_pointer<_Fp>::value,
-//     _Rp
-// >::type
-// __invoke(_Fp& __f, _A0& __a0)
-// {
-//     return __f(__a0);
-// }
-//
-// template <class _Rp, class _Fp, class _A0, class _A1>
-// inline _LIBCPP_INLINE_VISIBILITY
-// _Rp
-// __invoke(_Fp& __f, _A0& __a0, _A1& __a1)
-// {
-//     return __f(__a0, __a1);
-// }
-//
-// template <class _Rp, class _Fp, class _A0, class _A1, class _A2>
-// inline _LIBCPP_INLINE_VISIBILITY
-// _Rp
-// __invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2)
-// {
-//     return __f(__a0, __a1, __a2);
-// }
-
-template <class _Tp>
-struct __has_type
-{
-private:
-    struct __two {char __lx; char __lxx;};
-    template <class _Up> static __two __test(...);
-    template <class _Up> static char __test(typename _Up::type* = 0);
-public:
-    static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
-
-template <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value>
-struct __invoke_return
-{
-    typedef typename __weak_result_type<_Fp>::result_type type;
-};
-
-template <class _Fp>
-struct __invoke_return<_Fp, false>
-{
-    typedef decltype(__invoke(_VSTD::declval<_Fp>())) type;
-};
-
-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>
-{
-    typedef typename __apply_cv<_A0, _Rp>::type& type;
-};
-
-template <class _Rp, class _Tp, class _A0>
-struct __invoke_return0<_Rp _Tp::*, _A0*>
-{
-    typedef typename __apply_cv<_A0, _Rp>::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;
-};
-
-template <class _Tp, class _A0, class _A1, class _A2>
-struct __invoke_return2
-{
-    typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_A0>(),
-                                                    _VSTD::declval<_A1>(),
-                                                    _VSTD::declval<_A2>())) type;
-};
-
-template <class _Tp>
-class _LIBCPP_TYPE_VIS_ONLY reference_wrapper
-    : public __weak_result_type<_Tp>
-{
-public:
-    // types
-    typedef _Tp type;
-private:
-    type* __f_;
-
-public:
-    // construct/copy/destroy
-    _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) : __f_(&__f) {}
-
-    // access
-    _LIBCPP_INLINE_VISIBILITY operator type&    () const {return *__f_;}
-    _LIBCPP_INLINE_VISIBILITY          type& get() const {return *__f_;}
-
-    // invoke
-
-    _LIBCPP_INLINE_VISIBILITY
-    typename __invoke_return<type&>::type
-       operator() () const
-       {
-           return __invoke(get());
-       }
-
-    template <class _A0>
-       _LIBCPP_INLINE_VISIBILITY
-       typename __invoke_return0<type&, _A0>::type
-          operator() (_A0& __a0) const
-          {
-              return __invoke<type&, _A0>(get(), __a0);
-          }
-
-    template <class _A0, class _A1>
-       _LIBCPP_INLINE_VISIBILITY
-       typename __invoke_return1<type&, _A0, _A1>::type
-          operator() (_A0& __a0, _A1& __a1) const
-          {
-              return __invoke<type&, _A0, _A1>(get(), __a0, __a1);
-          }
-
-    template <class _A0, class _A1, class _A2>
-       _LIBCPP_INLINE_VISIBILITY
-       typename __invoke_return2<type&, _A0, _A1, _A2>::type
-          operator() (_A0& __a0, _A1& __a1, _A2& __a2) const
-          {
-              return __invoke<type&, _A0, _A1, _A2>(get(), __a0, __a1, __a2);
-          }
-};
-
-template <class _Tp> struct __is_reference_wrapper_impl : public false_type {};
-template <class _Tp> struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {};
-template <class _Tp> struct __is_reference_wrapper
-    : public __is_reference_wrapper_impl<typename remove_cv<_Tp>::type> {};
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-reference_wrapper<_Tp>
-ref(_Tp& __t)
-{
-    return reference_wrapper<_Tp>(__t);
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-reference_wrapper<_Tp>
-ref(reference_wrapper<_Tp> __t)
-{
-    return ref(__t.get());
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-reference_wrapper<const _Tp>
-cref(const _Tp& __t)
-{
-    return reference_wrapper<const _Tp>(__t);
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-reference_wrapper<const _Tp>
-cref(reference_wrapper<_Tp> __t)
-{
-    return cref(__t.get());
-}
-
-#endif  // _LIBCPP_FUNCTIONAL_BASE_03
diff --git a/include/__hash_table b/include/__hash_table
index 7c954b6..df0f7c8 100644
--- a/include/__hash_table
+++ b/include/__hash_table
@@ -1,67 +1,109 @@
 // -*- 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.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef _LIBCPP__HASH_TABLE
 #define _LIBCPP__HASH_TABLE
 
+#include <__bits> // __libcpp_clz
 #include <__config>
-#include <initializer_list>
-#include <memory>
-#include <iterator>
+#include <__debug>
 #include <algorithm>
 #include <cmath>
-
-#include <__undef_min_max>
-
-#include <__debug>
+#include <initializer_list>
+#include <iterator>
+#include <memory>
+#include <type_traits>
+#include <utility>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+template <class _Key, class _Tp>
+struct __hash_value_type;
+
+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> {};
+
 _LIBCPP_FUNC_VIS
 size_t __next_prime(size_t __n);
 
 template <class _NodePtr>
 struct __hash_node_base
 {
+    typedef typename pointer_traits<_NodePtr>::element_type __node_type;
     typedef __hash_node_base __first_node;
+    typedef typename __rebind_pointer<_NodePtr, __first_node>::type __node_base_pointer;
+    typedef _NodePtr __node_pointer;
 
-    _NodePtr    __next_;
+#if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB)
+  typedef __node_base_pointer __next_pointer;
+#else
+  typedef typename conditional<
+      is_pointer<__node_pointer>::value,
+      __node_base_pointer,
+      __node_pointer>::type   __next_pointer;
+#endif
+
+    __next_pointer    __next_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __next_pointer __ptr() _NOEXCEPT {
+        return static_cast<__next_pointer>(
+            pointer_traits<__node_base_pointer>::pointer_to(*this));
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __node_pointer __upcast() _NOEXCEPT {
+        return static_cast<__node_pointer>(
+            pointer_traits<__node_base_pointer>::pointer_to(*this));
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t __hash() const _NOEXCEPT {
+        return static_cast<__node_type const&>(*this).__hash_;
+    }
 
     _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {}
 };
 
 template <class _Tp, class _VoidPtr>
-struct __hash_node
+struct _LIBCPP_STANDALONE_DEBUG __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_;
+    size_t            __hash_;
+    __node_value_type __value_;
 };
 
 inline _LIBCPP_INLINE_VISIBILITY
 bool
-__is_power2(size_t __bc)
+__is_hash_power2(size_t __bc)
 {
     return __bc > 2 && !(__bc & (__bc - 1));
 }
@@ -70,55 +112,188 @@
 size_t
 __constrain_hash(size_t __h, size_t __bc)
 {
-    return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : __h % __bc;
+    return !(__bc & (__bc - 1)) ? __h & (__bc - 1) :
+        (__h < __bc ? __h : __h % __bc);
 }
 
 inline _LIBCPP_INLINE_VISIBILITY
 size_t
-__next_pow2(size_t __n)
+__next_hash_pow2(size_t __n)
 {
-    return size_t(1) << (std::numeric_limits<size_t>::digits - __clz(__n-1));
+    return __n < 2 ? __n : (size_t(1) << (numeric_limits<size_t>::digits - __libcpp_clz(__n-1)));
 }
 
+
 template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table;
-template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
-template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;
-template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
-template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
-    class _LIBCPP_TYPE_VIS_ONLY unordered_map;
 
-template <class _NodePtr>
-class _LIBCPP_TYPE_VIS_ONLY __hash_iterator
+template <class _NodePtr>      class _LIBCPP_TEMPLATE_VIS __hash_iterator;
+template <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
+template <class _NodePtr>      class _LIBCPP_TEMPLATE_VIS __hash_local_iterator;
+template <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
+template <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
+template <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
+
+template <class _Tp>
+struct __hash_key_value_types {
+  static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, "");
+  typedef _Tp key_type;
+  typedef _Tp __node_value_type;
+  typedef _Tp __container_value_type;
+  static const bool __is_map = false;
+
+  _LIBCPP_INLINE_VISIBILITY
+  static key_type const& __get_key(_Tp const& __v) {
+    return __v;
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  static __container_value_type const& __get_value(__node_value_type const& __v) {
+    return __v;
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  static __container_value_type* __get_ptr(__node_value_type& __n) {
+    return _VSTD::addressof(__n);
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  static __container_value_type&& __move(__node_value_type& __v) {
+    return _VSTD::move(__v);
+  }
+};
+
+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 __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.__get_value();
+  }
+
+  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.__get_value());
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) {
+    return __v.__move();
+  }
+};
+
+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 _NodePtr __node_pointer;
-
-    __node_pointer            __node_;
+  typedef __hash_key_value_types<_Tp>           __base;
 
 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 ptrdiff_t difference_type;
+  typedef size_t size_type;
 
-    _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT
-#if _LIBCPP_STD_VER > 11
-    : __node_(nullptr)
-#endif
-    {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+  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 typename __node_base_type::__next_pointer          __next_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_TEMPLATE_VIS __hash_iterator
+{
+    typedef __hash_node_types<_NodePtr> _NodeTypes;
+    typedef _NodePtr                            __node_pointer;
+    typedef typename _NodeTypes::__next_pointer __next_pointer;
+
+    __next_pointer            __node_;
+
+public:
+    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 : __node_(nullptr) {
+#if _LIBCPP_DEBUG_LEVEL == 2
         __get_db()->__insert_i(this);
 #endif
     }
 
-#if _LIBCPP_DEBUG_LEVEL >= 2
-
+#if _LIBCPP_DEBUG_LEVEL == 2
     _LIBCPP_INLINE_VISIBILITY
     __hash_iterator(const __hash_iterator& __i)
         : __node_(__i.__node_)
@@ -142,35 +317,26 @@
         }
         return *this;
     }
-
-#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+#endif // _LIBCPP_DEBUG_LEVEL == 2
 
     _LIBCPP_INLINE_VISIBILITY
-        reference operator*() const
-        {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+    reference operator*() const {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
+                             "Attempted to dereference a non-dereferenceable unordered container iterator");
+        return __node_->__upcast()->__value_;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator->() const {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
                            "Attempted to dereference a non-dereferenceable unordered container iterator");
-#endif
-            return __node_->__value_;
-        }
-    _LIBCPP_INLINE_VISIBILITY
-        pointer operator->() const
-        {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
-                           "Attempted to dereference a non-dereferenceable unordered container iterator");
-#endif
-            return pointer_traits<pointer>::pointer_to(__node_->__value_);
-        }
+        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
+    }
 
     _LIBCPP_INLINE_VISIBILITY
-    __hash_iterator& operator++()
-    {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
-                       "Attempted to increment non-incrementable unordered container iterator");
-#endif
+    __hash_iterator& operator++() {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment a non-incrementable unordered container iterator");
         __node_ = __node_->__next_;
         return *this;
     }
@@ -193,79 +359,62 @@
         {return !(__x == __y);}
 
 private:
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     _LIBCPP_INLINE_VISIBILITY
-    __hash_iterator(__node_pointer __node, const void* __c) _NOEXCEPT
+    __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
         : __node_(__node)
         {
             __get_db()->__insert_ic(this, __c);
         }
 #else
     _LIBCPP_INLINE_VISIBILITY
-    __hash_iterator(__node_pointer __node) _NOEXCEPT
+    __hash_iterator(__next_pointer __node) _NOEXCEPT
         : __node_(__node)
         {}
 #endif
-
     template <class, class, class, class> friend class __hash_table;
-    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
-    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
+    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
+    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
+    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
 };
 
-template <class _ConstNodePtr>
-class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator
+template <class _NodePtr>
+class _LIBCPP_TEMPLATE_VIS __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;
+    typedef typename _NodeTypes::__next_pointer __next_pointer;
 
-    __node_pointer         __node_;
-
-    typedef typename remove_const<
-        typename pointer_traits<__node_pointer>::element_type
-                                 >::type __node;
+    __next_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;
 
-    _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT
-#if _LIBCPP_STD_VER > 11
-    : __node_(nullptr)
-#endif
-    {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+    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 : __node_(nullptr) {
+#if _LIBCPP_DEBUG_LEVEL == 2
         __get_db()->__insert_i(this);
 #endif
     }
-    _LIBCPP_INLINE_VISIBILITY 
+
+    _LIBCPP_INLINE_VISIBILITY
     __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT
         : __node_(__x.__node_)
     {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
         __get_db()->__iterator_copy(this, &__x);
 #endif
     }
 
-#if _LIBCPP_DEBUG_LEVEL >= 2
-
+#if _LIBCPP_DEBUG_LEVEL == 2
     _LIBCPP_INLINE_VISIBILITY
     __hash_const_iterator(const __hash_const_iterator& __i)
         : __node_(__i.__node_)
@@ -289,35 +438,25 @@
         }
         return *this;
     }
-
-#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+#endif // _LIBCPP_DEBUG_LEVEL == 2
 
     _LIBCPP_INLINE_VISIBILITY
-        reference operator*() const
-        {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+    reference operator*() const {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
                            "Attempted to dereference a non-dereferenceable unordered container const_iterator");
-#endif
-            return __node_->__value_;
-        }
+        return __node_->__upcast()->__value_;
+    }
     _LIBCPP_INLINE_VISIBILITY
-        pointer operator->() const
-        {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+    pointer operator->() const {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
                            "Attempted to dereference a non-dereferenceable unordered container const_iterator");
-#endif
-            return pointer_traits<pointer>::pointer_to(__node_->__value_);
-        }
+        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
+    }
 
     _LIBCPP_INLINE_VISIBILITY
-    __hash_const_iterator& operator++()
-    {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
-                       "Attempted to increment non-incrementable unordered container const_iterator");
-#endif
+    __hash_const_iterator& operator++() {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
+                             "Attempted to increment a non-incrementable unordered container const_iterator");
         __node_ = __node_->__next_;
         return *this;
     }
@@ -340,60 +479,50 @@
         {return !(__x == __y);}
 
 private:
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     _LIBCPP_INLINE_VISIBILITY
-    __hash_const_iterator(__node_pointer __node, const void* __c) _NOEXCEPT
+    __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
         : __node_(__node)
         {
             __get_db()->__insert_ic(this, __c);
         }
 #else
     _LIBCPP_INLINE_VISIBILITY
-    __hash_const_iterator(__node_pointer __node) _NOEXCEPT
+    __hash_const_iterator(__next_pointer __node) _NOEXCEPT
         : __node_(__node)
         {}
 #endif
-
     template <class, class, class, class> friend class __hash_table;
-    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
+    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
+    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS 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
+class _LIBCPP_TEMPLATE_VIS __hash_local_iterator
 {
-    typedef _NodePtr __node_pointer;
+    typedef __hash_node_types<_NodePtr> _NodeTypes;
+    typedef _NodePtr                            __node_pointer;
+    typedef typename _NodeTypes::__next_pointer __next_pointer;
 
-    __node_pointer         __node_;
+    __next_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
-    {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) {
+#if _LIBCPP_DEBUG_LEVEL == 2
         __get_db()->__insert_i(this);
 #endif
     }
 
-#if _LIBCPP_DEBUG_LEVEL >= 2
-
+#if _LIBCPP_DEBUG_LEVEL == 2
     _LIBCPP_INLINE_VISIBILITY
     __hash_local_iterator(const __hash_local_iterator& __i)
         : __node_(__i.__node_),
@@ -421,37 +550,28 @@
         }
         return *this;
     }
-
-#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+#endif // _LIBCPP_DEBUG_LEVEL == 2
 
     _LIBCPP_INLINE_VISIBILITY
-        reference operator*() const
-        {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+    reference operator*() const {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
                            "Attempted to dereference a non-dereferenceable unordered container local_iterator");
-#endif
-            return __node_->__value_;
-        }
-    _LIBCPP_INLINE_VISIBILITY
-        pointer operator->() const
-        {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
-                           "Attempted to dereference a non-dereferenceable unordered container local_iterator");
-#endif
-            return pointer_traits<pointer>::pointer_to(__node_->__value_);
-        }
+        return __node_->__upcast()->__value_;
+    }
 
     _LIBCPP_INLINE_VISIBILITY
-    __hash_local_iterator& operator++()
-    {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
-                       "Attempted to increment non-incrementable unordered container local_iterator");
-#endif
+    pointer operator->() const {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
+                             "Attempted to dereference a non-dereferenceable unordered container local_iterator");
+        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_local_iterator& operator++() {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment a non-incrementable unordered container local_iterator");
         __node_ = __node_->__next_;
-        if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_)
+        if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
             __node_ = nullptr;
         return *this;
     }
@@ -474,9 +594,9 @@
         {return !(__x == __y);}
 
 private:
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     _LIBCPP_INLINE_VISIBILITY
-    __hash_local_iterator(__node_pointer __node, size_t __bucket,
+    __hash_local_iterator(__next_pointer __node, size_t __bucket,
                           size_t __bucket_count, const void* __c) _NOEXCEPT
         : __node_(__node),
           __bucket_(__bucket),
@@ -488,7 +608,7 @@
         }
 #else
     _LIBCPP_INLINE_VISIBILITY
-    __hash_local_iterator(__node_pointer __node, size_t __bucket,
+    __hash_local_iterator(__next_pointer __node, size_t __bucket,
                           size_t __bucket_count) _NOEXCEPT
         : __node_(__node),
           __bucket_(__bucket),
@@ -499,49 +619,39 @@
         }
 #endif
     template <class, class, class, class> friend class __hash_table;
-    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
-    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;
+    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
+    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
 };
 
 template <class _ConstNodePtr>
-class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator
+class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator
 {
-    typedef _ConstNodePtr __node_pointer;
+    typedef __hash_node_types<_ConstNodePtr> _NodeTypes;
+    typedef _ConstNodePtr                       __node_pointer;
+    typedef typename _NodeTypes::__next_pointer __next_pointer;
 
-    __node_pointer         __node_;
+    __next_pointer         __node_;
     size_t                 __bucket_;
     size_t                 __bucket_count_;
 
     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;
 
-    _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT
-    {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+    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 : __node_(nullptr) {
+#if _LIBCPP_DEBUG_LEVEL == 2
         __get_db()->__insert_i(this);
 #endif
     }
@@ -552,13 +662,12 @@
           __bucket_(__x.__bucket_),
           __bucket_count_(__x.__bucket_count_)
     {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
         __get_db()->__iterator_copy(this, &__x);
 #endif
     }
 
-#if _LIBCPP_DEBUG_LEVEL >= 2
-
+#if _LIBCPP_DEBUG_LEVEL == 2
     _LIBCPP_INLINE_VISIBILITY
     __hash_const_local_iterator(const __hash_const_local_iterator& __i)
         : __node_(__i.__node_),
@@ -586,37 +695,28 @@
         }
         return *this;
     }
-
-#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+#endif // _LIBCPP_DEBUG_LEVEL == 2
 
     _LIBCPP_INLINE_VISIBILITY
-        reference operator*() const
-        {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+    reference operator*() const {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
                            "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
-#endif
-            return __node_->__value_;
-        }
-    _LIBCPP_INLINE_VISIBILITY
-        pointer operator->() const
-        {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
-                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
-#endif
-            return pointer_traits<pointer>::pointer_to(__node_->__value_);
-        }
+        return __node_->__upcast()->__value_;
+    }
 
     _LIBCPP_INLINE_VISIBILITY
-    __hash_const_local_iterator& operator++()
-    {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
-                       "Attempted to increment non-incrementable unordered container const_local_iterator");
-#endif
+    pointer operator->() const {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_local_iterator& operator++() {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment a non-incrementable unordered container const_local_iterator");
         __node_ = __node_->__next_;
-        if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_)
+        if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
             __node_ = nullptr;
         return *this;
     }
@@ -639,11 +739,11 @@
         {return !(__x == __y);}
 
 private:
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     _LIBCPP_INLINE_VISIBILITY
-    __hash_const_local_iterator(__node_pointer __node, size_t __bucket,
+    __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket,
                                 size_t __bucket_count, const void* __c) _NOEXCEPT
-        : __node_(__node),
+        : __node_(__node_ptr),
           __bucket_(__bucket),
           __bucket_count_(__bucket_count)
         {
@@ -653,9 +753,9 @@
         }
 #else
     _LIBCPP_INLINE_VISIBILITY
-    __hash_const_local_iterator(__node_pointer __node, size_t __bucket,
+    __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket,
                                 size_t __bucket_count) _NOEXCEPT
-        : __node_(__node),
+        : __node_(__node_ptr),
           __bucket_(__bucket),
           __bucket_count_(__bucket_count)
         {
@@ -664,7 +764,7 @@
         }
 #endif
     template <class, class, class, class> friend class __hash_table;
-    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
+    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
 };
 
 template <class _Alloc>
@@ -681,15 +781,13 @@
     _LIBCPP_INLINE_VISIBILITY
     __bucket_list_deallocator()
         _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
-        : __data_(0) {}
+        : __data_(0, __default_init_tag()) {}
 
     _LIBCPP_INLINE_VISIBILITY
     __bucket_list_deallocator(const allocator_type& __a, size_type __size)
         _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
         : __data_(__size, __a) {}
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
     _LIBCPP_INLINE_VISIBILITY
     __bucket_list_deallocator(__bucket_list_deallocator&& __x)
         _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
@@ -698,8 +796,6 @@
         __x.size() = 0;
     }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
     _LIBCPP_INLINE_VISIBILITY
     size_type& size() _NOEXCEPT {return __data_.first();}
     _LIBCPP_INLINE_VISIBILITY
@@ -724,18 +820,21 @@
 {
     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_;
 
-    __hash_node_destructor& operator=(const __hash_node_destructor&);
-
 public:
     bool __value_constructed;
 
+    __hash_node_destructor(__hash_node_destructor const&) = default;
+    __hash_node_destructor& operator=(const __hash_node_destructor&) = delete;
+
+
     _LIBCPP_INLINE_VISIBILITY
     explicit __hash_node_destructor(allocator_type& __na,
                                     bool __constructed = false) _NOEXCEPT
@@ -747,7 +846,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);
     }
@@ -755,6 +854,45 @@
     template <class> friend class __hash_map_node_destructor;
 };
 
+#if _LIBCPP_STD_VER > 14
+template <class _NodeType, class _Alloc>
+struct __generic_container_node_destructor;
+
+template <class _Tp, class _VoidPtr, class _Alloc>
+struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc>
+    : __hash_node_destructor<_Alloc>
+{
+    using __hash_node_destructor<_Alloc>::__hash_node_destructor;
+};
+#endif
+
+template <class _Key, class _Hash, class _Equal>
+struct __enforce_unordered_container_requirements {
+#ifndef _LIBCPP_CXX03_LANG
+    static_assert(__check_hash_requirements<_Key, _Hash>::value,
+    "the specified hash does not meet the Hash requirements");
+    static_assert(is_copy_constructible<_Equal>::value,
+    "the specified comparator is required to be copy constructible");
+#endif
+    typedef int type;
+};
+
+template <class _Key, class _Hash, class _Equal>
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value,
+    "the specified comparator type does not provide a viable const call operator")
+    _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value,
+    "the specified hash functor does not provide a viable const call operator")
+#endif
+typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type
+__diagnose_unordered_container_requirements(int);
+
+// This dummy overload is used so that the compiler won't emit a spurious
+// "no matching function for call to __diagnose_unordered_xxx" diagnostic
+// when the overload above causes a hard error.
+template <class _Key, class _Hash, class _Equal>
+int __diagnose_unordered_container_requirements(void*);
+
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 class __hash_table
 {
@@ -766,54 +904,62 @@
 
 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 __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind_alloc<__node>
-#else
-            rebind_alloc<__node>::other
-#endif
-                                                     __node_allocator;
+
+    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;
+    typedef typename _NodeTypes::__next_pointer      __next_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:
 
-    typedef typename __node_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind_alloc<__node_pointer>
-#else
-            rebind_alloc<__node_pointer>::other
-#endif
-                                                            __pointer_allocator;
+    typedef typename __rebind_alloc_helper<__node_traits, __next_pointer>::type __pointer_allocator;
     typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter;
-    typedef unique_ptr<__node_pointer[], __bucket_list_deleter> __bucket_list;
+    typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list;
     typedef allocator_traits<__pointer_allocator>          __pointer_alloc_traits;
-    typedef typename __bucket_list_deleter::pointer __node_pointer_pointer;
+    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
@@ -849,6 +995,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 &&
@@ -856,13 +1003,13 @@
             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
     __hash_table(__hash_table&& __u)
         _NOEXCEPT_(
             is_nothrow_move_constructible<__bucket_list>::value &&
@@ -871,18 +1018,16 @@
             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
     ~__hash_table();
 
     __hash_table& operator=(const __hash_table& __u);
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
     __hash_table& operator=(__hash_table&& __u)
         _NOEXCEPT_(
             __node_traits::propagate_on_container_move_assignment::value &&
             is_nothrow_move_assignable<__node_allocator>::value &&
             is_nothrow_move_assignable<hasher>::value &&
             is_nothrow_move_assignable<key_equal>::value);
-#endif
     template <class _InputIterator>
         void __assign_unique(_InputIterator __first, _InputIterator __last);
     template <class _InputIterator>
@@ -891,40 +1036,153 @@
     _LIBCPP_INLINE_VISIBILITY
     size_type max_size() const _NOEXCEPT
     {
-        return allocator_traits<__pointer_allocator>::max_size(
-            __bucket_list_.get_deleter().__alloc());
+        return _VSTD::min<size_type>(
+            __node_traits::max_size(__node_alloc()),
+            numeric_limits<difference_type >::max()
+        );
     }
 
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    __next_pointer __node_insert_multi_prepare(size_t __cp_hash,
+                                               value_type& __cp_val);
+    _LIBCPP_INLINE_VISIBILITY
+    void __node_insert_multi_perform(__node_pointer __cp,
+                                     __next_pointer __pn) _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __next_pointer __node_insert_unique_prepare(size_t __nd_hash,
+                                                value_type& __nd_val);
+    _LIBCPP_INLINE_VISIBILITY
+    void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
     pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
+    _LIBCPP_INLINE_VISIBILITY
     iterator             __node_insert_multi(__node_pointer __nd);
+    _LIBCPP_INLINE_VISIBILITY
     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)
+    template <class _Key, class ..._Args>
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args);
 
-    pair<iterator, bool> __insert_unique(const value_type& __x);
+    template <class... _Args>
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     template <class _Pp>
-        pair<iterator, bool> __insert_unique(_Pp&& __x);
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _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>());
+    }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    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>
-        iterator __insert_multi(_Pp&& __x);
+    _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>
-        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>
+    __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));
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> __insert_unique(const __container_value_type& __x) {
+        return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x);
+    }
+
+#if _LIBCPP_STD_VER > 14
+    template <class _NodeHandle, class _InsertReturnType>
+    _LIBCPP_INLINE_VISIBILITY
+    _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh);
+    template <class _NodeHandle>
+    _LIBCPP_INLINE_VISIBILITY
+    iterator __node_handle_insert_unique(const_iterator __hint,
+                                         _NodeHandle&& __nh);
+    template <class _Table>
+    _LIBCPP_INLINE_VISIBILITY
+    void __node_handle_merge_unique(_Table& __source);
+
+    template <class _NodeHandle>
+    _LIBCPP_INLINE_VISIBILITY
+    iterator __node_handle_insert_multi(_NodeHandle&& __nh);
+    template <class _NodeHandle>
+    _LIBCPP_INLINE_VISIBILITY
+    iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh);
+    template <class _Table>
+    _LIBCPP_INLINE_VISIBILITY
+    void __node_handle_merge_multi(_Table& __source);
+
+    template <class _NodeHandle>
+    _LIBCPP_INLINE_VISIBILITY
+    _NodeHandle __node_handle_extract(key_type const& __key);
+    template <class _NodeHandle>
+    _LIBCPP_INLINE_VISIBILITY
+    _NodeHandle __node_handle_extract(const_iterator __it);
+#endif
 
     void clear() _NOEXCEPT;
     void rehash(size_type __n);
@@ -937,9 +1195,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>
@@ -968,6 +1230,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;
@@ -987,17 +1250,21 @@
         __equal_range_multi(const _Key& __k) const;
 
     void swap(__hash_table& __u)
+#if _LIBCPP_STD_VER <= 11
         _NOEXCEPT_(
-            (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
-             __is_nothrow_swappable<__pointer_allocator>::value) &&
-            (!__node_traits::propagate_on_container_swap::value ||
-             __is_nothrow_swappable<__node_allocator>::value) &&
-            __is_nothrow_swappable<hasher>::value &&
-            __is_nothrow_swappable<key_equal>::value);
+            __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
+            && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
+                  || __is_nothrow_swappable<__pointer_allocator>::value)
+            && (!__node_traits::propagate_on_container_swap::value
+                  || __is_nothrow_swappable<__node_allocator>::value)
+            );
+#else
+     _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value);
+#endif
 
     _LIBCPP_INLINE_VISIBILITY
     size_type max_bucket_count() const _NOEXCEPT
-        {return __pointer_alloc_traits::max_size(__bucket_list_.get_deleter().__alloc());}
+        {return max_size(); }
     size_type bucket_size(size_type __n) const;
     _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT
     {
@@ -1017,7 +1284,7 @@
     {
         _LIBCPP_ASSERT(__n < bucket_count(),
             "unordered container::begin(n) called with n >= bucket_count()");
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
         return local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
 #else
         return local_iterator(__bucket_list_[__n], __n, bucket_count());
@@ -1030,7 +1297,7 @@
     {
         _LIBCPP_ASSERT(__n < bucket_count(),
             "unordered container::end(n) called with n >= bucket_count()");
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
         return local_iterator(nullptr, __n, bucket_count(), this);
 #else
         return local_iterator(nullptr, __n, bucket_count());
@@ -1043,7 +1310,7 @@
     {
         _LIBCPP_ASSERT(__n < bucket_count(),
             "unordered container::cbegin(n) called with n >= bucket_count()");
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
         return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
 #else
         return const_local_iterator(__bucket_list_[__n], __n, bucket_count());
@@ -1056,35 +1323,31 @@
     {
         _LIBCPP_ASSERT(__n < bucket_count(),
             "unordered container::cend(n) called with n >= bucket_count()");
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
         return const_local_iterator(nullptr, __n, bucket_count(), this);
 #else
         return const_local_iterator(nullptr, __n, bucket_count());
 #endif
     }
 
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
 
     bool __dereferenceable(const const_iterator* __i) const;
     bool __decrementable(const const_iterator* __i) const;
     bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
     bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
 
-#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+#endif // _LIBCPP_DEBUG_LEVEL == 2
 
 private:
     void __rehash(size_type __n);
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#ifndef _LIBCPP_HAS_NO_VARIADICS
     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);
-#endif
-    __node_holder __construct_node(const value_type& __v, size_t __hash);
+    __node_holder __construct_node(_Args&& ...__args);
+
+    template <class _First, class ..._Rest>
+    __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest);
+
 
     _LIBCPP_INLINE_VISIBILITY
     void __copy_assign_alloc(const __hash_table& __u)
@@ -1121,60 +1384,29 @@
     _LIBCPP_INLINE_VISIBILITY
         void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
 
-    template <class _Ap>
-    _LIBCPP_INLINE_VISIBILITY
-    static
-    void
-    __swap_alloc(_Ap& __x, _Ap& __y)
-        _NOEXCEPT_(
-            !allocator_traits<_Ap>::propagate_on_container_swap::value ||
-            __is_nothrow_swappable<_Ap>::value)
-    {
-        __swap_alloc(__x, __y,
-                     integral_constant<bool,
-                        allocator_traits<_Ap>::propagate_on_container_swap::value
-                                      >());
-    }
+    void __deallocate_node(__next_pointer __np) _NOEXCEPT;
+    __next_pointer __detach() _NOEXCEPT;
 
-    template <class _Ap>
-    _LIBCPP_INLINE_VISIBILITY
-    static
-    void
-    __swap_alloc(_Ap& __x, _Ap& __y, true_type)
-        _NOEXCEPT_(__is_nothrow_swappable<_Ap>::value)
-    {
-        using _VSTD::swap;
-        swap(__x, __y);
-    }
-
-    template <class _Ap>
-    _LIBCPP_INLINE_VISIBILITY
-    static
-    void
-    __swap_alloc(_Ap&, _Ap&, false_type) _NOEXCEPT {}
-
-    void __deallocate(__node_pointer __np) _NOEXCEPT;
-    __node_pointer __detach() _NOEXCEPT;
-
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
+    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
 };
 
 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),
-      __p3_(1.0f)
+    : __p2_(0, __default_init_tag()),
+      __p3_(1.0f, __default_init_tag())
 {
 }
 
 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()),
@@ -1189,7 +1421,7 @@
                                                        const key_equal& __eql,
                                                        const allocator_type& __a)
     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
-      __p1_(__node_allocator(__a)),
+      __p1_(__default_init_tag(), __node_allocator(__a)),
       __p2_(0, __hf),
       __p3_(1.0f, __eql)
 {
@@ -1198,9 +1430,9 @@
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a)
     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
-      __p1_(__node_allocator(__a)),
-      __p2_(0),
-      __p3_(1.0f)
+      __p1_(__default_init_tag(), __node_allocator(__a)),
+      __p2_(0, __default_init_tag()),
+      __p3_(1.0f, __default_init_tag())
 {
 }
 
@@ -1210,7 +1442,7 @@
           __bucket_list_deleter(allocator_traits<__pointer_allocator>::
               select_on_container_copy_construction(
                   __u.__bucket_list_.get_deleter().__alloc()), 0)),
-      __p1_(allocator_traits<__node_allocator>::
+      __p1_(__default_init_tag(), allocator_traits<__node_allocator>::
           select_on_container_copy_construction(__u.__node_alloc())),
       __p2_(0, __u.hash_function()),
       __p3_(__u.__p3_)
@@ -1221,19 +1453,18 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u,
                                                        const allocator_type& __a)
     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
-      __p1_(__node_allocator(__a)),
+      __p1_(__default_init_tag(), __node_allocator(__a)),
       __p2_(0, __u.hash_function()),
       __p3_(__u.__p3_)
 {
 }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 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_)),
@@ -1243,8 +1474,8 @@
 {
     if (size() > 0)
     {
-        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
-            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
+        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
+            __p1_.first().__ptr();
         __u.__p1_.first().__next_ = nullptr;
         __u.size() = 0;
     }
@@ -1254,7 +1485,7 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u,
                                                        const allocator_type& __a)
     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
-      __p1_(__node_allocator(__a)),
+      __p1_(__default_init_tag(), __node_allocator(__a)),
       __p2_(0, _VSTD::move(__u.hash_function())),
       __p3_(_VSTD::move(__u.__p3_))
 {
@@ -1267,21 +1498,26 @@
         {
             __p1_.first().__next_ = __u.__p1_.first().__next_;
             __u.__p1_.first().__next_ = nullptr;
-            __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
-                static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
+            __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
+                __p1_.first().__ptr();
             size() = __u.size();
             __u.size() = 0;
         }
     }
 }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table()
 {
-    __deallocate(__p1_.first().__next_);
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if defined(_LIBCPP_CXX03_LANG)
+    static_assert((is_copy_constructible<key_equal>::value),
+                 "Predicate must be copy-constructible.");
+    static_assert((is_copy_constructible<hasher>::value),
+                 "Hasher must be copy-constructible.");
+#endif
+
+    __deallocate_node(__p1_.first().__next_);
+#if _LIBCPP_DEBUG_LEVEL == 2
     __get_db()->__erase_c(this);
 #endif
 }
@@ -1318,14 +1554,14 @@
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 void
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate(__node_pointer __np)
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np)
     _NOEXCEPT
 {
     __node_allocator& __na = __node_alloc();
     while (__np != nullptr)
     {
-        __node_pointer __next = __np->__next_;
-#if _LIBCPP_DEBUG_LEVEL >= 2
+        __next_pointer __next = __np->__next_;
+#if _LIBCPP_DEBUG_LEVEL == 2
         __c_node* __c = __get_db()->__find_c_and_lock(this);
         for (__i_node** __p = __c->end_; __p != __c->beg_; )
         {
@@ -1335,32 +1571,31 @@
             {
                 (*__p)->__c_ = nullptr;
                 if (--__c->end_ != __p)
-                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+                    _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
             }
         }
         __get_db()->unlock();
 #endif
-        __node_traits::destroy(__na, _VSTD::addressof(__np->__value_));
-        __node_traits::deallocate(__na, __np, 1);
+        __node_pointer __real_np = __np->__upcast();
+        __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_));
+        __node_traits::deallocate(__na, __real_np, 1);
         __np = __next;
     }
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
-typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_pointer
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT
 {
     size_type __bc = bucket_count();
     for (size_type __i = 0; __i < __bc; ++__i)
         __bucket_list_[__i] = nullptr;
     size() = 0;
-    __node_pointer __cache = __p1_.first().__next_;
+    __next_pointer __cache = __p1_.first().__next_;
     __p1_.first().__next_ = nullptr;
     return __cache;
 }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 void
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
@@ -1382,12 +1617,12 @@
     __p1_.first().__next_ = __u.__p1_.first().__next_;
     if (size() > 0)
     {
-        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
-            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
+        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
+            __p1_.first().__ptr();
         __u.__p1_.first().__next_ = nullptr;
         __u.size() = 0;
     }
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     __get_db()->swap(this, &__u);
 #endif
 }
@@ -1406,34 +1641,34 @@
         max_load_factor() = __u.max_load_factor();
         if (bucket_count() != 0)
         {
-            __node_pointer __cache = __detach();
+            __next_pointer __cache = __detach();
 #ifndef _LIBCPP_NO_EXCEPTIONS
             try
             {
-#endif  // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_NO_EXCEPTIONS
                 const_iterator __i = __u.begin();
                 while (__cache != nullptr && __u.size() != 0)
                 {
-                    __cache->__value_ = _VSTD::move(__u.remove(__i++)->__value_);
-                    __node_pointer __next = __cache->__next_;
-                    __node_insert_multi(__cache);
+                    __cache->__upcast()->__value_ =
+                        _VSTD::move(__u.remove(__i++)->__value_);
+                    __next_pointer __next = __cache->__next_;
+                    __node_insert_multi(__cache->__upcast());
                     __cache = __next;
                 }
 #ifndef _LIBCPP_NO_EXCEPTIONS
             }
             catch (...)
             {
-                __deallocate(__cache);
+                __deallocate_node(__cache);
                 throw;
             }
-#endif  // _LIBCPP_NO_EXCEPTIONS
-            __deallocate(__cache);
+#endif // _LIBCPP_NO_EXCEPTIONS
+            __deallocate_node(__cache);
         }
         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();
         }
@@ -1441,7 +1676,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_(
@@ -1455,37 +1690,40 @@
     return *this;
 }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 template <class _InputIterator>
 void
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first,
                                                           _InputIterator __last)
 {
+    typedef iterator_traits<_InputIterator> _ITraits;
+    typedef typename _ITraits::value_type _ItValueType;
+    static_assert((is_same<_ItValueType, __container_value_type>::value),
+                  "__assign_unique may only be called with the containers value type");
+
     if (bucket_count() != 0)
     {
-        __node_pointer __cache = __detach();
+        __next_pointer __cache = __detach();
 #ifndef _LIBCPP_NO_EXCEPTIONS
         try
         {
-#endif  // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_NO_EXCEPTIONS
             for (; __cache != nullptr && __first != __last; ++__first)
             {
-                __cache->__value_ = *__first;
-                __node_pointer __next = __cache->__next_;
-                __node_insert_unique(__cache);
+                __cache->__upcast()->__value_ = *__first;
+                __next_pointer __next = __cache->__next_;
+                __node_insert_unique(__cache->__upcast());
                 __cache = __next;
             }
 #ifndef _LIBCPP_NO_EXCEPTIONS
         }
         catch (...)
         {
-            __deallocate(__cache);
+            __deallocate_node(__cache);
             throw;
         }
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        __deallocate(__cache);
+#endif // _LIBCPP_NO_EXCEPTIONS
+        __deallocate_node(__cache);
     }
     for (; __first != __last; ++__first)
         __insert_unique(*__first);
@@ -1497,40 +1735,46 @@
 __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();
+        __next_pointer __cache = __detach();
 #ifndef _LIBCPP_NO_EXCEPTIONS
         try
         {
-#endif  // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_NO_EXCEPTIONS
             for (; __cache != nullptr && __first != __last; ++__first)
             {
-                __cache->__value_ = *__first;
-                __node_pointer __next = __cache->__next_;
-                __node_insert_multi(__cache);
+                __cache->__upcast()->__value_ = *__first;
+                __next_pointer __next = __cache->__next_;
+                __node_insert_multi(__cache->__upcast());
                 __cache = __next;
             }
 #ifndef _LIBCPP_NO_EXCEPTIONS
         }
         catch (...)
         {
-            __deallocate(__cache);
+            __deallocate_node(__cache);
             throw;
         }
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        __deallocate(__cache);
+#endif // _LIBCPP_NO_EXCEPTIONS
+        __deallocate_node(__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
 {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     return iterator(__p1_.first().__next_, this);
 #else
     return iterator(__p1_.first().__next_);
@@ -1538,11 +1782,11 @@
 }
 
 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
 {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     return iterator(nullptr, this);
 #else
     return iterator(nullptr);
@@ -1550,11 +1794,11 @@
 }
 
 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
 {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     return const_iterator(__p1_.first().__next_, this);
 #else
     return const_iterator(__p1_.first().__next_);
@@ -1562,11 +1806,11 @@
 }
 
 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
 {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     return const_iterator(nullptr, this);
 #else
     return const_iterator(nullptr);
@@ -1579,7 +1823,7 @@
 {
     if (size() > 0)
     {
-        __deallocate(__p1_.first().__next_);
+        __deallocate_node(__p1_.first().__next_);
         __p1_.first().__next_ = nullptr;
         size_type __bc = bucket_count();
         for (size_type __i = 0; __i < __bc; ++__i)
@@ -1588,96 +1832,125 @@
     }
 }
 
+
+// Prepare the container for an insertion of the value __value with the hash
+// __hash. This does a lookup into the container to see if __value is already
+// present, and performs a rehash if necessary. Returns a pointer to the
+// existing element if it exists, otherwise nullptr.
+//
+// Note that this function does forward exceptions if key_eq() throws, and never
+// mutates __value or actually inserts into the map.
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+_LIBCPP_INLINE_VISIBILITY
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(
+    size_t __hash, value_type& __value)
+{
+    size_type __bc = bucket_count();
+
+    if (__bc != 0)
+    {
+        size_t __chash = __constrain_hash(__hash, __bc);
+        __next_pointer __ndptr = __bucket_list_[__chash];
+        if (__ndptr != nullptr)
+        {
+            for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&
+                                             __constrain_hash(__ndptr->__hash(), __bc) == __chash;
+                                                     __ndptr = __ndptr->__next_)
+            {
+                if (key_eq()(__ndptr->__upcast()->__value_, __value))
+                    return __ndptr;
+            }
+        }
+    }
+    if (size()+1 > __bc * max_load_factor() || __bc == 0)
+    {
+        rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
+                                     size_type(ceil(float(size() + 1) / max_load_factor()))));
+    }
+    return nullptr;
+}
+
+// Insert the node __nd into the container by pushing it into the right bucket,
+// and updating size(). Assumes that __nd->__hash is up-to-date, and that
+// rehashing has already occurred and that no element with the same key exists
+// in the map.
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+_LIBCPP_INLINE_VISIBILITY
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform(
+    __node_pointer __nd) _NOEXCEPT
+{
+    size_type __bc = bucket_count();
+    size_t __chash = __constrain_hash(__nd->__hash(), __bc);
+    // insert_after __bucket_list_[__chash], or __first_node if bucket is null
+    __next_pointer __pn = __bucket_list_[__chash];
+    if (__pn == nullptr)
+    {
+        __pn =__p1_.first().__ptr();
+        __nd->__next_ = __pn->__next_;
+        __pn->__next_ = __nd->__ptr();
+        // fix up __bucket_list_
+        __bucket_list_[__chash] = __pn;
+        if (__nd->__next_ != nullptr)
+            __bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr();
+    }
+    else
+    {
+        __nd->__next_ = __pn->__next_;
+        __pn->__next_ = __nd->__ptr();
+    }
+    ++size();
+}
+
 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>::__node_insert_unique(__node_pointer __nd)
 {
     __nd->__hash_ = hash_function()(__nd->__value_);
-    size_type __bc = bucket_count();
+    __next_pointer __existing_node =
+        __node_insert_unique_prepare(__nd->__hash(), __nd->__value_);
+
+    // Insert the node, unless it already exists in the container.
     bool __inserted = false;
-    __node_pointer __ndptr;
-    size_t __chash;
-    if (__bc != 0)
+    if (__existing_node == nullptr)
     {
-        __chash = __constrain_hash(__nd->__hash_, __bc);
-        __ndptr = __bucket_list_[__chash];
-        if (__ndptr != nullptr)
-        {
-            for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&
-                                             __constrain_hash(__ndptr->__hash_, __bc) == __chash;
-                                                     __ndptr = __ndptr->__next_)
-            {
-                if (key_eq()(__ndptr->__value_, __nd->__value_))
-                    goto __done;
-            }
-        }
-    }
-    {
-        if (size()+1 > __bc * max_load_factor() || __bc == 0)
-        {
-            rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
-                           size_type(ceil(float(size() + 1) / max_load_factor()))));
-            __bc = bucket_count();
-            __chash = __constrain_hash(__nd->__hash_, __bc);
-        }
-        // insert_after __bucket_list_[__chash], or __first_node if bucket is null
-        __node_pointer __pn = __bucket_list_[__chash];
-        if (__pn == nullptr)
-        {
-            __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
-            __nd->__next_ = __pn->__next_;
-            __pn->__next_ = __nd;
-            // fix up __bucket_list_
-            __bucket_list_[__chash] = __pn;
-            if (__nd->__next_ != nullptr)
-                __bucket_list_[__constrain_hash(__nd->__next_->__hash_, __bc)] = __nd;
-        }
-        else
-        {
-            __nd->__next_ = __pn->__next_;
-            __pn->__next_ = __nd;
-        }
-        __ndptr = __nd;
-        // increment size
-        ++size();
+        __node_insert_unique_perform(__nd);
+        __existing_node = __nd->__ptr();
         __inserted = true;
     }
-__done:
-#if _LIBCPP_DEBUG_LEVEL >= 2
-    return pair<iterator, bool>(iterator(__ndptr, this), __inserted);
+#if _LIBCPP_DEBUG_LEVEL == 2
+    return pair<iterator, bool>(iterator(__existing_node, this), __inserted);
 #else
-    return pair<iterator, bool>(iterator(__ndptr), __inserted);
+    return pair<iterator, bool>(iterator(__existing_node), __inserted);
 #endif
 }
 
+// Prepare the container for an insertion of the value __cp_val with the hash
+// __cp_hash. This does a lookup into the container to see if __cp_value is
+// already present, and performs a rehash if necessary. Returns a pointer to the
+// last occurrence of __cp_val in the map.
+//
+// Note that this function does forward exceptions if key_eq() throws, and never
+// mutates __value or actually inserts into the map.
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
-typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp)
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare(
+    size_t __cp_hash, value_type& __cp_val)
 {
-    __cp->__hash_ = hash_function()(__cp->__value_);
     size_type __bc = bucket_count();
     if (size()+1 > __bc * max_load_factor() || __bc == 0)
     {
-        rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
+        rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
                        size_type(ceil(float(size() + 1) / max_load_factor()))));
         __bc = bucket_count();
     }
-    size_t __chash = __constrain_hash(__cp->__hash_, __bc);
-    __node_pointer __pn = __bucket_list_[__chash];
-    if (__pn == nullptr)
-    {
-        __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
-        __cp->__next_ = __pn->__next_;
-        __pn->__next_ = __cp;
-        // fix up __bucket_list_
-        __bucket_list_[__chash] = __pn;
-        if (__cp->__next_ != nullptr)
-            __bucket_list_[__constrain_hash(__cp->__next_->__hash_, __bc)] = __cp;
-    }
-    else
+    size_t __chash = __constrain_hash(__cp_hash, __bc);
+    __next_pointer __pn = __bucket_list_[__chash];
+    if (__pn != nullptr)
     {
         for (bool __found = false; __pn->__next_ != nullptr &&
-                                   __constrain_hash(__pn->__next_->__hash_, __bc) == __chash;
+                                   __constrain_hash(__pn->__next_->__hash(), __bc) == __chash;
                                                            __pn = __pn->__next_)
         {
             //      __found    key_eq()     action
@@ -1685,8 +1958,8 @@
             //      true        true        loop
             //      false       true        set __found to true
             //      true        false       break
-            if (__found != (__pn->__next_->__hash_ == __cp->__hash_ &&
-                            key_eq()(__pn->__next_->__value_, __cp->__value_)))
+            if (__found != (__pn->__next_->__hash() == __cp_hash &&
+                            key_eq()(__pn->__next_->__upcast()->__value_, __cp_val)))
             {
                 if (!__found)
                     __found = true;
@@ -1694,20 +1967,60 @@
                     break;
             }
         }
+    }
+    return __pn;
+}
+
+// Insert the node __cp into the container after __pn (which is the last node in
+// the bucket that compares equal to __cp). Rehashing, and checking for
+// uniqueness has already been performed (in __node_insert_multi_prepare), so
+// all we need to do is update the bucket and size(). Assumes that __cp->__hash
+// is up-to-date.
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform(
+    __node_pointer __cp, __next_pointer __pn) _NOEXCEPT
+{
+    size_type __bc = bucket_count();
+    size_t __chash = __constrain_hash(__cp->__hash_, __bc);
+    if (__pn == nullptr)
+    {
+        __pn =__p1_.first().__ptr();
         __cp->__next_ = __pn->__next_;
-        __pn->__next_ = __cp;
+        __pn->__next_ = __cp->__ptr();
+        // fix up __bucket_list_
+        __bucket_list_[__chash] = __pn;
+        if (__cp->__next_ != nullptr)
+            __bucket_list_[__constrain_hash(__cp->__next_->__hash(), __bc)]
+                = __cp->__ptr();
+    }
+    else
+    {
+        __cp->__next_ = __pn->__next_;
+        __pn->__next_ = __cp->__ptr();
         if (__cp->__next_ != nullptr)
         {
-            size_t __nhash = __constrain_hash(__cp->__next_->__hash_, __bc);
+            size_t __nhash = __constrain_hash(__cp->__next_->__hash(), __bc);
             if (__nhash != __chash)
-                __bucket_list_[__nhash] = __cp;
+                __bucket_list_[__nhash] = __cp->__ptr();
         }
     }
     ++size();
-#if _LIBCPP_DEBUG_LEVEL >= 2
-    return iterator(__cp, this);
+}
+
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp)
+{
+    __cp->__hash_ = hash_function()(__cp->__value_);
+    __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_);
+    __node_insert_multi_perform(__cp, __pn);
+
+#if _LIBCPP_DEBUG_LEVEL == 2
+    return iterator(__cp->__ptr(), this);
 #else
-    return iterator(__cp);
+    return iterator(__cp->__ptr());
 #endif
 }
 
@@ -1716,46 +2029,50 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
         const_iterator __p, __node_pointer __cp)
 {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
         "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
         " referring to this unordered container");
 #endif
     if (__p != end() && key_eq()(*__p, __cp->__value_))
     {
-        __node_pointer __np = __p.__node_;
-        __cp->__hash_ = __np->__hash_;
+        __next_pointer __np = __p.__node_;
+        __cp->__hash_ = __np->__hash();
         size_type __bc = bucket_count();
         if (size()+1 > __bc * max_load_factor() || __bc == 0)
         {
-            rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
+            rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
                            size_type(ceil(float(size() + 1) / max_load_factor()))));
             __bc = bucket_count();
         }
         size_t __chash = __constrain_hash(__cp->__hash_, __bc);
-        __node_pointer __pp = __bucket_list_[__chash];
+        __next_pointer __pp = __bucket_list_[__chash];
         while (__pp->__next_ != __np)
             __pp = __pp->__next_;
         __cp->__next_ = __np;
-        __pp->__next_ = __cp;
+        __pp->__next_ = static_cast<__next_pointer>(__cp);
         ++size();
-#if _LIBCPP_DEBUG_LEVEL >= 2
-        return iterator(__cp, this);
+#if _LIBCPP_DEBUG_LEVEL == 2
+        return iterator(static_cast<__next_pointer>(__cp), this);
 #else
-        return iterator(__cp);
+        return iterator(static_cast<__next_pointer>(__cp));
 #endif
     }
     return __node_insert_multi(__cp);
 }
 
+
+
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Key, class ..._Args>
 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(const value_type& __x)
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args)
 {
-    size_t __hash = hash_function()(__x);
+
+    size_t __hash = hash_function()(__k);
     size_type __bc = bucket_count();
     bool __inserted = false;
-    __node_pointer __nd;
+    __next_pointer __nd;
     size_t __chash;
     if (__bc != 0)
     {
@@ -1764,60 +2081,58 @@
         if (__nd != nullptr)
         {
             for (__nd = __nd->__next_; __nd != nullptr &&
-                                       __constrain_hash(__nd->__hash_, __bc) == __chash;
+                (__nd->__hash() == __hash || __constrain_hash(__nd->__hash(), __bc) == __chash);
                                                            __nd = __nd->__next_)
             {
-                if (key_eq()(__nd->__value_, __x))
+                if (key_eq()(__nd->__upcast()->__value_, __k))
                     goto __done;
             }
         }
     }
     {
-        __node_holder __h = __construct_node(__x, __hash);
+        __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...);
         if (size()+1 > __bc * max_load_factor() || __bc == 0)
         {
-            rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
+            rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
                            size_type(ceil(float(size() + 1) / max_load_factor()))));
             __bc = bucket_count();
             __chash = __constrain_hash(__hash, __bc);
         }
         // insert_after __bucket_list_[__chash], or __first_node if bucket is null
-        __node_pointer __pn = __bucket_list_[__chash];
+        __next_pointer __pn = __bucket_list_[__chash];
         if (__pn == nullptr)
         {
-            __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
+            __pn = __p1_.first().__ptr();
             __h->__next_ = __pn->__next_;
-            __pn->__next_ = __h.get();
+            __pn->__next_ = __h.get()->__ptr();
             // fix up __bucket_list_
             __bucket_list_[__chash] = __pn;
             if (__h->__next_ != nullptr)
-                __bucket_list_[__constrain_hash(__h->__next_->__hash_, __bc)] = __h.get();
+                __bucket_list_[__constrain_hash(__h->__next_->__hash(), __bc)]
+                    = __h.get()->__ptr();
         }
         else
         {
             __h->__next_ = __pn->__next_;
-            __pn->__next_ = __h.get();
+            __pn->__next_ = static_cast<__next_pointer>(__h.get());
         }
-        __nd = __h.release();
+        __nd = static_cast<__next_pointer>(__h.release());
         // increment size
         ++size();
         __inserted = true;
     }
 __done:
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     return pair<iterator, bool>(iterator(__nd, this), __inserted);
 #else
     return pair<iterator, bool>(iterator(__nd), __inserted);
 #endif
 }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-
 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());
@@ -1843,7 +2158,7 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(
         const_iterator __p, _Args&&... __args)
 {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
         "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
         " referring to this unordered container");
@@ -1854,85 +2169,142 @@
     return __r;
 }
 
-#endif  // _LIBCPP_HAS_NO_VARIADICS
-
+#if _LIBCPP_STD_VER > 14
 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)
+template <class _NodeHandle, class _InsertReturnType>
+_LIBCPP_INLINE_VISIBILITY
+_InsertReturnType
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
+    _NodeHandle&& __nh)
 {
-    __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;
+    if (__nh.empty())
+        return _InsertReturnType{end(), false, _NodeHandle()};
+    pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
+    if (__result.second)
+        __nh.__release_ptr();
+    return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)};
 }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
-template <class _Pp>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(_Pp&& __x)
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
+    const_iterator, _NodeHandle&& __nh)
 {
-    __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));
-    iterator __r = __node_insert_multi(__h.get());
-    __h.release();
-    return __r;
+    if (__nh.empty())
+        return end();
+    pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
+    if (__result.second)
+        __nh.__release_ptr();
+    return __result.first;
 }
 
 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)
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+_NodeHandle
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
+    key_type const& __key)
 {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
-        "unordered container::insert(const_iterator, rvalue) called with an iterator not"
-        " referring to this unordered container");
-#endif
-    __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));
-    iterator __r = __node_insert_multi(__p, __h.get());
-    __h.release();
-    return __r;
-}
-
-#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-template <class _Tp, class _Hash, class _Equal, class _Alloc>
-typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const value_type& __x)
-{
-    __node_holder __h = __construct_node(__x);
-    iterator __r = __node_insert_multi(__h.get());
-    __h.release();
-    return __r;
+    iterator __i = find(__key);
+    if (__i == end())
+        return _NodeHandle();
+    return __node_handle_extract<_NodeHandle>(__i);
 }
 
 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)
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+_NodeHandle
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
+    const_iterator __p)
 {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
-        "unordered container::insert(const_iterator, lvalue) called with an iterator not"
-        " referring to this unordered container");
-#endif
-    __node_holder __h = __construct_node(__x);
-    iterator __r = __node_insert_multi(__p, __h.get());
-    __h.release();
-    return __r;
+    allocator_type __alloc(__node_alloc());
+    return _NodeHandle(remove(__p).release(), __alloc);
 }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Table>
+_LIBCPP_INLINE_VISIBILITY
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique(
+    _Table& __source)
+{
+    static_assert(is_same<__node, typename _Table::__node>::value, "");
+
+    for (typename _Table::iterator __it = __source.begin();
+         __it != __source.end();)
+    {
+        __node_pointer __src_ptr = __it.__node_->__upcast();
+        size_t __hash = hash_function()(__src_ptr->__value_);
+        __next_pointer __existing_node =
+            __node_insert_unique_prepare(__hash, __src_ptr->__value_);
+        auto __prev_iter = __it++;
+        if (__existing_node == nullptr)
+        {
+            (void)__source.remove(__prev_iter).release();
+            __src_ptr->__hash_ = __hash;
+            __node_insert_unique_perform(__src_ptr);
+        }
+    }
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
+    _NodeHandle&& __nh)
+{
+    if (__nh.empty())
+        return end();
+    iterator __result = __node_insert_multi(__nh.__ptr_);
+    __nh.__release_ptr();
+    return __result;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
+    const_iterator __hint, _NodeHandle&& __nh)
+{
+    if (__nh.empty())
+        return end();
+    iterator __result = __node_insert_multi(__hint, __nh.__ptr_);
+    __nh.__release_ptr();
+    return __result;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Table>
+_LIBCPP_INLINE_VISIBILITY
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(
+    _Table& __source)
+{
+    static_assert(is_same<typename _Table::__node, __node>::value, "");
+
+    for (typename _Table::iterator __it = __source.begin();
+         __it != __source.end();)
+    {
+        __node_pointer __src_ptr = __it.__node_->__upcast();
+        size_t __src_hash = hash_function()(__src_ptr->__value_);
+        __next_pointer __pn =
+            __node_insert_multi_prepare(__src_hash, __src_ptr->__value_);
+        (void)__source.remove(__it++).release();
+        __src_ptr->__hash_ = __src_hash;
+        __node_insert_multi_perform(__src_ptr, __pn);
+    }
+}
+#endif // _LIBCPP_STD_VER > 14
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 void
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n)
+_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
 {
     if (__n == 1)
         __n = 2;
@@ -1946,8 +2318,8 @@
         __n = _VSTD::max<size_type>
               (
                   __n,
-                  __is_power2(__bc) ? __next_pow2(size_t(ceil(float(size()) / max_load_factor()))) :
-                                      __next_prime(size_t(ceil(float(size()) / max_load_factor())))
+                  __is_hash_power2(__bc) ? __next_hash_pow2(size_t(ceil(float(size()) / max_load_factor()))) :
+                                           __next_prime(size_t(ceil(float(size()) / max_load_factor())))
               );
         if (__n < __bc)
             __rehash(__n);
@@ -1958,9 +2330,9 @@
 void
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc)
 {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     __get_db()->__invalidate_all(this);
-#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+#endif
     __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
     __bucket_list_.reset(__nbc > 0 ?
                       __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
@@ -1969,17 +2341,17 @@
     {
         for (size_type __i = 0; __i < __nbc; ++__i)
             __bucket_list_[__i] = nullptr;
-        __node_pointer __pp(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())));
-        __node_pointer __cp = __pp->__next_;
+        __next_pointer __pp = __p1_.first().__ptr();
+        __next_pointer __cp = __pp->__next_;
         if (__cp != nullptr)
         {
-            size_type __chash = __constrain_hash(__cp->__hash_, __nbc);
+            size_type __chash = __constrain_hash(__cp->__hash(), __nbc);
             __bucket_list_[__chash] = __pp;
             size_type __phash = __chash;
             for (__pp = __cp, __cp = __cp->__next_; __cp != nullptr;
                                                            __cp = __pp->__next_)
             {
-                __chash = __constrain_hash(__cp->__hash_, __nbc);
+                __chash = __constrain_hash(__cp->__hash(), __nbc);
                 if (__chash == __phash)
                     __pp = __cp;
                 else
@@ -1992,9 +2364,10 @@
                     }
                     else
                     {
-                        __node_pointer __np = __cp;
+                        __next_pointer __np = __cp;
                         for (; __np->__next_ != nullptr &&
-                               key_eq()(__cp->__value_, __np->__next_->__value_);
+                               key_eq()(__cp->__upcast()->__value_,
+                                        __np->__next_->__upcast()->__value_);
                                                            __np = __np->__next_)
                             ;
                         __pp->__next_ = __np->__next_;
@@ -2018,15 +2391,17 @@
     if (__bc != 0)
     {
         size_t __chash = __constrain_hash(__hash, __bc);
-        __node_pointer __nd = __bucket_list_[__chash];
+        __next_pointer __nd = __bucket_list_[__chash];
         if (__nd != nullptr)
         {
             for (__nd = __nd->__next_; __nd != nullptr &&
-                                       __constrain_hash(__nd->__hash_, __bc) == __chash;
+                (__nd->__hash() == __hash
+                  || __constrain_hash(__nd->__hash(), __bc) == __chash);
                                                            __nd = __nd->__next_)
             {
-                if (key_eq()(__nd->__value_, __k))
-#if _LIBCPP_DEBUG_LEVEL >= 2
+                if ((__nd->__hash() == __hash)
+                    && key_eq()(__nd->__upcast()->__value_, __k))
+#if _LIBCPP_DEBUG_LEVEL == 2
                     return iterator(__nd, this);
 #else
                     return iterator(__nd);
@@ -2047,15 +2422,17 @@
     if (__bc != 0)
     {
         size_t __chash = __constrain_hash(__hash, __bc);
-        __node_const_pointer __nd = __bucket_list_[__chash];
+        __next_pointer __nd = __bucket_list_[__chash];
         if (__nd != nullptr)
         {
             for (__nd = __nd->__next_; __nd != nullptr &&
-                                           __constrain_hash(__nd->__hash_, __bc) == __chash;
+                (__hash == __nd->__hash()
+                    || __constrain_hash(__nd->__hash(), __bc) == __chash);
                                                            __nd = __nd->__next_)
             {
-                if (key_eq()(__nd->__value_, __k))
-#if _LIBCPP_DEBUG_LEVEL >= 2
+                if ((__nd->__hash() == __hash)
+                    && key_eq()(__nd->__upcast()->__value_, __k))
+#if _LIBCPP_DEBUG_LEVEL == 2
                     return const_iterator(__nd, this);
 #else
                     return const_iterator(__nd);
@@ -2067,76 +2444,47 @@
     return end();
 }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-
 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
-
-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)
-{
-    __node_allocator& __na = __node_alloc();
-    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-    __node_traits::construct(__na, _VSTD::addressof(__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
-}
-
-#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)
-{
-    __node_allocator& __na = __node_alloc();
-    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v);
-    __h.get_deleter().__value_constructed = true;
-    __h->__hash_ = __hash;
-    __h->__next_ = nullptr;
-    return _VSTD::move(__h);  // explicitly moved for C++03
-}
-
 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)
 {
-    __node_pointer __np = __p.__node_;
-#if _LIBCPP_DEBUG_LEVEL >= 2
+    __next_pointer __np = __p.__node_;
+#if _LIBCPP_DEBUG_LEVEL == 2
     _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
         "unordered container erase(iterator) called with an iterator not"
         " referring to this container");
@@ -2156,21 +2504,21 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first,
                                                 const_iterator __last)
 {
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
-        "unodered container::erase(iterator, iterator) called with an iterator not"
-        " referring to this unodered container");
+        "unordered container::erase(iterator, iterator) called with an iterator not"
+        " referring to this container");
     _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this,
-        "unodered container::erase(iterator, iterator) called with an iterator not"
-        " referring to this unodered container");
+        "unordered container::erase(iterator, iterator) called with an iterator not"
+        " referring to this container");
 #endif
     for (const_iterator __p = __first; __first != __last; __p = __first)
     {
         ++__first;
         erase(__p);
     }
-    __node_pointer __np = __last.__node_;
-#if _LIBCPP_DEBUG_LEVEL >= 2
+    __next_pointer __np = __last.__node_;
+#if _LIBCPP_DEBUG_LEVEL == 2
     return iterator (__np, this);
 #else
     return iterator (__np);
@@ -2213,26 +2561,27 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
 {
     // current node
-    __node_pointer __cn = __p.__node_;
+    __next_pointer __cn = __p.__node_;
     size_type __bc = bucket_count();
-    size_t __chash = __constrain_hash(__cn->__hash_, __bc);
+    size_t __chash = __constrain_hash(__cn->__hash(), __bc);
     // find previous node
-    __node_pointer __pn = __bucket_list_[__chash];
+    __next_pointer __pn = __bucket_list_[__chash];
     for (; __pn->__next_ != __cn; __pn = __pn->__next_)
         ;
     // Fix up __bucket_list_
         // if __pn is not in same bucket (before begin is not in same bucket) &&
         //    if __cn->__next_ is not in same bucket (nullptr is not in same bucket)
-    if (__pn == static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()))
-                            || __constrain_hash(__pn->__hash_, __bc) != __chash)
+    if (__pn == __p1_.first().__ptr()
+            || __constrain_hash(__pn->__hash(), __bc) != __chash)
     {
-        if (__cn->__next_ == nullptr || __constrain_hash(__cn->__next_->__hash_, __bc) != __chash)
+        if (__cn->__next_ == nullptr
+            || __constrain_hash(__cn->__next_->__hash(), __bc) != __chash)
             __bucket_list_[__chash] = nullptr;
     }
         // if __cn->__next_ is not in same bucket (nullptr is in same bucket)
     if (__cn->__next_ != nullptr)
     {
-        size_t __nhash = __constrain_hash(__cn->__next_->__hash_, __bc);
+        size_t __nhash = __constrain_hash(__cn->__next_->__hash(), __bc);
         if (__nhash != __chash)
             __bucket_list_[__nhash] = __pn;
     }
@@ -2240,27 +2589,27 @@
     __pn->__next_ = __cn->__next_;
     __cn->__next_ = nullptr;
     --size();
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
     __c_node* __c = __get_db()->__find_c_and_lock(this);
-    for (__i_node** __p = __c->end_; __p != __c->beg_; )
+    for (__i_node** __dp = __c->end_; __dp != __c->beg_; )
     {
-        --__p;
-        iterator* __i = static_cast<iterator*>((*__p)->__i_);
+        --__dp;
+        iterator* __i = static_cast<iterator*>((*__dp)->__i_);
         if (__i->__node_ == __cn)
         {
-            (*__p)->__c_ = nullptr;
-            if (--__c->end_ != __p)
-                memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+            (*__dp)->__c_ = nullptr;
+            if (--__c->end_ != __dp)
+                _VSTD::memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*));
         }
     }
     __get_db()->unlock();
 #endif
-    return __node_holder(__cn, _Dp(__node_alloc(), true));
+    return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true));
 }
 
 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
 {
@@ -2357,33 +2706,41 @@
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 void
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
+#if _LIBCPP_STD_VER <= 11
     _NOEXCEPT_(
-        (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
-         __is_nothrow_swappable<__pointer_allocator>::value) &&
-        (!__node_traits::propagate_on_container_swap::value ||
-         __is_nothrow_swappable<__node_allocator>::value) &&
-        __is_nothrow_swappable<hasher>::value &&
-        __is_nothrow_swappable<key_equal>::value)
+        __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
+        && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
+              || __is_nothrow_swappable<__pointer_allocator>::value)
+        && (!__node_traits::propagate_on_container_swap::value
+              || __is_nothrow_swappable<__node_allocator>::value)
+            )
+#else
+  _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value)
+#endif
 {
+    _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value ||
+                   this->__node_alloc() == __u.__node_alloc(),
+                   "list::swap: Either propagate_on_container_swap must be true"
+                   " or the allocators must compare equal");
     {
     __node_pointer_pointer __npp = __bucket_list_.release();
     __bucket_list_.reset(__u.__bucket_list_.release());
     __u.__bucket_list_.reset(__npp);
     }
     _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size());
-    __swap_alloc(__bucket_list_.get_deleter().__alloc(),
+    _VSTD::__swap_allocator(__bucket_list_.get_deleter().__alloc(),
              __u.__bucket_list_.get_deleter().__alloc());
-    __swap_alloc(__node_alloc(), __u.__node_alloc());
+    _VSTD::__swap_allocator(__node_alloc(), __u.__node_alloc());
     _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_);
     __p2_.swap(__u.__p2_);
     __p3_.swap(__u.__p3_);
     if (size() > 0)
-        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
-            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
+        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
+            __p1_.first().__ptr();
     if (__u.size() > 0)
-        __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash_, __u.bucket_count())] =
-            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__u.__p1_.first()));
-#if _LIBCPP_DEBUG_LEVEL >= 2
+        __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] =
+            __u.__p1_.first().__ptr();
+#if _LIBCPP_DEBUG_LEVEL == 2
     __get_db()->swap(this, &__u);
 #endif
 }
@@ -2394,13 +2751,13 @@
 {
     _LIBCPP_ASSERT(__n < bucket_count(),
         "unordered container::bucket_size(n) called with n >= bucket_count()");
-    __node_const_pointer __np = __bucket_list_[__n];
+    __next_pointer __np = __bucket_list_[__n];
     size_type __bc = bucket_count();
     size_type __r = 0;
     if (__np != nullptr)
     {
         for (__np = __np->__next_; __np != nullptr &&
-                                   __constrain_hash(__np->__hash_, __bc) == __n;
+                                   __constrain_hash(__np->__hash(), __bc) == __n;
                                                     __np = __np->__next_, ++__r)
             ;
     }
@@ -2417,7 +2774,7 @@
     __x.swap(__y);
 }
 
-#if _LIBCPP_DEBUG_LEVEL >= 2
+#if _LIBCPP_DEBUG_LEVEL == 2
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 bool
@@ -2447,7 +2804,10 @@
     return false;
 }
 
-#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+#endif // _LIBCPP_DEBUG_LEVEL == 2
+
 _LIBCPP_END_NAMESPACE_STD
 
-#endif  // _LIBCPP__HASH_TABLE
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP__HASH_TABLE
diff --git a/include/__iterator/access.h b/include/__iterator/access.h
new file mode 100644
index 0000000..c0576b4
--- /dev/null
+++ b/include/__iterator/access.h
@@ -0,0 +1,134 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_ACCESS_H
+#define _LIBCPP___ITERATOR_ACCESS_H
+
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, size_t _Np>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp*
+begin(_Tp (&__array)[_Np])
+{
+    return __array;
+}
+
+template <class _Tp, size_t _Np>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp*
+end(_Tp (&__array)[_Np])
+{
+    return __array + _Np;
+}
+
+#if !defined(_LIBCPP_CXX03_LANG)
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+auto
+begin(_Cp& __c) -> decltype(__c.begin())
+{
+    return __c.begin();
+}
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+auto
+begin(const _Cp& __c) -> decltype(__c.begin())
+{
+    return __c.begin();
+}
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+auto
+end(_Cp& __c) -> decltype(__c.end())
+{
+    return __c.end();
+}
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+auto
+end(const _Cp& __c) -> decltype(__c.end())
+{
+    return __c.end();
+}
+
+#if _LIBCPP_STD_VER > 11
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+auto cbegin(const _Cp& __c) -> decltype(_VSTD::begin(__c))
+{
+    return _VSTD::begin(__c);
+}
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+auto cend(const _Cp& __c) -> decltype(_VSTD::end(__c))
+{
+    return _VSTD::end(__c);
+}
+
+#endif
+
+
+#else  // defined(_LIBCPP_CXX03_LANG)
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY
+typename _Cp::iterator
+begin(_Cp& __c)
+{
+    return __c.begin();
+}
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY
+typename _Cp::const_iterator
+begin(const _Cp& __c)
+{
+    return __c.begin();
+}
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY
+typename _Cp::iterator
+end(_Cp& __c)
+{
+    return __c.end();
+}
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY
+typename _Cp::const_iterator
+end(const _Cp& __c)
+{
+    return __c.end();
+}
+
+#endif // !defined(_LIBCPP_CXX03_LANG)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_ACCESS_H
diff --git a/include/__iterator/advance.h b/include/__iterator/advance.h
new file mode 100644
index 0000000..47bce1d
--- /dev/null
+++ b/include/__iterator/advance.h
@@ -0,0 +1,200 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_ADVANCE_H
+#define _LIBCPP___ITERATOR_ADVANCE_H
+
+#include <__config>
+#include <__debug>
+#include <__function_like.h>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iterator_traits.h>
+#include <__utility/move.h>
+#include <cstdlib>
+#include <concepts>
+#include <limits>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
+void __advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) {
+  for (; __n > 0; --__n)
+    ++__i;
+}
+
+template <class _BiDirIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
+void __advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) {
+  if (__n >= 0)
+    for (; __n > 0; --__n)
+      ++__i;
+  else
+    for (; __n < 0; ++__n)
+      --__i;
+}
+
+template <class _RandIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
+void __advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) {
+  __i += __n;
+}
+
+template <
+    class _InputIter, class _Distance,
+    class _IntegralDistance = decltype(_VSTD::__convert_to_integral(declval<_Distance>())),
+    class = _EnableIf<is_integral<_IntegralDistance>::value> >
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
+void advance(_InputIter& __i, _Distance __orig_n) {
+  typedef typename iterator_traits<_InputIter>::difference_type _Difference;
+  _Difference __n = static_cast<_Difference>(_VSTD::__convert_to_integral(__orig_n));
+  _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
+                 "Attempt to advance(it, n) with negative n on a non-bidirectional iterator");
+  _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
+}
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+// [range.iter.op.advance]
+struct __advance_fn final : private __function_like {
+private:
+  template <class _Tp>
+  _LIBCPP_HIDE_FROM_ABI
+  static constexpr _Tp __magnitude_geq(_Tp __a, _Tp __b) noexcept {
+    return __a < 0 ? (__a <= __b) : (__a >= __b);
+  }
+
+  template <class _Ip>
+  _LIBCPP_HIDE_FROM_ABI
+  static constexpr void __advance_forward(_Ip& __i, iter_difference_t<_Ip> __n) {
+    while (__n > 0) {
+      --__n;
+      ++__i;
+    }
+  }
+
+  template <class _Ip>
+  _LIBCPP_HIDE_FROM_ABI
+  static constexpr void __advance_backward(_Ip& __i, iter_difference_t<_Ip> __n) {
+    while (__n < 0) {
+      ++__n;
+      --__i;
+    }
+  }
+
+public:
+  constexpr explicit __advance_fn(__tag __x) noexcept : __function_like(__x) {}
+
+  // Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative.
+  template <input_or_output_iterator _Ip>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const {
+    _LIBCPP_ASSERT(__n >= 0 || bidirectional_iterator<_Ip>,
+                   "If `n < 0`, then `bidirectional_iterator<I>` must be true.");
+
+    // If `I` models `random_access_iterator`, equivalent to `i += n`.
+    if constexpr (random_access_iterator<_Ip>) {
+      __i += __n;
+      return;
+    } else if constexpr (bidirectional_iterator<_Ip>) {
+      // Otherwise, if `n` is non-negative, increments `i` by `n`.
+      __advance_forward(__i, __n);
+      // Otherwise, decrements `i` by `-n`.
+      __advance_backward(__i, __n);
+      return;
+    } else {
+      // Otherwise, if `n` is non-negative, increments `i` by `n`.
+      __advance_forward(__i, __n);
+      return;
+    }
+  }
+
+  // Preconditions: Either `assignable_from<I&, S> || sized_sentinel_for<S, I>` is modeled, or [i, bound) denotes a range.
+  template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr void operator()(_Ip& __i, _Sp __bound) const {
+    // If `I` and `S` model `assignable_from<I&, S>`, equivalent to `i = std::move(bound)`.
+    if constexpr (assignable_from<_Ip&, _Sp>) {
+      __i = _VSTD::move(__bound);
+    }
+    // Otherwise, if `S` and `I` model `sized_sentinel_for<S, I>`, equivalent to `ranges::advance(i, bound - i)`.
+    else if constexpr (sized_sentinel_for<_Sp, _Ip>) {
+      (*this)(__i, __bound - __i);
+    }
+    // Otherwise, while `bool(i != bound)` is true, increments `i`.
+    else {
+      while (__i != __bound) {
+        ++__i;
+      }
+    }
+  }
+
+  // Preconditions:
+  //   * If `n > 0`, [i, bound) denotes a range.
+  //   * If `n == 0`, [i, bound) or [bound, i) denotes a range.
+  //   * If `n < 0`, [bound, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model `same_as<I, S>`.
+  // Returns: `n - M`, where `M` is the difference between the the ending and starting position.
+  template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n, _Sp __bound) const {
+    _LIBCPP_ASSERT((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>),
+                   "If `n < 0`, then `bidirectional_iterator<I> && same_as<I, S>` must be true.");
+    // If `S` and `I` model `sized_sentinel_for<S, I>`:
+    if constexpr (sized_sentinel_for<_Sp, _Ip>) {
+      // If |n| >= |bound - i|, equivalent to `ranges::advance(i, bound)`.
+      if (const auto __M = __bound - __i; __magnitude_geq(__n, __M)) {
+        (*this)(__i, __bound);
+        return __n - __M;
+      }
+
+      // Otherwise, equivalent to `ranges::advance(i, n)`.
+      (*this)(__i, __n);
+      return 0;
+    } else {
+      // Otherwise, if `n` is non-negative, while `bool(i != bound)` is true, increments `i` but at
+      // most `n` times.
+      while (__i != __bound && __n > 0) {
+        ++__i;
+        --__n;
+      }
+
+      // Otherwise, while `bool(i != bound)` is true, decrements `i` but at most `-n` times.
+      if constexpr (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>) {
+        while (__i != __bound && __n < 0) {
+          --__i;
+          ++__n;
+        }
+      }
+      return __n;
+    }
+
+    _LIBCPP_UNREACHABLE();
+  }
+};
+
+inline constexpr auto advance = __advance_fn(__function_like::__tag());
+} // namespace ranges
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_ADVANCE_H
diff --git a/include/__iterator/back_insert_iterator.h b/include/__iterator/back_insert_iterator.h
new file mode 100644
index 0000000..f34cb86
--- /dev/null
+++ b/include/__iterator/back_insert_iterator.h
@@ -0,0 +1,75 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H
+#define _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H
+
+#include <__config>
+#include <__iterator/iterator.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <__utility/move.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Container>
+class _LIBCPP_TEMPLATE_VIS back_insert_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
+    : public iterator<output_iterator_tag, void, void, void, void>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+protected:
+    _Container* container;
+public:
+    typedef output_iterator_tag iterator_category;
+    typedef void value_type;
+#if _LIBCPP_STD_VER > 17
+    typedef ptrdiff_t difference_type;
+#else
+    typedef void difference_type;
+#endif
+    typedef void pointer;
+    typedef void reference;
+    typedef _Container container_type;
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(const typename _Container::value_type& __value_)
+        {container->push_back(__value_); return *this;}
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(typename _Container::value_type&& __value_)
+        {container->push_back(_VSTD::move(__value_)); return *this;}
+#endif // _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator*()     {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator++()    {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator  operator++(int) {return *this;}
+};
+
+template <class _Container>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+back_insert_iterator<_Container>
+back_inserter(_Container& __x)
+{
+    return back_insert_iterator<_Container>(__x);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H
diff --git a/include/__iterator/common_iterator.h b/include/__iterator/common_iterator.h
new file mode 100644
index 0000000..fb01d8b
--- /dev/null
+++ b/include/__iterator/common_iterator.h
@@ -0,0 +1,301 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_COMMON_ITERATOR_H
+#define _LIBCPP___ITERATOR_COMMON_ITERATOR_H
+
+#include <__config>
+#include <__debug>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/readable_traits.h>
+#include <concepts>
+#include <variant>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent>
+  requires (!same_as<_Iter, _Sent> && copyable<_Iter>)
+class common_iterator {
+  class __proxy {
+    friend common_iterator;
+
+    iter_value_t<_Iter> __value;
+    // We can move __x because the only caller verifies that __x is not a reference.
+    constexpr __proxy(iter_reference_t<_Iter>&& __x)
+      : __value(_VSTD::move(__x)) {}
+
+  public:
+    const iter_value_t<_Iter>* operator->() const {
+      return _VSTD::addressof(__value);
+    }
+  };
+
+  class __postfix_proxy {
+    friend common_iterator;
+
+    iter_value_t<_Iter> __value;
+    constexpr __postfix_proxy(iter_reference_t<_Iter>&& __x)
+      : __value(_VSTD::forward<iter_reference_t<_Iter>>(__x)) {}
+
+  public:
+    constexpr static bool __valid_for_iter =
+      constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>> &&
+      move_constructible<iter_value_t<_Iter>>;
+
+    const iter_value_t<_Iter>& operator*() const {
+      return __value;
+    }
+  };
+
+public:
+  variant<_Iter, _Sent> __hold_;
+
+  common_iterator() requires default_initializable<_Iter> = default;
+
+  constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, _VSTD::move(__i)) {}
+  constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, _VSTD::move(__s)) {}
+
+  template<class _I2, class _S2>
+    requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent>
+  constexpr common_iterator(const common_iterator<_I2, _S2>& __other)
+    : __hold_([&]() -> variant<_Iter, _Sent> {
+      _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Constructed from valueless iterator.");
+      if (__other.__hold_.index() == 0)
+        return variant<_Iter, _Sent>{in_place_index<0>, _VSTD::__unchecked_get<0>(__other.__hold_)};
+      return variant<_Iter, _Sent>{in_place_index<1>, _VSTD::__unchecked_get<1>(__other.__hold_)};
+    }()) {}
+
+  template<class _I2, class _S2>
+    requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent> &&
+             assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&>
+  common_iterator& operator=(const common_iterator<_I2, _S2>& __other) {
+    _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Assigned from valueless iterator.");
+
+    auto __idx = __hold_.index();
+    auto __other_idx = __other.__hold_.index();
+
+    // If they're the same index, just assign.
+    if (__idx == 0 && __other_idx == 0)
+      _VSTD::__unchecked_get<0>(__hold_) = _VSTD::__unchecked_get<0>(__other.__hold_);
+    else if (__idx == 1 && __other_idx == 1)
+      _VSTD::__unchecked_get<1>(__hold_) = _VSTD::__unchecked_get<1>(__other.__hold_);
+
+    // Otherwise replace with the oposite element.
+    else if (__other_idx == 1)
+      __hold_.template emplace<1>(_VSTD::__unchecked_get<1>(__other.__hold_));
+    else if (__other_idx == 0)
+      __hold_.template emplace<0>(_VSTD::__unchecked_get<0>(__other.__hold_));
+
+    return *this;
+  }
+
+  decltype(auto) operator*()
+  {
+    _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_),
+                   "Cannot dereference sentinel. Common iterator not holding an iterator.");
+    return *_VSTD::__unchecked_get<_Iter>(__hold_);
+  }
+
+  decltype(auto) operator*() const
+    requires __dereferenceable<const _Iter>
+  {
+    _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_),
+                   "Cannot dereference sentinel. Common iterator not holding an iterator.");
+    return *_VSTD::__unchecked_get<_Iter>(__hold_);
+  }
+
+  template<class _I2 = _Iter>
+  decltype(auto) operator->() const
+    requires indirectly_readable<const _I2> &&
+    (requires(const _I2& __i) { __i.operator->(); } ||
+     is_reference_v<iter_reference_t<_I2>> ||
+     constructible_from<iter_value_t<_I2>, iter_reference_t<_I2>>)
+  {
+    _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_),
+                   "Cannot dereference sentinel. Common iterator not holding an iterator.");
+
+    if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); })    {
+      return _VSTD::__unchecked_get<_Iter>(__hold_);
+    } else if constexpr (is_reference_v<iter_reference_t<_Iter>>) {
+      auto&& __tmp = *_VSTD::__unchecked_get<_Iter>(__hold_);
+      return _VSTD::addressof(__tmp);
+    } else {
+      return __proxy(*_VSTD::__unchecked_get<_Iter>(__hold_));
+    }
+  }
+
+  common_iterator& operator++() {
+    _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_),
+                   "Cannot increment sentinel. Common iterator not holding an iterator.");
+    ++_VSTD::__unchecked_get<_Iter>(__hold_); return *this;
+  }
+
+  decltype(auto) operator++(int) {
+    _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_),
+                   "Cannot increment sentinel. Common iterator not holding an iterator.");
+
+    if constexpr (forward_iterator<_Iter>) {
+      auto __tmp = *this;
+      ++*this;
+      return __tmp;
+    } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __referenceable; } ||
+                         !__postfix_proxy::__valid_for_iter) {
+      return _VSTD::__unchecked_get<_Iter>(__hold_)++;
+    } else {
+      __postfix_proxy __p(**this);
+      ++*this;
+      return __p;
+    }
+  }
+
+  template<class _I2, sentinel_for<_Iter> _S2>
+    requires sentinel_for<_Sent, _I2>
+  friend bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
+    _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() &&
+                   !__y.__hold_.valueless_by_exception(),
+                   "One or both common_iterators are valueless. (Cannot compare valueless iterators.)");
+
+    auto __x_index = __x.__hold_.index();
+    auto __y_index = __y.__hold_.index();
+
+    if (__x_index == __y_index)
+      return true;
+
+    if (__x_index == 0)
+      return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_S2>(__y.__hold_);
+
+    return _VSTD::__unchecked_get<_Sent>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_);
+  }
+
+  template<class _I2, sentinel_for<_Iter> _S2>
+    requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2>
+  friend bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
+    _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() &&
+                   !__y.__hold_.valueless_by_exception(),
+                   "One or both common_iterators are valueless. (Cannot compare valueless iterators.)");
+
+    auto __x_index = __x.__hold_.index();
+    auto __y_index = __y.__hold_.index();
+
+    if (__x_index == 1 && __y_index == 1)
+      return true;
+
+    if (__x_index == 0 && __y_index == 0)
+      return  _VSTD::__unchecked_get<_Iter>(__x.__hold_) ==  _VSTD::__unchecked_get<_I2>(__y.__hold_);
+
+    if (__x_index == 0)
+      return  _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_S2>(__y.__hold_);
+
+    return _VSTD::__unchecked_get<_Sent>(__x.__hold_) ==  _VSTD::__unchecked_get<_I2>(__y.__hold_);
+  }
+
+  template<sized_sentinel_for<_Iter> _I2, sized_sentinel_for<_Iter> _S2>
+    requires sized_sentinel_for<_Sent, _I2>
+  friend iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) {
+    _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() &&
+                   !__y.__hold_.valueless_by_exception(),
+                   "One or both common_iterators are valueless. (Cannot subtract valueless iterators.)");
+
+    auto __x_index = __x.__hold_.index();
+    auto __y_index = __y.__hold_.index();
+
+    if (__x_index == 1 && __y_index == 1)
+      return 0;
+
+    if (__x_index == 0 && __y_index == 0)
+      return  _VSTD::__unchecked_get<_Iter>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_);
+
+    if (__x_index == 0)
+      return  _VSTD::__unchecked_get<_Iter>(__x.__hold_) - _VSTD::__unchecked_get<_S2>(__y.__hold_);
+
+    return _VSTD::__unchecked_get<_Sent>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_);
+  }
+
+  friend iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i)
+    noexcept(noexcept(ranges::iter_move(declval<const _Iter&>())))
+      requires input_iterator<_Iter>
+  {
+    _LIBCPP_ASSERT(holds_alternative<_Iter>(__i.__hold_),
+                   "Cannot iter_move a sentinel. Common iterator not holding an iterator.");
+    return ranges::iter_move( _VSTD::__unchecked_get<_Iter>(__i.__hold_));
+  }
+
+  template<indirectly_swappable<_Iter> _I2, class _S2>
+  friend void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y)
+      noexcept(noexcept(ranges::iter_swap(declval<const _Iter&>(), declval<const _I2&>())))
+  {
+    _LIBCPP_ASSERT(holds_alternative<_Iter>(__x.__hold_),
+                   "Cannot swap __y with a sentinel. Common iterator (__x) not holding an iterator.");
+    _LIBCPP_ASSERT(holds_alternative<_Iter>(__y.__hold_),
+                   "Cannot swap __x with a sentinel. Common iterator (__y) not holding an iterator.");
+    return ranges::iter_swap( _VSTD::__unchecked_get<_Iter>(__x.__hold_),  _VSTD::__unchecked_get<_Iter>(__y.__hold_));
+  }
+};
+
+template<class _Iter, class _Sent>
+struct incrementable_traits<common_iterator<_Iter, _Sent>> {
+  using difference_type = iter_difference_t<_Iter>;
+};
+
+template<class _Iter>
+concept __denotes_forward_iter =
+  requires { typename iterator_traits<_Iter>::iterator_category; } &&
+  derived_from<typename iterator_traits<_Iter>::iterator_category, forward_iterator_tag>;
+
+template<class _Iter, class _Sent>
+concept __common_iter_has_ptr_op = requires(const common_iterator<_Iter, _Sent>& __a) {
+  __a.operator->();
+};
+
+template<class, class>
+struct __arrow_type_or_void {
+    using type = void;
+};
+
+template<class _Iter, class _Sent>
+  requires __common_iter_has_ptr_op<_Iter, _Sent>
+struct __arrow_type_or_void<_Iter, _Sent> {
+    using type = decltype(declval<const common_iterator<_Iter, _Sent>>().operator->());
+};
+
+template<class _Iter, class _Sent>
+struct iterator_traits<common_iterator<_Iter, _Sent>> {
+  using iterator_concept = _If<forward_iterator<_Iter>,
+                               forward_iterator_tag,
+                               input_iterator_tag>;
+  using iterator_category = _If<__denotes_forward_iter<_Iter>,
+                                forward_iterator_tag,
+                                input_iterator_tag>;
+  using pointer = typename __arrow_type_or_void<_Iter, _Sent>::type;
+  using value_type = iter_value_t<_Iter>;
+  using difference_type = iter_difference_t<_Iter>;
+  using reference = iter_reference_t<_Iter>;
+};
+
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_COMMON_ITERATOR_H
diff --git a/include/__iterator/concepts.h b/include/__iterator/concepts.h
new file mode 100644
index 0000000..6eb4aef
--- /dev/null
+++ b/include/__iterator/concepts.h
@@ -0,0 +1,272 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_CONCEPTS_H
+#define _LIBCPP___ITERATOR_CONCEPTS_H
+
+#include <__config>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/readable_traits.h>
+#include <__memory/pointer_traits.h>
+#include <__utility/forward.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+// clang-format off
+
+// [iterator.concept.readable]
+template<class _In>
+concept __indirectly_readable_impl =
+  requires(const _In __i) {
+    typename iter_value_t<_In>;
+    typename iter_reference_t<_In>;
+    typename iter_rvalue_reference_t<_In>;
+    { *__i } -> same_as<iter_reference_t<_In>>;
+    { ranges::iter_move(__i) } -> same_as<iter_rvalue_reference_t<_In>>;
+  } &&
+  common_reference_with<iter_reference_t<_In>&&, iter_value_t<_In>&> &&
+  common_reference_with<iter_reference_t<_In>&&, iter_rvalue_reference_t<_In>&&> &&
+  common_reference_with<iter_rvalue_reference_t<_In>&&, const iter_value_t<_In>&>;
+
+template<class _In>
+concept indirectly_readable = __indirectly_readable_impl<remove_cvref_t<_In>>;
+
+template<indirectly_readable _Tp>
+using iter_common_reference_t = common_reference_t<iter_reference_t<_Tp>, iter_value_t<_Tp>&>;
+
+// [iterator.concept.writable]
+template<class _Out, class _Tp>
+concept indirectly_writable =
+  requires(_Out&& __o, _Tp&& __t) {
+    *__o = _VSTD::forward<_Tp>(__t);                        // not required to be equality-preserving
+    *_VSTD::forward<_Out>(__o) = _VSTD::forward<_Tp>(__t);  // not required to be equality-preserving
+    const_cast<const iter_reference_t<_Out>&&>(*__o) = _VSTD::forward<_Tp>(__t);                       // not required to be equality-preserving
+    const_cast<const iter_reference_t<_Out>&&>(*_VSTD::forward<_Out>(__o)) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
+  };
+
+// [iterator.concept.winc]
+template<class _Tp>
+concept __integer_like = integral<_Tp> && !same_as<_Tp, bool>;
+
+template<class _Tp>
+concept __signed_integer_like = signed_integral<_Tp>;
+
+template<class _Ip>
+concept weakly_incrementable =
+  movable<_Ip> &&
+  requires(_Ip __i) {
+    typename iter_difference_t<_Ip>;
+    requires __signed_integer_like<iter_difference_t<_Ip>>;
+    { ++__i } -> same_as<_Ip&>;   // not required to be equality-preserving
+    __i++;                        // not required to be equality-preserving
+  };
+
+// [iterator.concept.inc]
+template<class _Ip>
+concept incrementable =
+  regular<_Ip> &&
+  weakly_incrementable<_Ip> &&
+  requires(_Ip __i) {
+    { __i++ } -> same_as<_Ip>;
+  };
+
+// [iterator.concept.iterator]
+template<class _Ip>
+concept input_or_output_iterator =
+  requires(_Ip __i) {
+    { *__i } -> __referenceable;
+  } &&
+  weakly_incrementable<_Ip>;
+
+// [iterator.concept.sentinel]
+template<class _Sp, class _Ip>
+concept sentinel_for =
+  semiregular<_Sp> &&
+  input_or_output_iterator<_Ip> &&
+  __weakly_equality_comparable_with<_Sp, _Ip>;
+
+template<class, class>
+inline constexpr bool disable_sized_sentinel_for = false;
+
+template<class _Sp, class _Ip>
+concept sized_sentinel_for =
+  sentinel_for<_Sp, _Ip> &&
+  !disable_sized_sentinel_for<remove_cv_t<_Sp>, remove_cv_t<_Ip>> &&
+  requires(const _Ip& __i, const _Sp& __s) {
+    { __s - __i } -> same_as<iter_difference_t<_Ip>>;
+    { __i - __s } -> same_as<iter_difference_t<_Ip>>;
+  };
+
+// [iterator.concept.input]
+template<class _Ip>
+concept input_iterator =
+  input_or_output_iterator<_Ip> &&
+  indirectly_readable<_Ip> &&
+  requires { typename _ITER_CONCEPT<_Ip>; } &&
+  derived_from<_ITER_CONCEPT<_Ip>, input_iterator_tag>;
+
+// [iterator.concept.output]
+template<class _Ip, class _Tp>
+concept output_iterator =
+  input_or_output_iterator<_Ip> &&
+  indirectly_writable<_Ip, _Tp> &&
+  requires (_Ip __it, _Tp&& __t) {
+    *__it++ = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving
+  };
+
+// [iterator.concept.forward]
+template<class _Ip>
+concept forward_iterator =
+  input_iterator<_Ip> &&
+  derived_from<_ITER_CONCEPT<_Ip>, forward_iterator_tag> &&
+  incrementable<_Ip> &&
+  sentinel_for<_Ip, _Ip>;
+
+// [iterator.concept.bidir]
+template<class _Ip>
+concept bidirectional_iterator =
+  forward_iterator<_Ip> &&
+  derived_from<_ITER_CONCEPT<_Ip>, bidirectional_iterator_tag> &&
+  requires(_Ip __i) {
+    { --__i } -> same_as<_Ip&>;
+    { __i-- } -> same_as<_Ip>;
+  };
+
+template<class _Ip>
+concept random_access_iterator =
+  bidirectional_iterator<_Ip> &&
+  derived_from<_ITER_CONCEPT<_Ip>, random_access_iterator_tag> &&
+  totally_ordered<_Ip> &&
+  sized_sentinel_for<_Ip, _Ip> &&
+  requires(_Ip __i, const _Ip __j, const iter_difference_t<_Ip> __n) {
+    { __i += __n } -> same_as<_Ip&>;
+    { __j +  __n } -> same_as<_Ip>;
+    { __n +  __j } -> same_as<_Ip>;
+    { __i -= __n } -> same_as<_Ip&>;
+    { __j -  __n } -> same_as<_Ip>;
+    {  __j[__n]  } -> same_as<iter_reference_t<_Ip>>;
+  };
+
+template<class _Ip>
+concept contiguous_iterator =
+  random_access_iterator<_Ip> &&
+  derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> &&
+  is_lvalue_reference_v<iter_reference_t<_Ip>> &&
+  same_as<iter_value_t<_Ip>, remove_cvref_t<iter_reference_t<_Ip>>> &&
+  (is_pointer_v<_Ip> || requires { sizeof(__pointer_traits_element_type<_Ip>); }) &&
+  requires(const _Ip& __i) {
+    { _VSTD::to_address(__i) } -> same_as<add_pointer_t<iter_reference_t<_Ip>>>;
+  };
+
+template<class _Ip>
+concept __has_arrow = input_iterator<_Ip> && (is_pointer_v<_Ip> || requires(_Ip __i) { __i.operator->(); });
+
+// [indirectcallable.indirectinvocable]
+template<class _Fp, class _It>
+concept indirectly_unary_invocable =
+  indirectly_readable<_It> &&
+  copy_constructible<_Fp> &&
+  invocable<_Fp&, iter_value_t<_It>&> &&
+  invocable<_Fp&, iter_reference_t<_It>> &&
+  invocable<_Fp&, iter_common_reference_t<_It>> &&
+  common_reference_with<
+    invoke_result_t<_Fp&, iter_value_t<_It>&>,
+    invoke_result_t<_Fp&, iter_reference_t<_It>>>;
+
+template<class _Fp, class _It>
+concept indirectly_regular_unary_invocable =
+  indirectly_readable<_It> &&
+  copy_constructible<_Fp> &&
+  regular_invocable<_Fp&, iter_value_t<_It>&> &&
+  regular_invocable<_Fp&, iter_reference_t<_It>> &&
+  regular_invocable<_Fp&, iter_common_reference_t<_It>> &&
+  common_reference_with<
+    invoke_result_t<_Fp&, iter_value_t<_It>&>,
+    invoke_result_t<_Fp&, iter_reference_t<_It>>>;
+
+template<class _Fp, class _It>
+concept indirect_unary_predicate =
+  indirectly_readable<_It> &&
+  copy_constructible<_Fp> &&
+  predicate<_Fp&, iter_value_t<_It>&> &&
+  predicate<_Fp&, iter_reference_t<_It>> &&
+  predicate<_Fp&, iter_common_reference_t<_It>>;
+
+template<class _Fp, class _It1, class _It2>
+concept indirect_binary_predicate =
+  indirectly_readable<_It1> && indirectly_readable<_It2> &&
+  copy_constructible<_Fp> &&
+  predicate<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
+  predicate<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
+  predicate<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
+  predicate<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> &&
+  predicate<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
+
+template<class _Fp, class _It1, class _It2 = _It1>
+concept indirect_equivalence_relation =
+  indirectly_readable<_It1> && indirectly_readable<_It2> &&
+  copy_constructible<_Fp> &&
+  equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
+  equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
+  equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
+  equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> &&
+  equivalence_relation<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
+
+template<class _Fp, class _It1, class _It2 = _It1>
+concept indirect_strict_weak_order =
+  indirectly_readable<_It1> && indirectly_readable<_It2> &&
+  copy_constructible<_Fp> &&
+  strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
+  strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
+  strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
+  strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> &&
+  strict_weak_order<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
+
+template<class _Fp, class... _Its>
+  requires (indirectly_readable<_Its> && ...) && invocable<_Fp, iter_reference_t<_Its>...>
+using indirect_result_t = invoke_result_t<_Fp, iter_reference_t<_Its>...>;
+
+template<class _In, class _Out>
+concept indirectly_movable =
+  indirectly_readable<_In> &&
+  indirectly_writable<_Out, iter_rvalue_reference_t<_In>>;
+
+template<class _In, class _Out>
+concept indirectly_movable_storable =
+  indirectly_movable<_In, _Out> &&
+  indirectly_writable<_Out, iter_value_t<_In>> &&
+  movable<iter_value_t<_In>> &&
+  constructible_from<iter_value_t<_In>, iter_rvalue_reference_t<_In>> &&
+  assignable_from<iter_value_t<_In>&, iter_rvalue_reference_t<_In>>;
+
+// Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle
+// (both iter_swap and indirectly_swappable require indirectly_readable).
+
+// clang-format on
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_CONCEPTS_H
diff --git a/include/__iterator/counted_iterator.h b/include/__iterator/counted_iterator.h
new file mode 100644
index 0000000..7136aaf
--- /dev/null
+++ b/include/__iterator/counted_iterator.h
@@ -0,0 +1,306 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___ITERATOR_COUNTED_ITERATOR_H
+#define _LIBCPP___ITERATOR_COUNTED_ITERATOR_H
+
+#include <__config>
+#include <__debug>
+#include <__iterator/concepts.h>
+#include <__iterator/default_sentinel.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/readable_traits.h>
+#include <__memory/pointer_traits.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+template<class>
+struct __counted_iterator_concept {};
+
+template<class _Iter>
+  requires requires { typename _Iter::iterator_concept; }
+struct __counted_iterator_concept<_Iter> {
+  using iterator_concept = typename _Iter::iterator_concept;
+};
+
+template<class>
+struct __counted_iterator_category {};
+
+template<class _Iter>
+  requires requires { typename _Iter::iterator_category; }
+struct __counted_iterator_category<_Iter> {
+  using iterator_category = typename _Iter::iterator_category;
+};
+
+template<class>
+struct __counted_iterator_value_type {};
+
+template<indirectly_readable _Iter>
+struct __counted_iterator_value_type<_Iter> {
+  using value_type = iter_value_t<_Iter>;
+};
+
+template<input_or_output_iterator _Iter>
+class counted_iterator
+  : public __counted_iterator_concept<_Iter>
+  , public __counted_iterator_category<_Iter>
+  , public __counted_iterator_value_type<_Iter>
+{
+public:
+  [[no_unique_address]] _Iter __current_ = _Iter();
+  iter_difference_t<_Iter> __count_ = 0;
+
+  using iterator_type = _Iter;
+  using difference_type = iter_difference_t<_Iter>;
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr counted_iterator() requires default_initializable<_Iter> = default;
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr counted_iterator(_Iter __iter, iter_difference_t<_Iter> __n)
+   : __current_(_VSTD::move(__iter)), __count_(__n) {
+    _LIBCPP_ASSERT(__n >= 0, "__n must not be negative.");
+  }
+
+  template<class _I2>
+    requires convertible_to<const _I2&, _Iter>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr counted_iterator(const counted_iterator<_I2>& __other)
+   : __current_(__other.__current_), __count_(__other.__count_) {}
+
+  template<class _I2>
+    requires assignable_from<_Iter&, const _I2&>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr counted_iterator& operator=(const counted_iterator<_I2>& __other) {
+    __current_ = __other.__current_;
+    __count_ = __other.__count_;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr const _Iter& base() const& { return __current_; }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _Iter base() && { return _VSTD::move(__current_); }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr iter_difference_t<_Iter> count() const noexcept { return __count_; }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr decltype(auto) operator*() {
+    _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end.");
+    return *__current_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr decltype(auto) operator*() const
+    requires __dereferenceable<const _Iter>
+  {
+    _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end.");
+    return *__current_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto operator->() const noexcept
+    requires contiguous_iterator<_Iter>
+  {
+    return _VSTD::to_address(__current_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr counted_iterator& operator++() {
+    _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
+    ++__current_;
+    --__count_;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  decltype(auto) operator++(int) {
+    _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
+    --__count_;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try { return __current_++; }
+    catch(...) { ++__count_; throw; }
+#else
+    return __current_++;
+#endif // _LIBCPP_NO_EXCEPTIONS
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr counted_iterator operator++(int)
+    requires forward_iterator<_Iter>
+  {
+    _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end.");
+    counted_iterator __tmp = *this;
+    ++*this;
+    return __tmp;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr counted_iterator& operator--()
+    requires bidirectional_iterator<_Iter>
+  {
+    --__current_;
+    ++__count_;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr counted_iterator operator--(int)
+    requires bidirectional_iterator<_Iter>
+  {
+    counted_iterator __tmp = *this;
+    --*this;
+    return __tmp;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr counted_iterator operator+(iter_difference_t<_Iter> __n) const
+    requires random_access_iterator<_Iter>
+  {
+    return counted_iterator(__current_ + __n, __count_ - __n);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr counted_iterator operator+(
+    iter_difference_t<_Iter> __n, const counted_iterator& __x)
+    requires random_access_iterator<_Iter>
+  {
+    return __x + __n;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr counted_iterator& operator+=(iter_difference_t<_Iter> __n)
+    requires random_access_iterator<_Iter>
+  {
+    _LIBCPP_ASSERT(__n <= __count_, "Cannot advance iterator past end.");
+    __current_ += __n;
+    __count_ -= __n;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr counted_iterator operator-(iter_difference_t<_Iter> __n) const
+    requires random_access_iterator<_Iter>
+  {
+    return counted_iterator(__current_ - __n, __count_ + __n);
+  }
+
+  template<common_with<_Iter> _I2>
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr iter_difference_t<_I2> operator-(
+    const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs)
+  {
+    return __rhs.__count_ - __lhs.__count_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr iter_difference_t<_Iter> operator-(
+    const counted_iterator& __lhs, default_sentinel_t)
+  {
+    return -__lhs.__count_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr iter_difference_t<_Iter> operator-(
+    default_sentinel_t, const counted_iterator& __rhs)
+  {
+    return __rhs.__count_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr counted_iterator& operator-=(iter_difference_t<_Iter> __n)
+    requires random_access_iterator<_Iter>
+  {
+    _LIBCPP_ASSERT(-__n <= __count_, "Attempt to subtract too large of a size: "
+                                     "counted_iterator would be decremented before the "
+                                     "first element of its range.");
+    __current_ -= __n;
+    __count_ += __n;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const
+    requires random_access_iterator<_Iter>
+  {
+    _LIBCPP_ASSERT(__n < __count_, "Subscript argument must be less than size.");
+    return __current_[__n];
+  }
+
+  template<common_with<_Iter> _I2>
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr bool operator==(
+    const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs)
+  {
+    return __lhs.__count_ == __rhs.__count_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr bool operator==(
+    const counted_iterator& __lhs, default_sentinel_t)
+  {
+    return __lhs.__count_ == 0;
+  }
+
+  template<common_with<_Iter> _I2>
+  friend constexpr strong_ordering operator<=>(
+    const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs)
+  {
+    return __rhs.__count_ <=> __lhs.__count_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const counted_iterator& __i)
+    noexcept(noexcept(ranges::iter_move(__i.__current_)))
+      requires input_iterator<_Iter>
+  {
+    _LIBCPP_ASSERT(__i.__count_ > 0, "Iterator must not be past end of range.");
+    return ranges::iter_move(__i.__current_);
+  }
+
+  template<indirectly_swappable<_Iter> _I2>
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr void iter_swap(const counted_iterator& __x, const counted_iterator<_I2>& __y)
+    noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_)))
+  {
+    _LIBCPP_ASSERT(__x.__count_ > 0 && __y.__count_ > 0,
+                   "Iterators must not be past end of range.");
+    return ranges::iter_swap(__x.__current_, __y.__current_);
+  }
+};
+
+template<input_iterator _Iter>
+  requires same_as<_ITER_TRAITS<_Iter>, iterator_traits<_Iter>>
+struct iterator_traits<counted_iterator<_Iter>> : iterator_traits<_Iter> {
+  using pointer = conditional_t<contiguous_iterator<_Iter>,
+                                add_pointer_t<iter_reference_t<_Iter>>, void>;
+};
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_COUNTED_ITERATOR_H
diff --git a/include/__iterator/data.h b/include/__iterator/data.h
new file mode 100644
index 0000000..cd8e37b
--- /dev/null
+++ b/include/__iterator/data.h
@@ -0,0 +1,56 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_DATA_H
+#define _LIBCPP___ITERATOR_DATA_H
+
+#include <__config>
+#include <cstddef>
+#include <initializer_list>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+template <class _Cont> constexpr
+_LIBCPP_INLINE_VISIBILITY
+auto data(_Cont& __c)
+_NOEXCEPT_(noexcept(__c.data()))
+-> decltype        (__c.data())
+{ return            __c.data(); }
+
+template <class _Cont> constexpr
+_LIBCPP_INLINE_VISIBILITY
+auto data(const _Cont& __c)
+_NOEXCEPT_(noexcept(__c.data()))
+-> decltype        (__c.data())
+{ return            __c.data(); }
+
+template <class _Tp, size_t _Sz>
+_LIBCPP_INLINE_VISIBILITY
+constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; }
+
+template <class _Ep>
+_LIBCPP_INLINE_VISIBILITY
+constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); }
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_DATA_H
diff --git a/include/__iterator/default_sentinel.h b/include/__iterator/default_sentinel.h
new file mode 100644
index 0000000..934a56f
--- /dev/null
+++ b/include/__iterator/default_sentinel.h
@@ -0,0 +1,35 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H
+#define _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+struct default_sentinel_t { };
+inline constexpr default_sentinel_t default_sentinel{};
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H
diff --git a/include/__iterator/distance.h b/include/__iterator/distance.h
new file mode 100644
index 0000000..33e4af8
--- /dev/null
+++ b/include/__iterator/distance.h
@@ -0,0 +1,56 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_DISTANCE_H
+#define _LIBCPP___ITERATOR_DISTANCE_H
+
+#include <__config>
+#include <__iterator/iterator_traits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIter>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+typename iterator_traits<_InputIter>::difference_type
+__distance(_InputIter __first, _InputIter __last, input_iterator_tag)
+{
+    typename iterator_traits<_InputIter>::difference_type __r(0);
+    for (; __first != __last; ++__first)
+        ++__r;
+    return __r;
+}
+
+template <class _RandIter>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+typename iterator_traits<_RandIter>::difference_type
+__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag)
+{
+    return __last - __first;
+}
+
+template <class _InputIter>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+typename iterator_traits<_InputIter>::difference_type
+distance(_InputIter __first, _InputIter __last)
+{
+    return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_DISTANCE_H
diff --git a/include/__iterator/empty.h b/include/__iterator/empty.h
new file mode 100644
index 0000000..4dd59f5
--- /dev/null
+++ b/include/__iterator/empty.h
@@ -0,0 +1,49 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_EMPTY_H
+#define _LIBCPP___ITERATOR_EMPTY_H
+
+#include <__config>
+#include <cstddef>
+#include <initializer_list>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+template <class _Cont>
+_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
+constexpr auto empty(const _Cont& __c)
+_NOEXCEPT_(noexcept(__c.empty()))
+-> decltype        (__c.empty())
+{ return            __c.empty(); }
+
+template <class _Tp, size_t _Sz>
+_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
+constexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; }
+
+template <class _Ep>
+_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
+constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; }
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_EMPTY_H
diff --git a/include/__iterator/erase_if_container.h b/include/__iterator/erase_if_container.h
new file mode 100644
index 0000000..a5dfd07
--- /dev/null
+++ b/include/__iterator/erase_if_container.h
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H
+#define _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Container, class _Predicate>
+_LIBCPP_HIDE_FROM_ABI
+typename _Container::size_type
+__libcpp_erase_if_container(_Container& __c, _Predicate& __pred) {
+  typename _Container::size_type __old_size = __c.size();
+
+  const typename _Container::iterator __last = __c.end();
+  for (typename _Container::iterator __iter = __c.begin(); __iter != __last;) {
+    if (__pred(*__iter))
+      __iter = __c.erase(__iter);
+    else
+      ++__iter;
+  }
+
+  return __old_size - __c.size();
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H
diff --git a/include/__iterator/front_insert_iterator.h b/include/__iterator/front_insert_iterator.h
new file mode 100644
index 0000000..0421dd5
--- /dev/null
+++ b/include/__iterator/front_insert_iterator.h
@@ -0,0 +1,75 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H
+#define _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H
+
+#include <__config>
+#include <__iterator/iterator.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <__utility/move.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Container>
+class _LIBCPP_TEMPLATE_VIS front_insert_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
+    : public iterator<output_iterator_tag, void, void, void, void>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+protected:
+    _Container* container;
+public:
+    typedef output_iterator_tag iterator_category;
+    typedef void value_type;
+#if _LIBCPP_STD_VER > 17
+    typedef ptrdiff_t difference_type;
+#else
+    typedef void difference_type;
+#endif
+    typedef void pointer;
+    typedef void reference;
+    typedef _Container container_type;
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(const typename _Container::value_type& __value_)
+        {container->push_front(__value_); return *this;}
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(typename _Container::value_type&& __value_)
+        {container->push_front(_VSTD::move(__value_)); return *this;}
+#endif // _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator*()     {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator++()    {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator  operator++(int) {return *this;}
+};
+
+template <class _Container>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+front_insert_iterator<_Container>
+front_inserter(_Container& __x)
+{
+    return front_insert_iterator<_Container>(__x);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H
diff --git a/include/__iterator/incrementable_traits.h b/include/__iterator/incrementable_traits.h
new file mode 100644
index 0000000..5a43398
--- /dev/null
+++ b/include/__iterator/incrementable_traits.h
@@ -0,0 +1,77 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H
+#define _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H
+
+#include <__config>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+// [incrementable.traits]
+template<class> struct incrementable_traits {};
+
+template<class _Tp>
+requires is_object_v<_Tp>
+struct incrementable_traits<_Tp*> {
+  using difference_type = ptrdiff_t;
+};
+
+template<class _Ip>
+struct incrementable_traits<const _Ip> : incrementable_traits<_Ip> {};
+
+template<class _Tp>
+concept __has_member_difference_type = requires { typename _Tp::difference_type; };
+
+template<__has_member_difference_type _Tp>
+struct incrementable_traits<_Tp> {
+  using difference_type = typename _Tp::difference_type;
+};
+
+template<class _Tp>
+concept __has_integral_minus =
+  requires(const _Tp& __x, const _Tp& __y) {
+    { __x - __y } -> integral;
+  };
+
+template<__has_integral_minus _Tp>
+requires (!__has_member_difference_type<_Tp>)
+struct incrementable_traits<_Tp> {
+  using difference_type = make_signed_t<decltype(declval<_Tp>() - declval<_Tp>())>;
+};
+
+template <class>
+struct iterator_traits;
+
+// Let `RI` be `remove_cvref_t<I>`. The type `iter_difference_t<I>` denotes
+// `incrementable_traits<RI>::difference_type` if `iterator_traits<RI>` names a specialization
+// generated from the primary template, and `iterator_traits<RI>::difference_type` otherwise.
+template <class _Ip>
+using iter_difference_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value,
+                                                 incrementable_traits<remove_cvref_t<_Ip> >,
+                                                 iterator_traits<remove_cvref_t<_Ip> > >::difference_type;
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H
diff --git a/include/__iterator/insert_iterator.h b/include/__iterator/insert_iterator.h
new file mode 100644
index 0000000..2658141
--- /dev/null
+++ b/include/__iterator/insert_iterator.h
@@ -0,0 +1,77 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_INSERT_ITERATOR_H
+#define _LIBCPP___ITERATOR_INSERT_ITERATOR_H
+
+#include <__config>
+#include <__iterator/iterator.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <__utility/move.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Container>
+class _LIBCPP_TEMPLATE_VIS insert_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
+    : public iterator<output_iterator_tag, void, void, void, void>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+protected:
+    _Container* container;
+    typename _Container::iterator iter; // FIXME: `ranges::iterator_t<Container>` in C++20 mode
+public:
+    typedef output_iterator_tag iterator_category;
+    typedef void value_type;
+#if _LIBCPP_STD_VER > 17
+    typedef ptrdiff_t difference_type;
+#else
+    typedef void difference_type;
+#endif
+    typedef void pointer;
+    typedef void reference;
+    typedef _Container container_type;
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator(_Container& __x, typename _Container::iterator __i)
+        : container(_VSTD::addressof(__x)), iter(__i) {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(const typename _Container::value_type& __value_)
+        {iter = container->insert(iter, __value_); ++iter; return *this;}
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(typename _Container::value_type&& __value_)
+        {iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;}
+#endif // _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator*()        {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++()       {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++(int)    {return *this;}
+};
+
+template <class _Container>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+insert_iterator<_Container>
+inserter(_Container& __x, typename _Container::iterator __i)
+{
+    return insert_iterator<_Container>(__x, __i);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_INSERT_ITERATOR_H
diff --git a/include/__iterator/istream_iterator.h b/include/__iterator/istream_iterator.h
new file mode 100644
index 0000000..f39faa6
--- /dev/null
+++ b/include/__iterator/istream_iterator.h
@@ -0,0 +1,103 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H
+#define _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H
+
+#include <__config>
+#include <__iterator/iterator.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <iosfwd> // for forward declarations of char_traits and basic_istream
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Tp, class _CharT = char,
+          class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
+class _LIBCPP_TEMPLATE_VIS istream_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
+    : public iterator<input_iterator_tag, _Tp, _Distance, const _Tp*, const _Tp&>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+public:
+    typedef input_iterator_tag iterator_category;
+    typedef _Tp value_type;
+    typedef _Distance difference_type;
+    typedef const _Tp* pointer;
+    typedef const _Tp& reference;
+    typedef _CharT char_type;
+    typedef _Traits traits_type;
+    typedef basic_istream<_CharT,_Traits> istream_type;
+private:
+    istream_type* __in_stream_;
+    _Tp __value_;
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {}
+    _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s))
+        {
+            if (!(*__in_stream_ >> __value_))
+                __in_stream_ = nullptr;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;}
+    _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return _VSTD::addressof((operator*()));}
+    _LIBCPP_INLINE_VISIBILITY istream_iterator& operator++()
+        {
+            if (!(*__in_stream_ >> __value_))
+                __in_stream_ = nullptr;
+            return *this;
+        }
+    _LIBCPP_INLINE_VISIBILITY istream_iterator  operator++(int)
+        {istream_iterator __t(*this); ++(*this); return __t;}
+
+    template <class _Up, class _CharU, class _TraitsU, class _DistanceU>
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool
+    operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
+               const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
+
+    template <class _Up, class _CharU, class _TraitsU, class _DistanceU>
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool
+    operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
+               const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
+};
+
+template <class _Tp, class _CharT, class _Traits, class _Distance>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
+           const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
+{
+    return __x.__in_stream_ == __y.__in_stream_;
+}
+
+template <class _Tp, class _CharT, class _Traits, class _Distance>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
+           const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y)
+{
+    return !(__x == __y);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H
diff --git a/include/__iterator/istreambuf_iterator.h b/include/__iterator/istreambuf_iterator.h
new file mode 100644
index 0000000..119698d
--- /dev/null
+++ b/include/__iterator/istreambuf_iterator.h
@@ -0,0 +1,110 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H
+#define _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H
+
+#include <__config>
+#include <__iterator/iterator.h>
+#include <__iterator/iterator_traits.h>
+#include <iosfwd> // for forward declaration of basic_streambuf
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template<class _CharT, class _Traits>
+class _LIBCPP_TEMPLATE_VIS istreambuf_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
+    : public iterator<input_iterator_tag, _CharT,
+                      typename _Traits::off_type, _CharT*,
+                      _CharT>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+public:
+    typedef input_iterator_tag              iterator_category;
+    typedef _CharT                          value_type;
+    typedef typename _Traits::off_type      difference_type;
+    typedef _CharT*                         pointer;
+    typedef _CharT                          reference;
+    typedef _CharT                          char_type;
+    typedef _Traits                         traits_type;
+    typedef typename _Traits::int_type      int_type;
+    typedef basic_streambuf<_CharT,_Traits> streambuf_type;
+    typedef basic_istream<_CharT,_Traits>   istream_type;
+private:
+    mutable streambuf_type* __sbuf_;
+
+    class __proxy
+    {
+        char_type __keep_;
+        streambuf_type* __sbuf_;
+        _LIBCPP_INLINE_VISIBILITY __proxy(char_type __c, streambuf_type* __s)
+            : __keep_(__c), __sbuf_(__s) {}
+        friend class istreambuf_iterator;
+    public:
+        _LIBCPP_INLINE_VISIBILITY char_type operator*() const {return __keep_;}
+    };
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool __test_for_eof() const
+    {
+        if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof()))
+            __sbuf_ = nullptr;
+        return __sbuf_ == nullptr;
+    }
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {}
+    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
+        : __sbuf_(__s.rdbuf()) {}
+    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
+        : __sbuf_(__s) {}
+    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT
+        : __sbuf_(__p.__sbuf_) {}
+
+    _LIBCPP_INLINE_VISIBILITY char_type  operator*() const
+        {return static_cast<char_type>(__sbuf_->sgetc());}
+    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++()
+        {
+            __sbuf_->sbumpc();
+            return *this;
+        }
+    _LIBCPP_INLINE_VISIBILITY __proxy              operator++(int)
+        {
+            return __proxy(__sbuf_->sbumpc(), __sbuf_);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
+        {return __test_for_eof() == __b.__test_for_eof();}
+};
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a,
+                const istreambuf_iterator<_CharT,_Traits>& __b)
+                {return __a.equal(__b);}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a,
+                const istreambuf_iterator<_CharT,_Traits>& __b)
+                {return !__a.equal(__b);}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H
diff --git a/include/__iterator/iter_move.h b/include/__iterator/iter_move.h
new file mode 100644
index 0000000..5540799
--- /dev/null
+++ b/include/__iterator/iter_move.h
@@ -0,0 +1,91 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_ITER_MOVE_H
+#define _LIBCPP___ITERATOR_ITER_MOVE_H
+
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__utility/forward.h>
+#include <concepts> // __class_or_enum
+#include <type_traits>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges::__iter_move {
+void iter_move();
+
+template<class _Ip>
+concept __unqualified_iter_move = requires(_Ip&& __i) {
+    iter_move(_VSTD::forward<_Ip>(__i));
+};
+
+// [iterator.cust.move]/1
+// The name ranges::iter_move denotes a customization point object.
+// The expression ranges::iter_move(E) for a subexpression E is
+// expression-equivalent to:
+struct __fn {
+  // [iterator.cust.move]/1.1
+  // iter_move(E), if E has class or enumeration type and iter_move(E) is a
+  // well-formed expression when treated as an unevaluated operand, [...]
+  template<class _Ip>
+    requires __class_or_enum<remove_cvref_t<_Ip>> && __unqualified_iter_move<_Ip>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const
+    noexcept(noexcept(iter_move(_VSTD::forward<_Ip>(__i))))
+  {
+    return iter_move(_VSTD::forward<_Ip>(__i));
+  }
+
+  // [iterator.cust.move]/1.2
+  // Otherwise, if the expression *E is well-formed:
+  //  1.2.1 if *E is an lvalue, std::move(*E);
+  //  1.2.2 otherwise, *E.
+  template<class _Ip>
+    requires (!(__class_or_enum<remove_cvref_t<_Ip>> && __unqualified_iter_move<_Ip>)) &&
+    requires(_Ip&& __i) { *_VSTD::forward<_Ip>(__i); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const
+    noexcept(noexcept(*_VSTD::forward<_Ip>(__i)))
+  {
+    if constexpr (is_lvalue_reference_v<decltype(*_VSTD::forward<_Ip>(__i))>) {
+      return _VSTD::move(*_VSTD::forward<_Ip>(__i));
+    } else {
+      return *_VSTD::forward<_Ip>(__i);
+    }
+  }
+
+  // [iterator.cust.move]/1.3
+  // Otherwise, ranges::iter_move(E) is ill-formed.
+};
+} // namespace ranges::__iter_move
+
+namespace ranges::inline __cpo {
+  inline constexpr auto iter_move = __iter_move::__fn{};
+}
+
+template<__dereferenceable _Tp>
+requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __referenceable; }
+using iter_rvalue_reference_t = decltype(ranges::iter_move(declval<_Tp&>()));
+
+#endif // !_LIBCPP_HAS_NO_RANGES
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_ITER_MOVE_H
diff --git a/include/__iterator/iter_swap.h b/include/__iterator/iter_swap.h
new file mode 100644
index 0000000..d70da09
--- /dev/null
+++ b/include/__iterator/iter_swap.h
@@ -0,0 +1,107 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___ITERATOR_ITER_SWAP_H
+#define _LIBCPP___ITERATOR_ITER_SWAP_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/readable_traits.h>
+#include <__ranges/access.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+namespace __iter_swap {
+  template<class _I1, class _I2>
+  void iter_swap(_I1, _I2) = delete;
+
+  template<class _T1, class _T2>
+  concept __unqualified_iter_swap = requires(_T1&& __x, _T2&& __y) {
+    iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y));
+  };
+
+  template<class _T1, class _T2>
+  concept __readable_swappable =
+    indirectly_readable<_T1> && indirectly_readable<_T2> &&
+    swappable_with<iter_reference_t<_T1>, iter_reference_t<_T2>>;
+
+  struct __fn {
+    template <class _T1, class _T2>
+      requires __unqualified_iter_swap<_T1, _T2>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr void operator()(_T1&& __x, _T2&& __y) const
+      noexcept(noexcept(iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y))))
+    {
+      (void)iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y));
+    }
+
+    template <class _T1, class _T2>
+      requires (!__unqualified_iter_swap<_T1, _T2>) &&
+               __readable_swappable<_T1, _T2>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr void operator()(_T1&& __x, _T2&& __y) const
+      noexcept(noexcept(ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y))))
+    {
+      ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y));
+    }
+
+    template <class _T1, class _T2>
+      requires (!__unqualified_iter_swap<_T1, _T2> &&
+                !__readable_swappable<_T1, _T2>) &&
+               indirectly_movable_storable<_T1, _T2> &&
+               indirectly_movable_storable<_T2, _T1>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr void operator()(_T1&& __x, _T2&& __y) const
+      noexcept(noexcept(iter_value_t<_T2>(ranges::iter_move(__y))) &&
+               noexcept(*__y = ranges::iter_move(__x)) &&
+               noexcept(*_VSTD::forward<_T1>(__x) = declval<iter_value_t<_T2>>()))
+    {
+      iter_value_t<_T2> __old(ranges::iter_move(__y));
+      *__y = ranges::iter_move(__x);
+      *_VSTD::forward<_T1>(__x) = _VSTD::move(__old);
+    }
+  };
+} // end namespace __iter_swap
+
+inline namespace __cpo {
+  inline constexpr auto iter_swap = __iter_swap::__fn{};
+} // namespace __cpo
+
+} // namespace ranges
+
+template<class _I1, class _I2 = _I1>
+concept indirectly_swappable =
+  indirectly_readable<_I1> && indirectly_readable<_I2> &&
+  requires(const _I1 __i1, const _I2 __i2) {
+    ranges::iter_swap(__i1, __i1);
+    ranges::iter_swap(__i2, __i2);
+    ranges::iter_swap(__i1, __i2);
+    ranges::iter_swap(__i2, __i1);
+  };
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_ITER_SWAP_H
diff --git a/include/__iterator/iterator.h b/include/__iterator/iterator.h
new file mode 100644
index 0000000..dfd481e
--- /dev/null
+++ b/include/__iterator/iterator.h
@@ -0,0 +1,40 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_ITERATOR_H
+#define _LIBCPP___ITERATOR_ITERATOR_H
+
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template<class _Category, class _Tp, class _Distance = ptrdiff_t,
+         class _Pointer = _Tp*, class _Reference = _Tp&>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator
+{
+    typedef _Tp        value_type;
+    typedef _Distance  difference_type;
+    typedef _Pointer   pointer;
+    typedef _Reference reference;
+    typedef _Category  iterator_category;
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_ITERATOR_H
diff --git a/include/__iterator/iterator_traits.h b/include/__iterator/iterator_traits.h
new file mode 100644
index 0000000..5275705
--- /dev/null
+++ b/include/__iterator/iterator_traits.h
@@ -0,0 +1,500 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_ITERATOR_TRAITS_H
+#define _LIBCPP___ITERATOR_ITERATOR_TRAITS_H
+
+#include <__config>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/readable_traits.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+template <class _Tp>
+using __with_reference = _Tp&;
+
+template <class _Tp>
+concept __referenceable = requires {
+  typename __with_reference<_Tp>;
+};
+
+template <class _Tp>
+concept __dereferenceable = requires(_Tp& __t) {
+  { *__t } -> __referenceable; // not required to be equality-preserving
+};
+
+// [iterator.traits]
+template<__dereferenceable _Tp>
+using iter_reference_t = decltype(*declval<_Tp&>());
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+template <class _Iter>
+struct _LIBCPP_TEMPLATE_VIS iterator_traits;
+
+struct _LIBCPP_TEMPLATE_VIS input_iterator_tag {};
+struct _LIBCPP_TEMPLATE_VIS output_iterator_tag {};
+struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag       : public input_iterator_tag {};
+struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {};
+struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {};
+#if _LIBCPP_STD_VER > 17
+struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag    : public random_access_iterator_tag {};
+#endif
+
+template <class _Iter>
+struct __iter_traits_cache {
+  using type = _If<
+    __is_primary_template<iterator_traits<_Iter> >::value,
+    _Iter,
+    iterator_traits<_Iter>
+  >;
+};
+template <class _Iter>
+using _ITER_TRAITS = typename __iter_traits_cache<_Iter>::type;
+
+struct __iter_concept_concept_test {
+  template <class _Iter>
+  using _Apply = typename _ITER_TRAITS<_Iter>::iterator_concept;
+};
+struct __iter_concept_category_test {
+  template <class _Iter>
+  using _Apply = typename _ITER_TRAITS<_Iter>::iterator_category;
+};
+struct __iter_concept_random_fallback {
+  template <class _Iter>
+  using _Apply = _EnableIf<
+                          __is_primary_template<iterator_traits<_Iter> >::value,
+                          random_access_iterator_tag
+                        >;
+};
+
+template <class _Iter, class _Tester> struct __test_iter_concept
+    : _IsValidExpansion<_Tester::template _Apply, _Iter>,
+      _Tester
+{
+};
+
+template <class _Iter>
+struct __iter_concept_cache {
+  using type = _Or<
+    __test_iter_concept<_Iter, __iter_concept_concept_test>,
+    __test_iter_concept<_Iter, __iter_concept_category_test>,
+    __test_iter_concept<_Iter, __iter_concept_random_fallback>
+  >;
+};
+
+template <class _Iter>
+using _ITER_CONCEPT = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>;
+
+
+template <class _Tp>
+struct __has_iterator_typedefs
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename __void_t<typename _Up::iterator_category>::type* = 0,
+                                            typename __void_t<typename _Up::difference_type>::type* = 0,
+                                            typename __void_t<typename _Up::value_type>::type* = 0,
+                                            typename __void_t<typename _Up::reference>::type* = 0,
+                                            typename __void_t<typename _Up::pointer>::type* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1;
+};
+
+
+template <class _Tp>
+struct __has_iterator_category
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::iterator_category* = nullptr);
+public:
+    static const bool value = sizeof(__test<_Tp>(nullptr)) == 1;
+};
+
+template <class _Tp>
+struct __has_iterator_concept
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::iterator_concept* = nullptr);
+public:
+    static const bool value = sizeof(__test<_Tp>(nullptr)) == 1;
+};
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+// The `cpp17-*-iterator` exposition-only concepts are easily confused with the Cpp17*Iterator tables,
+// so they've been banished to a namespace that makes it obvious they have a niche use-case.
+namespace __iterator_traits_detail {
+template<class _Ip>
+concept __cpp17_iterator =
+  requires(_Ip __i) {
+    {   *__i } -> __referenceable;
+    {  ++__i } -> same_as<_Ip&>;
+    { *__i++ } -> __referenceable;
+  } &&
+  copyable<_Ip>;
+
+template<class _Ip>
+concept __cpp17_input_iterator =
+  __cpp17_iterator<_Ip> &&
+  equality_comparable<_Ip> &&
+  requires(_Ip __i) {
+    typename incrementable_traits<_Ip>::difference_type;
+    typename indirectly_readable_traits<_Ip>::value_type;
+    typename common_reference_t<iter_reference_t<_Ip>&&,
+                                typename indirectly_readable_traits<_Ip>::value_type&>;
+    typename common_reference_t<decltype(*__i++)&&,
+                                typename indirectly_readable_traits<_Ip>::value_type&>;
+    requires signed_integral<typename incrementable_traits<_Ip>::difference_type>;
+  };
+
+template<class _Ip>
+concept __cpp17_forward_iterator =
+  __cpp17_input_iterator<_Ip> &&
+  constructible_from<_Ip> &&
+  is_lvalue_reference_v<iter_reference_t<_Ip>> &&
+  same_as<remove_cvref_t<iter_reference_t<_Ip>>,
+          typename indirectly_readable_traits<_Ip>::value_type> &&
+  requires(_Ip __i) {
+    {  __i++ } -> convertible_to<_Ip const&>;
+    { *__i++ } -> same_as<iter_reference_t<_Ip>>;
+  };
+
+template<class _Ip>
+concept __cpp17_bidirectional_iterator =
+  __cpp17_forward_iterator<_Ip> &&
+  requires(_Ip __i) {
+    {  --__i } -> same_as<_Ip&>;
+    {  __i-- } -> convertible_to<_Ip const&>;
+    { *__i-- } -> same_as<iter_reference_t<_Ip>>;
+  };
+
+template<class _Ip>
+concept __cpp17_random_access_iterator =
+  __cpp17_bidirectional_iterator<_Ip> &&
+  totally_ordered<_Ip> &&
+  requires(_Ip __i, typename incrementable_traits<_Ip>::difference_type __n) {
+    { __i += __n } -> same_as<_Ip&>;
+    { __i -= __n } -> same_as<_Ip&>;
+    { __i +  __n } -> same_as<_Ip>;
+    { __n +  __i } -> same_as<_Ip>;
+    { __i -  __n } -> same_as<_Ip>;
+    { __i -  __i } -> same_as<decltype(__n)>;
+    {  __i[__n]  } -> convertible_to<iter_reference_t<_Ip>>;
+  };
+} // namespace __iterator_traits_detail
+
+template<class _Ip>
+concept __has_member_reference = requires { typename _Ip::reference; };
+
+template<class _Ip>
+concept __has_member_pointer = requires { typename _Ip::pointer; };
+
+template<class _Ip>
+concept __has_member_iterator_category = requires { typename _Ip::iterator_category; };
+
+template<class _Ip>
+concept __specifies_members = requires {
+    typename _Ip::value_type;
+    typename _Ip::difference_type;
+    requires __has_member_reference<_Ip>;
+    requires __has_member_iterator_category<_Ip>;
+  };
+
+template<class>
+struct __iterator_traits_member_pointer_or_void {
+  using type = void;
+};
+
+template<__has_member_pointer _Tp>
+struct __iterator_traits_member_pointer_or_void<_Tp> {
+  using type = typename _Tp::pointer;
+};
+
+template<class _Tp>
+concept __cpp17_iterator_missing_members =
+  !__specifies_members<_Tp> &&
+  __iterator_traits_detail::__cpp17_iterator<_Tp>;
+
+template<class _Tp>
+concept __cpp17_input_iterator_missing_members =
+  __cpp17_iterator_missing_members<_Tp> &&
+  __iterator_traits_detail::__cpp17_input_iterator<_Tp>;
+
+// Otherwise, `pointer` names `void`.
+template<class>
+struct __iterator_traits_member_pointer_or_arrow_or_void { using type = void; };
+
+// [iterator.traits]/3.2.1
+// If the qualified-id `I::pointer` is valid and denotes a type, `pointer` names that type.
+template<__has_member_pointer _Ip>
+struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { using type = typename _Ip::pointer; };
+
+// Otherwise, if `decltype(declval<I&>().operator->())` is well-formed, then `pointer` names that
+// type.
+template<class _Ip>
+  requires requires(_Ip& __i) { __i.operator->(); } && (!__has_member_pointer<_Ip>)
+struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> {
+  using type = decltype(declval<_Ip&>().operator->());
+};
+
+// Otherwise, `reference` names `iter-reference-t<I>`.
+template<class _Ip>
+struct __iterator_traits_member_reference { using type = iter_reference_t<_Ip>; };
+
+// [iterator.traits]/3.2.2
+// If the qualified-id `I::reference` is valid and denotes a type, `reference` names that type.
+template<__has_member_reference _Ip>
+struct __iterator_traits_member_reference<_Ip> { using type = typename _Ip::reference; };
+
+// [iterator.traits]/3.2.3.4
+// input_iterator_tag
+template<class _Ip>
+struct __deduce_iterator_category {
+  using type = input_iterator_tag;
+};
+
+// [iterator.traits]/3.2.3.1
+// `random_access_iterator_tag` if `I` satisfies `cpp17-random-access-iterator`, or otherwise
+template<__iterator_traits_detail::__cpp17_random_access_iterator _Ip>
+struct __deduce_iterator_category<_Ip> {
+  using type = random_access_iterator_tag;
+};
+
+// [iterator.traits]/3.2.3.2
+// `bidirectional_iterator_tag` if `I` satisfies `cpp17-bidirectional-iterator`, or otherwise
+template<__iterator_traits_detail::__cpp17_bidirectional_iterator _Ip>
+struct __deduce_iterator_category<_Ip> {
+  using type = bidirectional_iterator_tag;
+};
+
+// [iterator.traits]/3.2.3.3
+// `forward_iterator_tag` if `I` satisfies `cpp17-forward-iterator`, or otherwise
+template<__iterator_traits_detail::__cpp17_forward_iterator _Ip>
+struct __deduce_iterator_category<_Ip> {
+  using type = forward_iterator_tag;
+};
+
+template<class _Ip>
+struct __iterator_traits_iterator_category : __deduce_iterator_category<_Ip> {};
+
+// [iterator.traits]/3.2.3
+// If the qualified-id `I::iterator-category` is valid and denotes a type, `iterator-category` names
+// that type.
+template<__has_member_iterator_category _Ip>
+struct __iterator_traits_iterator_category<_Ip> {
+  using type = typename _Ip::iterator_category;
+};
+
+// otherwise, it names void.
+template<class>
+struct __iterator_traits_difference_type { using type = void; };
+
+// If the qualified-id `incrementable_traits<I>::difference_type` is valid and denotes a type, then
+// `difference_type` names that type;
+template<class _Ip>
+requires requires { typename incrementable_traits<_Ip>::difference_type; }
+struct __iterator_traits_difference_type<_Ip> {
+  using type = typename incrementable_traits<_Ip>::difference_type;
+};
+
+// [iterator.traits]/3.4
+// Otherwise, `iterator_traits<I>` has no members by any of the above names.
+template<class>
+struct __iterator_traits {};
+
+// [iterator.traits]/3.1
+// If `I` has valid ([temp.deduct]) member types `difference-type`, `value-type`, `reference`, and
+// `iterator-category`, then `iterator-traits<I>` has the following publicly accessible members:
+template<__specifies_members _Ip>
+struct __iterator_traits<_Ip> {
+  using iterator_category  = typename _Ip::iterator_category;
+  using value_type         = typename _Ip::value_type;
+  using difference_type    = typename _Ip::difference_type;
+  using pointer            = typename __iterator_traits_member_pointer_or_void<_Ip>::type;
+  using reference          = typename _Ip::reference;
+};
+
+// [iterator.traits]/3.2
+// Otherwise, if `I` satisfies the exposition-only concept `cpp17-input-iterator`,
+// `iterator-traits<I>` has the following publicly accessible members:
+template<__cpp17_input_iterator_missing_members _Ip>
+struct __iterator_traits<_Ip> {
+  using iterator_category = typename __iterator_traits_iterator_category<_Ip>::type;
+  using value_type        = typename indirectly_readable_traits<_Ip>::value_type;
+  using difference_type   = typename incrementable_traits<_Ip>::difference_type;
+  using pointer           = typename __iterator_traits_member_pointer_or_arrow_or_void<_Ip>::type;
+  using reference         = typename __iterator_traits_member_reference<_Ip>::type;
+};
+
+// Otherwise, if `I` satisfies the exposition-only concept `cpp17-iterator`, then
+// `iterator_traits<I>` has the following publicly accessible members:
+template<__cpp17_iterator_missing_members _Ip>
+struct __iterator_traits<_Ip> {
+  using iterator_category = output_iterator_tag;
+  using value_type        = void;
+  using difference_type   = typename __iterator_traits_difference_type<_Ip>::type;
+  using pointer           = void;
+  using reference         = void;
+};
+
+template<class _Ip>
+struct iterator_traits : __iterator_traits<_Ip> {
+  using __primary_template = iterator_traits;
+};
+
+#else // !defined(_LIBCPP_HAS_NO_RANGES)
+
+template <class _Iter, bool> struct __iterator_traits {};
+
+template <class _Iter, bool> struct __iterator_traits_impl {};
+
+template <class _Iter>
+struct __iterator_traits_impl<_Iter, true>
+{
+    typedef typename _Iter::difference_type   difference_type;
+    typedef typename _Iter::value_type        value_type;
+    typedef typename _Iter::pointer           pointer;
+    typedef typename _Iter::reference         reference;
+    typedef typename _Iter::iterator_category iterator_category;
+};
+
+template <class _Iter>
+struct __iterator_traits<_Iter, true>
+    :  __iterator_traits_impl
+      <
+        _Iter,
+        is_convertible<typename _Iter::iterator_category, input_iterator_tag>::value ||
+        is_convertible<typename _Iter::iterator_category, output_iterator_tag>::value
+      >
+{};
+
+// iterator_traits<Iterator> will only have the nested types if Iterator::iterator_category
+//    exists.  Else iterator_traits<Iterator> will be an empty class.  This is a
+//    conforming extension which allows some programs to compile and behave as
+//    the client expects instead of failing at compile time.
+
+template <class _Iter>
+struct _LIBCPP_TEMPLATE_VIS iterator_traits
+    : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> {
+
+  using __primary_template = iterator_traits;
+};
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+template<class _Tp>
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+requires is_object_v<_Tp>
+#endif
+struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>
+{
+    typedef ptrdiff_t difference_type;
+    typedef typename remove_cv<_Tp>::type value_type;
+    typedef _Tp* pointer;
+    typedef _Tp& reference;
+    typedef random_access_iterator_tag iterator_category;
+#if _LIBCPP_STD_VER > 17
+    typedef contiguous_iterator_tag    iterator_concept;
+#endif
+};
+
+template <class _Tp, class _Up, bool = __has_iterator_category<iterator_traits<_Tp> >::value>
+struct __has_iterator_category_convertible_to
+    : is_convertible<typename iterator_traits<_Tp>::iterator_category, _Up>
+{};
+
+template <class _Tp, class _Up>
+struct __has_iterator_category_convertible_to<_Tp, _Up, false> : false_type {};
+
+template <class _Tp, class _Up, bool = __has_iterator_concept<_Tp>::value>
+struct __has_iterator_concept_convertible_to
+    : is_convertible<typename _Tp::iterator_concept, _Up>
+{};
+
+template <class _Tp, class _Up>
+struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {};
+
+template <class _Tp>
+struct __is_cpp17_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {};
+
+template <class _Tp>
+struct __is_cpp17_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {};
+
+template <class _Tp>
+struct __is_cpp17_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {};
+
+template <class _Tp>
+struct __is_cpp17_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {};
+
+// __is_cpp17_contiguous_iterator determines if an iterator is known by
+// libc++ to be contiguous, either because it advertises itself as such
+// (in C++20) or because it is a pointer type or a known trivial wrapper
+// around a (possibly fancy) pointer type, such as __wrap_iter<T*>.
+// Such iterators receive special "contiguous" optimizations in
+// std::copy and std::sort.
+//
+#if _LIBCPP_STD_VER > 17
+template <class _Tp>
+struct __is_cpp17_contiguous_iterator : _Or<
+    __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag>,
+    __has_iterator_concept_convertible_to<_Tp, contiguous_iterator_tag>
+> {};
+#else
+template <class _Tp>
+struct __is_cpp17_contiguous_iterator : false_type {};
+#endif
+
+// Any native pointer which is an iterator is also a contiguous iterator.
+template <class _Up>
+struct __is_cpp17_contiguous_iterator<_Up*> : true_type {};
+
+
+template <class _Tp>
+struct __is_exactly_cpp17_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> {};
+
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+template<class _InputIterator>
+using __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
+
+template<class _InputIterator>
+using __iter_key_type = remove_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>;
+
+template<class _InputIterator>
+using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type;
+
+template<class _InputIterator>
+using __iter_to_alloc_type = pair<
+    add_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>,
+    typename iterator_traits<_InputIterator>::value_type::second_type>;
+#endif // _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_ITERATOR_TRAITS_H
diff --git a/include/__iterator/move_iterator.h b/include/__iterator/move_iterator.h
new file mode 100644
index 0000000..7819743
--- /dev/null
+++ b/include/__iterator/move_iterator.h
@@ -0,0 +1,189 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_MOVE_ITERATOR_H
+#define _LIBCPP___ITERATOR_MOVE_ITERATOR_H
+
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Iter>
+class _LIBCPP_TEMPLATE_VIS move_iterator
+{
+private:
+    _Iter __i;
+public:
+    typedef _Iter                                            iterator_type;
+    typedef typename iterator_traits<iterator_type>::value_type value_type;
+    typedef typename iterator_traits<iterator_type>::difference_type difference_type;
+    typedef iterator_type pointer;
+    typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
+        random_access_iterator_tag,
+        typename iterator_traits<_Iter>::iterator_category>  iterator_category;
+#if _LIBCPP_STD_VER > 17
+    typedef input_iterator_tag                               iterator_concept;
+#endif
+
+#ifndef _LIBCPP_CXX03_LANG
+    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
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    move_iterator() : __i() {}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    explicit move_iterator(_Iter __x) : __i(__x) {}
+
+    template <class _Up, class = _EnableIf<
+        !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
+    > >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    move_iterator(const move_iterator<_Up>& __u) : __i(__u.base()) {}
+
+    template <class _Up, class = _EnableIf<
+        !is_same<_Up, _Iter>::value &&
+        is_convertible<_Up const&, _Iter>::value &&
+        is_assignable<_Iter&, _Up const&>::value
+    > >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    move_iterator& operator=(const move_iterator<_Up>& __u) {
+        __i = __u.base();
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 _Iter base() const {return __i;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reference operator*() const { return static_cast<reference>(*__i); }
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    pointer  operator->() const { return __i;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    move_iterator& operator++() {++__i; return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    move_iterator  operator++(int) {move_iterator __tmp(*this); ++__i; return __tmp;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    move_iterator& operator--() {--__i; return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    move_iterator  operator--(int) {move_iterator __tmp(*this); --__i; return __tmp;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    move_iterator  operator+ (difference_type __n) const {return move_iterator(__i + __n);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    move_iterator& operator+=(difference_type __n) {__i += __n; return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    move_iterator  operator- (difference_type __n) const {return move_iterator(__i - __n);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    move_iterator& operator-=(difference_type __n) {__i -= __n; return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reference operator[](difference_type __n) const { return static_cast<reference>(__i[__n]); }
+};
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+bool
+operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() == __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+bool
+operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() < __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+bool
+operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() != __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+bool
+operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() > __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+bool
+operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() >= __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+bool
+operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() <= __y.base();
+}
+
+#ifndef _LIBCPP_CXX03_LANG
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+auto
+operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+-> decltype(__x.base() - __y.base())
+{
+    return __x.base() - __y.base();
+}
+#else
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename move_iterator<_Iter1>::difference_type
+operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() - __y.base();
+}
+#endif
+
+template <class _Iter>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+move_iterator<_Iter>
+operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x)
+{
+    return move_iterator<_Iter>(__x.base() + __n);
+}
+
+template <class _Iter>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+move_iterator<_Iter>
+make_move_iterator(_Iter __i)
+{
+    return move_iterator<_Iter>(__i);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H
diff --git a/include/__iterator/next.h b/include/__iterator/next.h
new file mode 100644
index 0000000..1eecaa9
--- /dev/null
+++ b/include/__iterator/next.h
@@ -0,0 +1,87 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_NEXT_H
+#define _LIBCPP___ITERATOR_NEXT_H
+
+#include <__config>
+#include <__debug>
+#include <__function_like.h>
+#include <__iterator/advance.h>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iterator_traits.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIter>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type
+    next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) {
+  _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
+                 "Attempt to next(it, n) with negative n on a non-bidirectional iterator");
+
+  _VSTD::advance(__x, __n);
+  return __x;
+}
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+struct __next_fn final : private __function_like {
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr explicit __next_fn(__tag __x) noexcept : __function_like(__x) {}
+
+  template <input_or_output_iterator _Ip>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _Ip operator()(_Ip __x) const {
+    ++__x;
+    return __x;
+  }
+
+  template <input_or_output_iterator _Ip>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const {
+    ranges::advance(__x, __n);
+    return __x;
+  }
+
+  template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _Ip operator()(_Ip __x, _Sp __bound) const {
+    ranges::advance(__x, __bound);
+    return __x;
+  }
+
+  template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Sp __bound) const {
+    ranges::advance(__x, __n, __bound);
+    return __x;
+  }
+};
+
+inline constexpr auto next = __next_fn(__function_like::__tag());
+} // namespace ranges
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_PRIMITIVES_H
diff --git a/include/__iterator/ostream_iterator.h b/include/__iterator/ostream_iterator.h
new file mode 100644
index 0000000..5b4466c
--- /dev/null
+++ b/include/__iterator/ostream_iterator.h
@@ -0,0 +1,75 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H
+#define _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H
+
+#include <__config>
+#include <__iterator/iterator.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <iosfwd> // for forward declarations of char_traits and basic_ostream
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >
+class _LIBCPP_TEMPLATE_VIS ostream_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
+    : public iterator<output_iterator_tag, void, void, void, void>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+public:
+    typedef output_iterator_tag             iterator_category;
+    typedef void                            value_type;
+#if _LIBCPP_STD_VER > 17
+    typedef ptrdiff_t                       difference_type;
+#else
+    typedef void                            difference_type;
+#endif
+    typedef void                            pointer;
+    typedef void                            reference;
+    typedef _CharT                          char_type;
+    typedef _Traits                         traits_type;
+    typedef basic_ostream<_CharT, _Traits>  ostream_type;
+
+private:
+    ostream_type* __out_stream_;
+    const char_type* __delim_;
+public:
+    _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) _NOEXCEPT
+        : __out_stream_(_VSTD::addressof(__s)), __delim_(nullptr) {}
+    _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT
+        : __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {}
+    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_)
+        {
+            *__out_stream_ << __value_;
+            if (__delim_)
+                *__out_stream_ << __delim_;
+            return *this;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator*()     {return *this;}
+    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++()    {return *this;}
+    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;}
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H
diff --git a/include/__iterator/ostreambuf_iterator.h b/include/__iterator/ostreambuf_iterator.h
new file mode 100644
index 0000000..90309da
--- /dev/null
+++ b/include/__iterator/ostreambuf_iterator.h
@@ -0,0 +1,81 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H
+#define _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H
+
+#include <__config>
+#include <__iterator/iterator.h>
+#include <__iterator/iterator_traits.h>
+#include <iosfwd> // for forward declaration of basic_streambuf
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _CharT, class _Traits>
+class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
+    : public iterator<output_iterator_tag, void, void, void, void>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+public:
+    typedef output_iterator_tag                 iterator_category;
+    typedef void                                value_type;
+#if _LIBCPP_STD_VER > 17
+    typedef ptrdiff_t                           difference_type;
+#else
+    typedef void                                difference_type;
+#endif
+    typedef void                                pointer;
+    typedef void                                reference;
+    typedef _CharT                              char_type;
+    typedef _Traits                             traits_type;
+    typedef basic_streambuf<_CharT, _Traits>    streambuf_type;
+    typedef basic_ostream<_CharT, _Traits>      ostream_type;
+
+private:
+    streambuf_type* __sbuf_;
+public:
+    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT
+        : __sbuf_(__s.rdbuf()) {}
+    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT
+        : __sbuf_(__s) {}
+    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator=(_CharT __c)
+        {
+            if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof()))
+                __sbuf_ = nullptr;
+            return *this;
+        }
+    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator*()     {return *this;}
+    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++()    {return *this;}
+    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;}
+    _LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == nullptr;}
+
+    template <class _Ch, class _Tr>
+    friend
+    _LIBCPP_HIDDEN
+    ostreambuf_iterator<_Ch, _Tr>
+    __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s,
+                     const _Ch* __ob, const _Ch* __op, const _Ch* __oe,
+                     ios_base& __iob, _Ch __fl);
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H
diff --git a/include/__iterator/prev.h b/include/__iterator/prev.h
new file mode 100644
index 0000000..cb8a571
--- /dev/null
+++ b/include/__iterator/prev.h
@@ -0,0 +1,79 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_PREV_H
+#define _LIBCPP___ITERATOR_PREV_H
+
+#include <__config>
+#include <__debug>
+#include <__function_like.h>
+#include <__iterator/advance.h>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iterator_traits.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIter>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type
+    prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) {
+  _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
+                 "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator");
+  _VSTD::advance(__x, -__n);
+  return __x;
+}
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+struct __prev_fn final : private __function_like {
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr explicit __prev_fn(__tag __x) noexcept : __function_like(__x) {}
+
+  template <bidirectional_iterator _Ip>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _Ip operator()(_Ip __x) const {
+    --__x;
+    return __x;
+  }
+
+  template <bidirectional_iterator _Ip>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const {
+    ranges::advance(__x, -__n);
+    return __x;
+  }
+
+  template <bidirectional_iterator _Ip>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Ip __bound) const {
+    ranges::advance(__x, -__n, __bound);
+    return __x;
+  }
+};
+
+inline constexpr auto prev = __prev_fn(__function_like::__tag());
+} // namespace ranges
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_PREV_H
diff --git a/include/__iterator/projected.h b/include/__iterator/projected.h
new file mode 100644
index 0000000..7064a5e
--- /dev/null
+++ b/include/__iterator/projected.h
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___ITERATOR_PROJECTED_H
+#define _LIBCPP___ITERATOR_PROJECTED_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+template<indirectly_readable _It, indirectly_regular_unary_invocable<_It> _Proj>
+struct projected {
+  using value_type = remove_cvref_t<indirect_result_t<_Proj&, _It>>;
+  indirect_result_t<_Proj&, _It> operator*() const; // not defined
+};
+
+template<weakly_incrementable _It, class _Proj>
+struct incrementable_traits<projected<_It, _Proj>> {
+  using difference_type = iter_difference_t<_It>;
+};
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_PROJECTED_H
diff --git a/include/__iterator/readable_traits.h b/include/__iterator/readable_traits.h
new file mode 100644
index 0000000..fbad106
--- /dev/null
+++ b/include/__iterator/readable_traits.h
@@ -0,0 +1,91 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_READABLE_TRAITS_H
+#define _LIBCPP___ITERATOR_READABLE_TRAITS_H
+
+#include <__config>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+// [readable.traits]
+template<class> struct __cond_value_type {};
+
+template<class _Tp>
+requires is_object_v<_Tp>
+struct __cond_value_type<_Tp> { using value_type = remove_cv_t<_Tp>; };
+
+template<class _Tp>
+concept __has_member_value_type = requires { typename _Tp::value_type; };
+
+template<class _Tp>
+concept __has_member_element_type = requires { typename _Tp::element_type; };
+
+template<class> struct indirectly_readable_traits {};
+
+template<class _Ip>
+requires is_array_v<_Ip>
+struct indirectly_readable_traits<_Ip> {
+  using value_type = remove_cv_t<remove_extent_t<_Ip>>;
+};
+
+template<class _Ip>
+struct indirectly_readable_traits<const _Ip> : indirectly_readable_traits<_Ip> {};
+
+template<class _Tp>
+struct indirectly_readable_traits<_Tp*> : __cond_value_type<_Tp> {};
+
+template<__has_member_value_type _Tp>
+struct indirectly_readable_traits<_Tp>
+  : __cond_value_type<typename _Tp::value_type> {};
+
+template<__has_member_element_type _Tp>
+struct indirectly_readable_traits<_Tp>
+  : __cond_value_type<typename _Tp::element_type> {};
+
+// Pre-emptively applies LWG3541
+template<__has_member_value_type _Tp>
+requires __has_member_element_type<_Tp>
+struct indirectly_readable_traits<_Tp> {};
+template<__has_member_value_type _Tp>
+requires __has_member_element_type<_Tp> &&
+         same_as<remove_cv_t<typename _Tp::element_type>,
+                 remove_cv_t<typename _Tp::value_type>>
+struct indirectly_readable_traits<_Tp>
+  : __cond_value_type<typename _Tp::value_type> {};
+
+template <class>
+struct iterator_traits;
+
+// Let `RI` be `remove_cvref_t<I>`. The type `iter_value_t<I>` denotes
+// `indirectly_readable_traits<RI>::value_type` if `iterator_traits<RI>` names a specialization
+// generated from the primary template, and `iterator_traits<RI>::value_type` otherwise.
+template <class _Ip>
+using iter_value_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value,
+                                            indirectly_readable_traits<remove_cvref_t<_Ip> >,
+                                            iterator_traits<remove_cvref_t<_Ip> > >::value_type;
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_READABLE_TRAITS_H
diff --git a/include/__iterator/reverse_access.h b/include/__iterator/reverse_access.h
new file mode 100644
index 0000000..66cc356
--- /dev/null
+++ b/include/__iterator/reverse_access.h
@@ -0,0 +1,109 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_REVERSE_ACCESS_H
+#define _LIBCPP___ITERATOR_REVERSE_ACCESS_H
+
+#include <__config>
+#include <__iterator/reverse_iterator.h>
+#include <cstddef>
+#include <initializer_list>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_CXX03_LANG)
+
+#if _LIBCPP_STD_VER > 11
+
+template <class _Tp, size_t _Np>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np])
+{
+    return reverse_iterator<_Tp*>(__array + _Np);
+}
+
+template <class _Tp, size_t _Np>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np])
+{
+    return reverse_iterator<_Tp*>(__array);
+}
+
+template <class _Ep>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+reverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il)
+{
+    return reverse_iterator<const _Ep*>(__il.end());
+}
+
+template <class _Ep>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+reverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il)
+{
+    return reverse_iterator<const _Ep*>(__il.begin());
+}
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+auto rbegin(_Cp& __c) -> decltype(__c.rbegin())
+{
+    return __c.rbegin();
+}
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+auto rbegin(const _Cp& __c) -> decltype(__c.rbegin())
+{
+    return __c.rbegin();
+}
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+auto rend(_Cp& __c) -> decltype(__c.rend())
+{
+    return __c.rend();
+}
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+auto rend(const _Cp& __c) -> decltype(__c.rend())
+{
+    return __c.rend();
+}
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+auto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c))
+{
+    return _VSTD::rbegin(__c);
+}
+
+template <class _Cp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c))
+{
+    return _VSTD::rend(__c);
+}
+
+#endif
+
+#endif // !defined(_LIBCPP_CXX03_LANG)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_REVERSE_ACCESS_H
diff --git a/include/__iterator/reverse_iterator.h b/include/__iterator/reverse_iterator.h
new file mode 100644
index 0000000..76424a8
--- /dev/null
+++ b/include/__iterator/reverse_iterator.h
@@ -0,0 +1,239 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
+#define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
+
+#include <__config>
+#include <__iterator/iterator.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, class = void>
+struct __is_stashing_iterator : false_type {};
+
+template <class _Tp>
+struct __is_stashing_iterator<_Tp, typename __void_t<typename _Tp::__stashing_iterator_tag>::type>
+  : true_type {};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Iter>
+class _LIBCPP_TEMPLATE_VIS reverse_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
+    : public iterator<typename iterator_traits<_Iter>::iterator_category,
+                      typename iterator_traits<_Iter>::value_type,
+                      typename iterator_traits<_Iter>::difference_type,
+                      typename iterator_traits<_Iter>::pointer,
+                      typename iterator_traits<_Iter>::reference>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+private:
+#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
+    _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break
+#endif
+
+    static_assert(!__is_stashing_iterator<_Iter>::value,
+      "The specified iterator type cannot be used with reverse_iterator; "
+      "Using stashing iterators with reverse_iterator causes undefined behavior");
+
+protected:
+    _Iter current;
+public:
+    typedef _Iter                                            iterator_type;
+    typedef typename iterator_traits<_Iter>::difference_type difference_type;
+    typedef typename iterator_traits<_Iter>::reference       reference;
+    typedef typename iterator_traits<_Iter>::pointer         pointer;
+    typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
+        random_access_iterator_tag,
+        typename iterator_traits<_Iter>::iterator_category>  iterator_category;
+    typedef typename iterator_traits<_Iter>::value_type      value_type;
+
+#if _LIBCPP_STD_VER > 17
+    typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
+        random_access_iterator_tag,
+        bidirectional_iterator_tag>                          iterator_concept;
+#endif
+
+#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator() : __t(), current() {}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}
+
+    template <class _Up, class = _EnableIf<
+        !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
+    > >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator(const reverse_iterator<_Up>& __u)
+        : __t(__u.base()), current(__u.base())
+    { }
+
+    template <class _Up, class = _EnableIf<
+        !is_same<_Up, _Iter>::value &&
+        is_convertible<_Up const&, _Iter>::value &&
+        is_assignable<_Up const&, _Iter>::value
+    > >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
+        __t = current = __u.base();
+        return *this;
+    }
+#else
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator() : current() {}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    explicit reverse_iterator(_Iter __x) : current(__x) {}
+
+    template <class _Up, class = _EnableIf<
+        !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
+    > >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator(const reverse_iterator<_Up>& __u)
+        : current(__u.base())
+    { }
+
+    template <class _Up, class = _EnableIf<
+        !is_same<_Up, _Iter>::value &&
+        is_convertible<_Up const&, _Iter>::value &&
+        is_assignable<_Up const&, _Iter>::value
+    > >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
+        current = __u.base();
+        return *this;
+    }
+#endif
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    _Iter base() const {return current;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reference operator*() const {_Iter __tmp = current; return *--__tmp;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    pointer  operator->() const {return _VSTD::addressof(operator*());}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator& operator++() {--current; return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator  operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator& operator--() {++current; return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator  operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator  operator+ (difference_type __n) const {return reverse_iterator(current - __n);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator  operator- (difference_type __n) const {return reverse_iterator(current + __n);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reference         operator[](difference_type __n) const {return *(*this + __n);}
+};
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+bool
+operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __x.base() == __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+bool
+operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __x.base() > __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+bool
+operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __x.base() != __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+bool
+operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __x.base() < __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+bool
+operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __x.base() <= __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+bool
+operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __x.base() >= __y.base();
+}
+
+#ifndef _LIBCPP_CXX03_LANG
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+auto
+operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+-> decltype(__y.base() - __x.base())
+{
+    return __y.base() - __x.base();
+}
+#else
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename reverse_iterator<_Iter1>::difference_type
+operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __y.base() - __x.base();
+}
+#endif
+
+template <class _Iter>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+reverse_iterator<_Iter>
+operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
+{
+    return reverse_iterator<_Iter>(__x.base() - __n);
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _Iter>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
+{
+    return reverse_iterator<_Iter>(__i);
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
diff --git a/include/__iterator/size.h b/include/__iterator/size.h
new file mode 100644
index 0000000..259424f
--- /dev/null
+++ b/include/__iterator/size.h
@@ -0,0 +1,58 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_SIZE_H
+#define _LIBCPP___ITERATOR_SIZE_H
+
+#include <__config>
+#include <cstddef>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+template <class _Cont>
+_LIBCPP_INLINE_VISIBILITY
+constexpr auto size(const _Cont& __c)
+_NOEXCEPT_(noexcept(__c.size()))
+-> decltype        (__c.size())
+{ return            __c.size(); }
+
+template <class _Tp, size_t _Sz>
+_LIBCPP_INLINE_VISIBILITY
+constexpr size_t size(const _Tp (&)[_Sz]) noexcept { return _Sz; }
+
+#if _LIBCPP_STD_VER > 17
+template <class _Cont>
+_LIBCPP_INLINE_VISIBILITY
+constexpr auto ssize(const _Cont& __c)
+_NOEXCEPT_(noexcept(static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size())))
+->                              common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>
+{ return            static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size()); }
+
+template <class _Tp, ptrdiff_t _Sz>
+_LIBCPP_INLINE_VISIBILITY
+constexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; }
+#endif
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_SIZE_H
diff --git a/include/__iterator/wrap_iter.h b/include/__iterator/wrap_iter.h
new file mode 100644
index 0000000..e35a372
--- /dev/null
+++ b/include/__iterator/wrap_iter.h
@@ -0,0 +1,300 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_WRAP_ITER_H
+#define _LIBCPP___ITERATOR_WRAP_ITER_H
+
+#include <__config>
+#include <__debug>
+#include <__iterator/iterator_traits.h>
+#include <__memory/pointer_traits.h> // __to_address
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Iter>
+class __wrap_iter
+{
+public:
+    typedef _Iter                                                      iterator_type;
+    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 typename iterator_traits<iterator_type>::reference         reference;
+    typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
+#if _LIBCPP_STD_VER > 17
+    typedef contiguous_iterator_tag                                    iterator_concept;
+#endif
+
+private:
+    iterator_type __i;
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+                : __i{}
+#endif
+    {
+#if _LIBCPP_DEBUG_LEVEL == 2
+        __get_db()->__insert_i(this);
+#endif
+    }
+    template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+        __wrap_iter(const __wrap_iter<_Up>& __u,
+            typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = nullptr) _NOEXCEPT
+            : __i(__u.base())
+    {
+#if _LIBCPP_DEBUG_LEVEL == 2
+        __get_db()->__iterator_copy(this, &__u);
+#endif
+    }
+#if _LIBCPP_DEBUG_LEVEL == 2
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+    __wrap_iter(const __wrap_iter& __x)
+        : __i(__x.base())
+    {
+        __get_db()->__iterator_copy(this, &__x);
+    }
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+    __wrap_iter& operator=(const __wrap_iter& __x)
+    {
+        if (this != &__x)
+        {
+            __get_db()->__iterator_copy(this, &__x);
+            __i = __x.__i;
+        }
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+    ~__wrap_iter()
+    {
+        __get_db()->__erase_i(this);
+    }
+#endif
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator*() const _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL == 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to dereference a non-dereferenceable iterator");
+#endif
+        return *__i;
+    }
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG pointer  operator->() const _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL == 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to dereference a non-dereferenceable iterator");
+#endif
+        return _VSTD::__to_address(__i);
+    }
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator++() _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL == 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment a non-incrementable iterator");
+#endif
+        ++__i;
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator++(int) _NOEXCEPT
+        {__wrap_iter __tmp(*this); ++(*this); return __tmp;}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator--() _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL == 2
+        _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
+                       "Attempted to decrement a non-decrementable iterator");
+#endif
+        --__i;
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator--(int) _NOEXCEPT
+        {__wrap_iter __tmp(*this); --(*this); return __tmp;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator+ (difference_type __n) const _NOEXCEPT
+        {__wrap_iter __w(*this); __w += __n; return __w;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator+=(difference_type __n) _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL == 2
+        _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n),
+                   "Attempted to add/subtract an iterator outside its valid range");
+#endif
+        __i += __n;
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator- (difference_type __n) const _NOEXCEPT
+        {return *this + (-__n);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator-=(difference_type __n) _NOEXCEPT
+        {*this += -__n; return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference    operator[](difference_type __n) const _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL == 2
+        _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n),
+                   "Attempted to subscript an iterator outside its valid range");
+#endif
+        return __i[__n];
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG iterator_type base() const _NOEXCEPT {return __i;}
+
+private:
+#if _LIBCPP_DEBUG_LEVEL == 2
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
+    {
+        __get_db()->__insert_ic(this, __p);
+    }
+#else
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
+#endif
+
+    template <class _Up> friend class __wrap_iter;
+    template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
+    template <class _Tp, class _Alloc> friend class _LIBCPP_TEMPLATE_VIS vector;
+    template <class _Tp, size_t> friend class _LIBCPP_TEMPLATE_VIS span;
+};
+
+template <class _Iter1>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
+{
+    return __x.base() == __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+{
+    return __x.base() == __y.base();
+}
+
+template <class _Iter1>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
+{
+#if _LIBCPP_DEBUG_LEVEL == 2
+    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
+                   "Attempted to compare incomparable iterators");
+#endif
+    return __x.base() < __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+{
+#if _LIBCPP_DEBUG_LEVEL == 2
+    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
+                   "Attempted to compare incomparable iterators");
+#endif
+    return __x.base() < __y.base();
+}
+
+template <class _Iter1>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
+{
+    return !(__x == __y);
+}
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+{
+    return !(__x == __y);
+}
+
+template <class _Iter1>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
+{
+    return __y < __x;
+}
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+{
+    return __y < __x;
+}
+
+template <class _Iter1>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
+{
+    return !(__x < __y);
+}
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+{
+    return !(__x < __y);
+}
+
+template <class _Iter1>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
+{
+    return !(__y < __x);
+}
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+{
+    return !(__y < __x);
+}
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+#ifndef _LIBCPP_CXX03_LANG
+auto operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+    -> decltype(__x.base() - __y.base())
+#else
+typename __wrap_iter<_Iter1>::difference_type
+operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+#endif // C++03
+{
+#if _LIBCPP_DEBUG_LEVEL == 2
+    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
+                   "Attempted to subtract incompatible iterators");
+#endif
+    return __x.base() - __y.base();
+}
+
+template <class _Iter1>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+__wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type __n, __wrap_iter<_Iter1> __x) _NOEXCEPT
+{
+    __x += __n;
+    return __x;
+}
+
+#if _LIBCPP_STD_VER <= 17
+template <class _It>
+struct __is_cpp17_contiguous_iterator<__wrap_iter<_It> > : true_type {};
+#endif
+
+template <class _Iter>
+_LIBCPP_CONSTEXPR
+decltype(_VSTD::__to_address(declval<_Iter>()))
+__to_address(__wrap_iter<_Iter> __w) _NOEXCEPT {
+    return _VSTD::__to_address(__w.base());
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ITERATOR_WRAP_ITER_H
diff --git a/include/__libcpp_version b/include/__libcpp_version
new file mode 100644
index 0000000..09514aa
--- /dev/null
+++ b/include/__libcpp_version
@@ -0,0 +1 @@
+13000
diff --git a/include/__locale b/include/__locale
index 5ccd795..ad74299 100644
--- a/include/__locale
+++ b/include/__locale
@@ -1,16 +1,16 @@
 // -*- 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.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef _LIBCPP___LOCALE
 #define _LIBCPP___LOCALE
 
+#include <__availability>
 #include <__config>
 #include <string>
 #include <memory>
@@ -19,20 +19,33 @@
 #include <cstdint>
 #include <cctype>
 #include <locale.h>
-#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
-# include <support/win32/locale_win32.h>
-#elif defined(_AIX)
-# include <support/ibm/xlocale.h>
+#if defined(_LIBCPP_MSVCRT_LIKE)
+# include <cstring>
+# include <__support/win32/locale_win32.h>
+#elif defined(__NuttX__)
+# include <__support/nuttx/xlocale.h>
+#elif defined(_AIX) || defined(__MVS__)
+# include <__support/ibm/xlocale.h>
 #elif defined(__ANDROID__)
-// Android gained the locale aware functions in L (API level 21)
-# include <android/api-level.h>
-# if __ANDROID_API__ <= 20
-#  include <support/android/locale_bionic.h>
-# endif
-#elif (defined(__GLIBC__) || defined(__APPLE__)      || defined(__FreeBSD__) \
-    || defined(__sun__)   || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
+# include <__support/android/locale_bionic.h>
+#elif defined(__sun__)
 # include <xlocale.h>
-#endif // __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || __EMSCRIPTEN__ || __IBMCPP__
+# include <__support/solaris/xlocale.h>
+#elif defined(_NEWLIB_VERSION)
+# include <__support/newlib/xlocale.h>
+#elif defined(__OpenBSD__)
+# include <__support/openbsd/xlocale.h>
+#elif (defined(__APPLE__)      || defined(__FreeBSD__) \
+    || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
+# include <xlocale.h>
+#elif defined(__Fuchsia__)
+# include <__support/fuchsia/xlocale.h>
+#elif defined(__wasi__)
+// WASI libc uses musl's locales support.
+# include <__support/musl/xlocale.h>
+#elif defined(_LIBCPP_HAS_MUSL_LIBC)
+# include <__support/musl/xlocale.h>
+#endif
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -40,6 +53,63 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#if !defined(_LIBCPP_LOCALE__L_EXTENSIONS)
+struct __libcpp_locale_guard {
+  _LIBCPP_INLINE_VISIBILITY
+  __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {}
+
+  _LIBCPP_INLINE_VISIBILITY
+  ~__libcpp_locale_guard() {
+    if (__old_loc_)
+      uselocale(__old_loc_);
+  }
+
+  locale_t __old_loc_;
+private:
+  __libcpp_locale_guard(__libcpp_locale_guard const&);
+  __libcpp_locale_guard& operator=(__libcpp_locale_guard const&);
+};
+#elif defined(_LIBCPP_MSVCRT_LIKE)
+struct __libcpp_locale_guard {
+    __libcpp_locale_guard(locale_t __l) :
+        __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
+      // Setting the locale can be expensive even when the locale given is
+      // already the current locale, so do an explicit check to see if the
+      // current locale is already the one we want.
+      const char* __lc = __setlocale(nullptr);
+      // If every category is the same, the locale string will simply be the
+      // locale name, otherwise it will be a semicolon-separated string listing
+      // each category.  In the second case, we know at least one category won't
+      // be what we want, so we only have to check the first case.
+      if (_VSTD::strcmp(__l.__get_locale(), __lc) != 0) {
+        __locale_all = _strdup(__lc);
+        if (__locale_all == nullptr)
+          __throw_bad_alloc();
+        __setlocale(__l.__get_locale());
+      }
+    }
+    ~__libcpp_locale_guard() {
+      // The CRT documentation doesn't explicitly say, but setlocale() does the
+      // right thing when given a semicolon-separated list of locale settings
+      // for the different categories in the same format as returned by
+      // setlocale(LC_ALL, nullptr).
+      if (__locale_all != nullptr) {
+        __setlocale(__locale_all);
+        free(__locale_all);
+      }
+      _configthreadlocale(__status);
+    }
+    static const char* __setlocale(const char* __locale) {
+      const char* __new_locale = setlocale(LC_ALL, __locale);
+      if (__new_locale == nullptr)
+        __throw_bad_alloc();
+      return __new_locale;
+    }
+    int __status;
+    char* __locale_all = nullptr;
+};
+#endif
+
 class _LIBCPP_TYPE_VIS locale;
 
 template <class _Facet>
@@ -60,6 +130,7 @@
     class _LIBCPP_TYPE_VIS id;
 
     typedef int category;
+    _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
     static const category // values assigned here are for exposition only
         none     = 0,
         collate  = LC_COLLATE_MASK,
@@ -85,13 +156,16 @@
 
     const locale& operator=(const locale&)  _NOEXCEPT;
 
-    template <class _Facet> locale combine(const locale&) const;
+    template <class _Facet>
+      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+      locale combine(const locale&) const;
 
     // locale operations:
     string name() const;
     bool operator==(const locale&) const;
     bool operator!=(const locale& __y) const {return !(*this == __y);}
     template <class _CharT, class _Traits, class _Allocator>
+      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
       bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
                       const basic_string<_CharT, _Traits, _Allocator>&) const;
 
@@ -158,10 +232,9 @@
 locale
 locale::combine(const locale& __other) const
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
     if (!_VSTD::has_facet<_Facet>(__other))
-        throw runtime_error("locale::combine: locale missing facet");
-#endif  // _LIBCPP_NO_EXCEPTIONS
+        __throw_runtime_error("locale::combine: locale missing facet");
+
     return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
 }
 
@@ -184,7 +257,7 @@
 // template <class _CharT> class collate;
 
 template <class _CharT>
-class _LIBCPP_TYPE_VIS_ONLY collate
+class _LIBCPP_TEMPLATE_VIS collate
     : public locale::facet
 {
 public:
@@ -202,7 +275,10 @@
         return do_compare(__lo1, __hi1, __lo2, __hi2);
     }
 
+    // FIXME(EricWF): The _LIBCPP_ALWAYS_INLINE is needed on Windows to work
+    // around a dllimport bug that expects an external instantiation.
     _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_ALWAYS_INLINE
     string_type transform(const char_type* __lo, const char_type* __hi) const
     {
         return do_transform(__lo, __hi);
@@ -263,12 +339,12 @@
     return static_cast<long>(__h);
 }
 
-_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<char>)
-_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>)
+_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>)
 
 // template <class CharT> class collate_byname;
 
-template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY collate_byname;
+template <class _CharT> class _LIBCPP_TEMPLATE_VIS collate_byname;
 
 template <>
 class _LIBCPP_TYPE_VIS collate_byname<char>
@@ -324,7 +400,26 @@
 class _LIBCPP_TYPE_VIS ctype_base
 {
 public:
-#ifdef __GLIBC__
+#if defined(_LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE)
+    typedef unsigned long mask;
+    static const mask space  = 1<<0;
+    static const mask print  = 1<<1;
+    static const mask cntrl  = 1<<2;
+    static const mask upper  = 1<<3;
+    static const mask lower  = 1<<4;
+    static const mask alpha  = 1<<5;
+    static const mask digit  = 1<<6;
+    static const mask punct  = 1<<7;
+    static const mask xdigit = 1<<8;
+    static const mask blank  = 1<<9;
+#if defined(__BIONIC__)
+    // Historically this was a part of regex_traits rather than ctype_base. The
+    // historical value of the constant is preserved for ABI compatibility.
+    static const mask __regex_word = 0x8000;
+#else
+    static const mask __regex_word = 1<<10;
+#endif // defined(__BIONIC__)
+#elif defined(__GLIBC__)
     typedef unsigned short mask;
     static const mask space  = _ISspace;
     static const mask print  = _ISprint;
@@ -336,7 +431,12 @@
     static const mask punct  = _ISpunct;
     static const mask xdigit = _ISxdigit;
     static const mask blank  = _ISblank;
-#elif defined(_WIN32)
+#if defined(__mips__)
+    static const mask __regex_word = static_cast<mask>(_ISbit(15));
+#else
+    static const mask __regex_word = 0x80;
+#endif
+#elif defined(_LIBCPP_MSVCRT_LIKE)
     typedef unsigned short mask;
     static const mask space  = _SPACE;
     static const mask print  = _BLANK|_PUNCT|_ALPHA|_DIGIT;
@@ -348,16 +448,16 @@
     static const mask punct  = _PUNCT;
     static const mask xdigit = _HEX;
     static const mask blank  = _BLANK;
-#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__ANDROID__)
-#ifdef __APPLE__
+    static const mask __regex_word = 0x80;
+# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
+#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
+# ifdef __APPLE__
     typedef __uint32_t mask;
-#elif defined(__FreeBSD__)
+# elif defined(__FreeBSD__)
     typedef unsigned long mask;
-#elif defined(__EMSCRIPTEN__) ||  defined(__NetBSD__)
+# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)
     typedef unsigned short mask;
-#elif defined(__ANDROID__)
-    typedef unsigned char mask;
-#endif
+# endif
     static const mask space  = _CTYPE_S;
     static const mask print  = _CTYPE_R;
     static const mask cntrl  = _CTYPE_C;
@@ -366,16 +466,16 @@
     static const mask alpha  = _CTYPE_A;
     static const mask digit  = _CTYPE_D;
     static const mask punct  = _CTYPE_P;
-# if defined(__ANDROID__)
-    static const mask xdigit = _CTYPE_X | _CTYPE_D;
-# else
     static const mask xdigit = _CTYPE_X;
-# endif
 
 # if defined(__NetBSD__)
     static const mask blank  = _CTYPE_BL;
+    // NetBSD defines classes up to 0x2000
+    // see sys/ctype_bits.h, _CTYPE_Q
+    static const mask __regex_word = 0x8000;
 # else
     static const mask blank  = _CTYPE_B;
+    static const mask __regex_word = 0x80;
 # endif
 #elif defined(__sun__) || defined(_AIX)
     typedef unsigned int mask;
@@ -389,26 +489,34 @@
     static const mask punct  = _ISPUNCT;
     static const mask xdigit = _ISXDIGIT;
     static const mask blank  = _ISBLANK;
-#else  // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __EMSCRIPTEN__ || __sun__
-    typedef unsigned long mask;
-    static const mask space  = 1<<0;
-    static const mask print  = 1<<1;
-    static const mask cntrl  = 1<<2;
-    static const mask upper  = 1<<3;
-    static const mask lower  = 1<<4;
-    static const mask alpha  = 1<<5;
-    static const mask digit  = 1<<6;
-    static const mask punct  = 1<<7;
-    static const mask xdigit = 1<<8;
-    static const mask blank  = 1<<9;
-#endif  // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
+    static const mask __regex_word = 0x80;
+#elif defined(_NEWLIB_VERSION)
+    // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
+    typedef char mask;
+    static const mask space  = _S;
+    static const mask print  = _P | _U | _L | _N | _B;
+    static const mask cntrl  = _C;
+    static const mask upper  = _U;
+    static const mask lower  = _L;
+    static const mask alpha  = _U | _L;
+    static const mask digit  = _N;
+    static const mask punct  = _P;
+    static const mask xdigit = _X | _N;
+    static const mask blank  = _B;
+    static const mask __regex_word = 0x80;
+# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
+# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
+# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
+#else
+# error unknown rune table for this platform -- do you mean to define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE?
+#endif
     static const mask alnum  = alpha | digit;
     static const mask graph  = alnum | punct;
 
-    _LIBCPP_ALWAYS_INLINE ctype_base() {}
+    _LIBCPP_INLINE_VISIBILITY ctype_base() {}
 };
 
-template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype;
+template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype;
 
 template <>
 class _LIBCPP_TYPE_VIS ctype<wchar_t>
@@ -418,77 +526,77 @@
 public:
     typedef wchar_t char_type;
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     explicit ctype(size_t __refs = 0)
         : locale::facet(__refs) {}
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     bool is(mask __m, char_type __c) const
     {
         return do_is(__m, __c);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
     {
         return do_is(__low, __high, __vec);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
     {
         return do_scan_is(__m, __low, __high);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
     {
         return do_scan_not(__m, __low, __high);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     char_type toupper(char_type __c) const
     {
         return do_toupper(__c);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char_type* toupper(char_type* __low, const char_type* __high) const
     {
         return do_toupper(__low, __high);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     char_type tolower(char_type __c) const
     {
         return do_tolower(__c);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char_type* tolower(char_type* __low, const char_type* __high) const
     {
         return do_tolower(__low, __high);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     char_type widen(char __c) const
     {
         return do_widen(__c);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char* widen(const char* __low, const char* __high, char_type* __to) const
     {
         return do_widen(__low, __high, __to);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     char narrow(char_type __c, char __dfault) const
     {
         return do_narrow(__c, __dfault);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
     {
         return do_narrow(__low, __high, __dfault, __to);
@@ -521,15 +629,15 @@
 public:
     typedef char char_type;
 
-    explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
+    explicit ctype(const mask* __tab = nullptr, bool __del = false, size_t __refs = 0);
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     bool is(mask __m, char_type __c) const
     {
         return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
     {
         for (; __low != __high; ++__low, ++__vec)
@@ -537,7 +645,7 @@
         return __low;
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
     {
         for (; __low != __high; ++__low)
@@ -546,7 +654,7 @@
         return __low;
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
     {
         for (; __low != __high; ++__low)
@@ -555,49 +663,49 @@
         return __low;
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     char_type toupper(char_type __c) const
     {
         return do_toupper(__c);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char_type* toupper(char_type* __low, const char_type* __high) const
     {
         return do_toupper(__low, __high);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     char_type tolower(char_type __c) const
     {
         return do_tolower(__c);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char_type* tolower(char_type* __low, const char_type* __high) const
     {
         return do_tolower(__low, __high);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     char_type widen(char __c) const
     {
         return do_widen(__c);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char* widen(const char* __low, const char* __high, char_type* __to) const
     {
         return do_widen(__low, __high, __to);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     char narrow(char_type __c, char __dfault) const
     {
         return do_narrow(__c, __dfault);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
     {
         return do_narrow(__low, __high, __dfault, __to);
@@ -610,7 +718,7 @@
 #else
     static const size_t table_size = 256;  // FIXME: Don't hardcode this.
 #endif
-    _LIBCPP_ALWAYS_INLINE const mask* table() const  _NOEXCEPT {return __tab_;}
+    _LIBCPP_INLINE_VISIBILITY const mask* table() const  _NOEXCEPT {return __tab_;}
     static const mask* classic_table()  _NOEXCEPT;
 #if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
     static const int* __classic_upper_table() _NOEXCEPT;
@@ -635,7 +743,7 @@
 
 // template <class CharT> class ctype_byname;
 
-template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype_byname;
+template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype_byname;
 
 template <>
 class _LIBCPP_TYPE_VIS ctype_byname<char>
@@ -790,13 +898,13 @@
 class _LIBCPP_TYPE_VIS codecvt_base
 {
 public:
-    _LIBCPP_ALWAYS_INLINE codecvt_base() {}
+    _LIBCPP_INLINE_VISIBILITY codecvt_base() {}
     enum result {ok, partial, error, noconv};
 };
 
 // template <class internT, class externT, class stateT> class codecvt;
 
-template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TYPE_VIS_ONLY codecvt;
+template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TEMPLATE_VIS codecvt;
 
 // template <> class codecvt<char, char, mbstate_t>
 
@@ -810,11 +918,11 @@
     typedef char      extern_type;
     typedef mbstate_t state_type;
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     explicit codecvt(size_t __refs = 0)
         : locale::facet(__refs) {}
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     result out(state_type& __st,
                const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
                extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
@@ -822,14 +930,14 @@
         return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     result unshift(state_type& __st,
                    extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
     {
         return do_unshift(__st, __to, __to_end, __to_nxt);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     result in(state_type& __st,
               const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
               intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
@@ -837,25 +945,25 @@
         return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     int encoding() const  _NOEXCEPT
     {
         return do_encoding();
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     bool always_noconv() const  _NOEXCEPT
     {
         return do_always_noconv();
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
     {
         return do_length(__st, __frm, __end, __mx);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     int max_length() const  _NOEXCEPT
     {
         return do_max_length();
@@ -864,7 +972,7 @@
     static locale::id id;
 
 protected:
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     explicit codecvt(const char*, size_t __refs = 0)
         : locale::facet(__refs) {}
 
@@ -899,7 +1007,7 @@
 
     explicit codecvt(size_t __refs = 0);
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     result out(state_type& __st,
                const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
                extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
@@ -907,14 +1015,14 @@
         return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     result unshift(state_type& __st,
                    extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
     {
         return do_unshift(__st, __to, __to_end, __to_nxt);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     result in(state_type& __st,
               const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
               intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
@@ -922,25 +1030,25 @@
         return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     int encoding() const  _NOEXCEPT
     {
         return do_encoding();
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     bool always_noconv() const  _NOEXCEPT
     {
         return do_always_noconv();
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
     {
         return do_length(__st, __frm, __end, __mx);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     int max_length() const  _NOEXCEPT
     {
         return do_max_length();
@@ -967,10 +1075,10 @@
     virtual int do_max_length() const  _NOEXCEPT;
 };
 
-// template <> class codecvt<char16_t, char, mbstate_t>
+// template <> class codecvt<char16_t, char, mbstate_t> // deprecated in C++20
 
 template <>
-class _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
+class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
     : public locale::facet,
       public codecvt_base
 {
@@ -979,11 +1087,11 @@
     typedef char      extern_type;
     typedef mbstate_t state_type;
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     explicit codecvt(size_t __refs = 0)
         : locale::facet(__refs) {}
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     result out(state_type& __st,
                const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
                extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
@@ -991,14 +1099,14 @@
         return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     result unshift(state_type& __st,
                    extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
     {
         return do_unshift(__st, __to, __to_end, __to_nxt);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     result in(state_type& __st,
               const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
               intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
@@ -1006,25 +1114,25 @@
         return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     int encoding() const  _NOEXCEPT
     {
         return do_encoding();
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     bool always_noconv() const  _NOEXCEPT
     {
         return do_always_noconv();
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
     {
         return do_length(__st, __frm, __end, __mx);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     int max_length() const  _NOEXCEPT
     {
         return do_max_length();
@@ -1033,7 +1141,7 @@
     static locale::id id;
 
 protected:
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     explicit codecvt(const char*, size_t __refs = 0)
         : locale::facet(__refs) {}
 
@@ -1053,10 +1161,100 @@
     virtual int do_max_length() const  _NOEXCEPT;
 };
 
-// template <> class codecvt<char32_t, char, mbstate_t>
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+
+// template <> class codecvt<char16_t, char8_t, mbstate_t> // C++20
 
 template <>
-class _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
+class _LIBCPP_TYPE_VIS codecvt<char16_t, char8_t, mbstate_t>
+    : public locale::facet,
+      public codecvt_base
+{
+public:
+    typedef char16_t  intern_type;
+    typedef char8_t   extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit codecvt(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
+    {
+        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    result unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
+    {
+        return do_unshift(__st, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    result in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
+    {
+        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    int encoding() const  _NOEXCEPT
+    {
+        return do_encoding();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool always_noconv() const  _NOEXCEPT
+    {
+        return do_always_noconv();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
+    {
+        return do_length(__st, __frm, __end, __mx);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    int max_length() const  _NOEXCEPT
+    {
+        return do_max_length();
+    }
+
+    static locale::id id;
+
+protected:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit codecvt(const char*, size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    ~codecvt();
+
+    virtual result do_out(state_type& __st,
+                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result do_in(state_type& __st,
+                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result do_unshift(state_type& __st,
+                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const  _NOEXCEPT;
+    virtual bool do_always_noconv() const  _NOEXCEPT;
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
+    virtual int do_max_length() const  _NOEXCEPT;
+};
+
+#endif
+
+// template <> class codecvt<char32_t, char, mbstate_t> // deprecated in C++20
+
+template <>
+class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
     : public locale::facet,
       public codecvt_base
 {
@@ -1065,11 +1263,11 @@
     typedef char      extern_type;
     typedef mbstate_t state_type;
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     explicit codecvt(size_t __refs = 0)
         : locale::facet(__refs) {}
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     result out(state_type& __st,
                const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
                extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
@@ -1077,14 +1275,14 @@
         return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     result unshift(state_type& __st,
                    extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
     {
         return do_unshift(__st, __to, __to_end, __to_nxt);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     result in(state_type& __st,
               const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
               intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
@@ -1092,25 +1290,25 @@
         return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     int encoding() const  _NOEXCEPT
     {
         return do_encoding();
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     bool always_noconv() const  _NOEXCEPT
     {
         return do_always_noconv();
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
     {
         return do_length(__st, __frm, __end, __mx);
     }
 
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     int max_length() const  _NOEXCEPT
     {
         return do_max_length();
@@ -1119,7 +1317,7 @@
     static locale::id id;
 
 protected:
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     explicit codecvt(const char*, size_t __refs = 0)
         : locale::facet(__refs) {}
 
@@ -1139,34 +1337,128 @@
     virtual int do_max_length() const  _NOEXCEPT;
 };
 
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+
+// template <> class codecvt<char32_t, char8_t, mbstate_t> // C++20
+
+template <>
+class _LIBCPP_TYPE_VIS codecvt<char32_t, char8_t, mbstate_t>
+    : public locale::facet,
+      public codecvt_base
+{
+public:
+    typedef char32_t  intern_type;
+    typedef char8_t   extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit codecvt(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
+    {
+        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    result unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
+    {
+        return do_unshift(__st, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    result in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
+    {
+        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    int encoding() const  _NOEXCEPT
+    {
+        return do_encoding();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool always_noconv() const  _NOEXCEPT
+    {
+        return do_always_noconv();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
+    {
+        return do_length(__st, __frm, __end, __mx);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    int max_length() const  _NOEXCEPT
+    {
+        return do_max_length();
+    }
+
+    static locale::id id;
+
+protected:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit codecvt(const char*, size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    ~codecvt();
+
+    virtual result do_out(state_type& __st,
+                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result do_in(state_type& __st,
+                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result do_unshift(state_type& __st,
+                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const  _NOEXCEPT;
+    virtual bool do_always_noconv() const  _NOEXCEPT;
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
+    virtual int do_max_length() const  _NOEXCEPT;
+};
+
+#endif
+
 // template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
 
 template <class _InternT, class _ExternT, class _StateT>
-class _LIBCPP_TYPE_VIS_ONLY codecvt_byname
+class _LIBCPP_TEMPLATE_VIS codecvt_byname
     : public codecvt<_InternT, _ExternT, _StateT>
 {
 public:
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     explicit codecvt_byname(const char* __nm, size_t __refs = 0)
         : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     explicit codecvt_byname(const string& __nm, size_t __refs = 0)
         : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
 protected:
     ~codecvt_byname();
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _InternT, class _ExternT, class _StateT>
 codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
 {
 }
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 
-_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
-_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
-_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
-_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
-
-_LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
+_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
+_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
+_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>) // deprecated in C++20
+_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>) // deprecated in C++20
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char8_t, mbstate_t>) // C++20
+_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char8_t, mbstate_t>) // C++20
+#endif
 
 template <size_t _Np>
 struct __narrow_to_utf8
@@ -1180,7 +1472,7 @@
 struct __narrow_to_utf8<8>
 {
     template <class _OutputIterator, class _CharT>
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     _OutputIterator
     operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
     {
@@ -1190,17 +1482,19 @@
     }
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-struct __narrow_to_utf8<16>
+struct _LIBCPP_TYPE_VIS __narrow_to_utf8<16>
     : public codecvt<char16_t, char, mbstate_t>
 {
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 
     ~__narrow_to_utf8();
 
     template <class _OutputIterator, class _CharT>
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     _OutputIterator
     operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
     {
@@ -1224,17 +1518,19 @@
     }
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-struct __narrow_to_utf8<32>
+struct _LIBCPP_TYPE_VIS __narrow_to_utf8<32>
     : public codecvt<char32_t, char, mbstate_t>
 {
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 
     ~__narrow_to_utf8();
 
     template <class _OutputIterator, class _CharT>
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     _OutputIterator
     operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
     {
@@ -1270,7 +1566,7 @@
 struct __widen_from_utf8<8>
 {
     template <class _OutputIterator>
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     _OutputIterator
     operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
     {
@@ -1280,17 +1576,19 @@
     }
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-struct __widen_from_utf8<16>
+struct _LIBCPP_TYPE_VIS __widen_from_utf8<16>
     : public codecvt<char16_t, char, mbstate_t>
 {
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 
     ~__widen_from_utf8();
 
     template <class _OutputIterator>
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     _OutputIterator
     operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
     {
@@ -1307,24 +1605,26 @@
             if (__r == codecvt_base::error || __nn == __nb)
                 __throw_runtime_error("locale not supported");
             for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
-                *__s = (wchar_t)*__p;
+                *__s = *__p;
             __nb = __nn;
         }
         return __s;
     }
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
-struct __widen_from_utf8<32>
+struct _LIBCPP_TYPE_VIS __widen_from_utf8<32>
     : public codecvt<char32_t, char, mbstate_t>
 {
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 
     ~__widen_from_utf8();
 
     template <class _OutputIterator>
-    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_INLINE_VISIBILITY
     _OutputIterator
     operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
     {
@@ -1341,7 +1641,7 @@
             if (__r == codecvt_base::error || __nn == __nb)
                 __throw_runtime_error("locale not supported");
             for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
-                *__s = (wchar_t)*__p;
+                *__s = *__p;
             __nb = __nn;
         }
         return __s;
@@ -1350,7 +1650,7 @@
 
 // template <class charT> class numpunct
 
-template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY numpunct;
+template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct;
 
 template <>
 class _LIBCPP_TYPE_VIS numpunct<char>
@@ -1362,11 +1662,11 @@
 
     explicit numpunct(size_t __refs = 0);
 
-    _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
-    _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
-    _LIBCPP_ALWAYS_INLINE string grouping() const         {return do_grouping();}
-    _LIBCPP_ALWAYS_INLINE string_type truename() const    {return do_truename();}
-    _LIBCPP_ALWAYS_INLINE string_type falsename() const   {return do_falsename();}
+    _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
+    _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
+    _LIBCPP_INLINE_VISIBILITY string grouping() const         {return do_grouping();}
+    _LIBCPP_INLINE_VISIBILITY string_type truename() const    {return do_truename();}
+    _LIBCPP_INLINE_VISIBILITY string_type falsename() const   {return do_falsename();}
 
     static locale::id id;
 
@@ -1393,11 +1693,11 @@
 
     explicit numpunct(size_t __refs = 0);
 
-    _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
-    _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
-    _LIBCPP_ALWAYS_INLINE string grouping() const         {return do_grouping();}
-    _LIBCPP_ALWAYS_INLINE string_type truename() const    {return do_truename();}
-    _LIBCPP_ALWAYS_INLINE string_type falsename() const   {return do_falsename();}
+    _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
+    _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
+    _LIBCPP_INLINE_VISIBILITY string grouping() const         {return do_grouping();}
+    _LIBCPP_INLINE_VISIBILITY string_type truename() const    {return do_truename();}
+    _LIBCPP_INLINE_VISIBILITY string_type falsename() const   {return do_falsename();}
 
     static locale::id id;
 
@@ -1416,7 +1716,7 @@
 
 // template <class charT> class numpunct_byname
 
-template <class charT> class _LIBCPP_TYPE_VIS_ONLY numpunct_byname;
+template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname;
 
 template <>
 class _LIBCPP_TYPE_VIS numpunct_byname<char>
@@ -1456,4 +1756,4 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif  // _LIBCPP___LOCALE
+#endif // _LIBCPP___LOCALE
diff --git a/include/__memory/addressof.h b/include/__memory/addressof.h
new file mode 100644
index 0000000..5efdb58
--- /dev/null
+++ b/include/__memory/addressof.h
@@ -0,0 +1,96 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_ADDRESSOF_H
+#define _LIBCPP___MEMORY_ADDRESSOF_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_HAS_NO_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 reinterpret_cast<_Tp *>(
+      const_cast<char *>(&reinterpret_cast<const volatile char &>(__x)));
+}
+
+#endif // _LIBCPP_HAS_NO_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
+
+#if !defined(_LIBCPP_CXX03_LANG)
+template <class _Tp> _Tp* addressof(const _Tp&&) noexcept = delete;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_ADDRESSOF_H
diff --git a/include/__memory/allocation_guard.h b/include/__memory/allocation_guard.h
new file mode 100644
index 0000000..4987af2
--- /dev/null
+++ b/include/__memory/allocation_guard.h
@@ -0,0 +1,89 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_ALLOCATION_GUARD_H
+#define _LIBCPP___MEMORY_ALLOCATION_GUARD_H
+
+#include <__config>
+#include <__memory/allocator_traits.h>
+#include <cstddef>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Helper class to allocate memory using an Allocator in an exception safe
+// manner.
+//
+// The intended usage of this class is as follows:
+//
+// 0
+// 1     __allocation_guard<SomeAllocator> guard(alloc, 10);
+// 2     do_some_initialization_that_may_throw(guard.__get());
+// 3     save_allocated_pointer_in_a_noexcept_operation(guard.__release_ptr());
+// 4
+//
+// If line (2) throws an exception during initialization of the memory, the
+// guard's destructor will be called, and the memory will be released using
+// Allocator deallocation. Otherwise, we release the memory from the guard on
+// line (3) in an operation that can't throw -- after that, the guard is not
+// responsible for the memory anymore.
+//
+// This is similar to a unique_ptr, except it's easier to use with a
+// custom allocator.
+template<class _Alloc>
+struct __allocation_guard {
+    using _Pointer = typename allocator_traits<_Alloc>::pointer;
+    using _Size = typename allocator_traits<_Alloc>::size_type;
+
+    template<class _AllocT> // we perform the allocator conversion inside the constructor
+    _LIBCPP_HIDE_FROM_ABI
+    explicit __allocation_guard(_AllocT __alloc, _Size __n)
+        : __alloc_(_VSTD::move(__alloc))
+        , __n_(__n)
+        , __ptr_(allocator_traits<_Alloc>::allocate(__alloc_, __n_)) // initialization order is important
+    { }
+
+    _LIBCPP_HIDE_FROM_ABI
+    ~__allocation_guard() _NOEXCEPT {
+        if (__ptr_ != nullptr) {
+            allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __n_);
+        }
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    _Pointer __release_ptr() _NOEXCEPT { // not called __release() because it's a keyword in objective-c++
+        _Pointer __tmp = __ptr_;
+        __ptr_ = nullptr;
+        return __tmp;
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    _Pointer __get() const _NOEXCEPT {
+        return __ptr_;
+    }
+
+private:
+    _Alloc __alloc_;
+    _Size __n_;
+    _Pointer __ptr_;
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_ALLOCATION_GUARD_H
diff --git a/include/__memory/allocator.h b/include/__memory/allocator.h
new file mode 100644
index 0000000..2c21a16
--- /dev/null
+++ b/include/__memory/allocator.h
@@ -0,0 +1,254 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_ALLOCATOR_H
+#define _LIBCPP___MEMORY_ALLOCATOR_H
+
+#include <__config>
+#include <__memory/allocator_traits.h>
+#include <__utility/forward.h>
+#include <cstddef>
+#include <new>
+#include <stdexcept>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> class allocator;
+
+#if _LIBCPP_STD_VER <= 17
+template <>
+class _LIBCPP_TEMPLATE_VIS allocator<void>
+{
+public:
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef void*             pointer;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef const void*       const_pointer;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef void              value_type;
+
+    template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
+};
+
+template <>
+class _LIBCPP_TEMPLATE_VIS allocator<const void>
+{
+public:
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef const void*       pointer;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef const void*       const_pointer;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef const void        value_type;
+
+    template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
+};
+#endif
+
+// This class provides a non-trivial default constructor to the class that derives from it
+// if the condition is satisfied.
+//
+// The second template parameter exists to allow giving a unique type to __non_trivial_if,
+// which makes it possible to avoid breaking the ABI when making this a base class of an
+// existing class. Without that, imagine we have classes D1 and D2, both of which used to
+// have no base classes, but which now derive from __non_trivial_if. The layout of a class
+// that inherits from both D1 and D2 will change because the two __non_trivial_if base
+// classes are not allowed to share the same address.
+//
+// By making those __non_trivial_if base classes unique, we work around this problem and
+// it is safe to start deriving from __non_trivial_if in existing classes.
+template <bool _Cond, class _Unique>
+struct __non_trivial_if { };
+
+template <class _Unique>
+struct __non_trivial_if<true, _Unique> {
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR __non_trivial_if() _NOEXCEPT { }
+};
+
+// allocator
+//
+// Note: For ABI compatibility between C++20 and previous standards, we make
+//       allocator<void> trivial in C++20.
+
+template <class _Tp>
+class _LIBCPP_TEMPLATE_VIS allocator
+    : private __non_trivial_if<!is_void<_Tp>::value, allocator<_Tp> >
+{
+public:
+    typedef size_t      size_type;
+    typedef ptrdiff_t   difference_type;
+    typedef _Tp         value_type;
+    typedef true_type   propagate_on_container_move_assignment;
+    typedef true_type   is_always_equal;
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    allocator() _NOEXCEPT _LIBCPP_DEFAULT
+
+    template <class _Up>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    allocator(const allocator<_Up>&) _NOEXCEPT { }
+
+    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    _Tp* allocate(size_t __n) {
+        if (__n > allocator_traits<allocator>::max_size(*this))
+            __throw_length_error("allocator<T>::allocate(size_t n)"
+                                 " 'n' exceeds maximum supported size");
+        if (__libcpp_is_constant_evaluated()) {
+            return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
+        } else {
+            return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
+        }
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    void deallocate(_Tp* __p, size_t __n) _NOEXCEPT {
+        if (__libcpp_is_constant_evaluated()) {
+            ::operator delete(__p);
+        } else {
+            _VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
+        }
+    }
+
+    // C++20 Removed members
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp*       pointer;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp&       reference;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
+
+    template <class _Up>
+    struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
+        typedef allocator<_Up> other;
+    };
+
+    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
+    pointer address(reference __x) const _NOEXCEPT {
+        return _VSTD::addressof(__x);
+    }
+    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
+    const_pointer address(const_reference __x) const _NOEXCEPT {
+        return _VSTD::addressof(__x);
+    }
+
+    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
+    _Tp* allocate(size_t __n, const void*) {
+        return allocate(__n);
+    }
+
+    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
+        return size_type(~0) / sizeof(_Tp);
+    }
+
+    template <class _Up, class... _Args>
+    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
+    void construct(_Up* __p, _Args&&... __args) {
+        ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
+    }
+
+    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
+    void destroy(pointer __p) {
+        __p->~_Tp();
+    }
+#endif
+};
+
+template <class _Tp>
+class _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
+    : private __non_trivial_if<!is_void<_Tp>::value, allocator<const _Tp> >
+{
+public:
+    typedef size_t      size_type;
+    typedef ptrdiff_t   difference_type;
+    typedef const _Tp   value_type;
+    typedef true_type   propagate_on_container_move_assignment;
+    typedef true_type   is_always_equal;
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    allocator() _NOEXCEPT _LIBCPP_DEFAULT
+
+    template <class _Up>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    allocator(const allocator<_Up>&) _NOEXCEPT { }
+
+    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    const _Tp* allocate(size_t __n) {
+        if (__n > allocator_traits<allocator>::max_size(*this))
+            __throw_length_error("allocator<const T>::allocate(size_t n)"
+                                 " 'n' exceeds maximum supported size");
+        if (__libcpp_is_constant_evaluated()) {
+            return static_cast<const _Tp*>(::operator new(__n * sizeof(_Tp)));
+        } else {
+            return static_cast<const _Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
+        }
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    void deallocate(const _Tp* __p, size_t __n) {
+        if (__libcpp_is_constant_evaluated()) {
+            ::operator delete(const_cast<_Tp*>(__p));
+        } else {
+            _VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
+        }
+    }
+
+    // C++20 Removed members
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* pointer;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& reference;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
+
+    template <class _Up>
+    struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
+        typedef allocator<_Up> other;
+    };
+
+    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
+    const_pointer address(const_reference __x) const _NOEXCEPT {
+        return _VSTD::addressof(__x);
+    }
+
+    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
+    const _Tp* allocate(size_t __n, const void*) {
+        return allocate(__n);
+    }
+
+    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
+        return size_type(~0) / sizeof(_Tp);
+    }
+
+    template <class _Up, class... _Args>
+    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
+    void construct(_Up* __p, _Args&&... __args) {
+        ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
+    }
+
+    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
+    void destroy(pointer __p) {
+        __p->~_Tp();
+    }
+#endif
+};
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;}
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+bool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_ALLOCATOR_H
diff --git a/include/__memory/allocator_arg_t.h b/include/__memory/allocator_arg_t.h
new file mode 100644
index 0000000..830c6b8
--- /dev/null
+++ b/include/__memory/allocator_arg_t.h
@@ -0,0 +1,78 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FUNCTIONAL___ALLOCATOR_ARG_T_H
+#define _LIBCPP___FUNCTIONAL___ALLOCATOR_ARG_T_H
+
+#include <__config>
+#include <__memory/uses_allocator.h>
+#include <__utility/forward.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; };
+
+#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
+extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg;
+#else
+/* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
+#endif
+
+#ifndef _LIBCPP_CXX03_LANG
+
+// allocator construction
+
+template <class _Tp, class _Alloc, class ..._Args>
+struct __uses_alloc_ctor_imp
+{
+    typedef _LIBCPP_NODEBUG_TYPE typename __uncvref<_Alloc>::type _RawAlloc;
+    static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value;
+    static const bool __ic =
+        is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
+    static const int value = __ua ? 2 - __ic : 0;
+};
+
+template <class _Tp, class _Alloc, class ..._Args>
+struct __uses_alloc_ctor
+    : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
+    {};
+
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args )
+{
+    new (__storage) _Tp (_VSTD::forward<_Args>(__args)...);
+}
+
+// FIXME: This should have a version which takes a non-const alloc.
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
+{
+    new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
+}
+
+// FIXME: This should have a version which takes a non-const alloc.
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
+{
+    new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
+}
+
+#endif // _LIBCPP_CXX03_LANG
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FUNCTIONAL___ALLOCATOR_ARG_T_H
diff --git a/include/__memory/allocator_traits.h b/include/__memory/allocator_traits.h
new file mode 100644
index 0000000..a02af0d
--- /dev/null
+++ b/include/__memory/allocator_traits.h
@@ -0,0 +1,405 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_ALLOCATOR_TRAITS_H
+#define _LIBCPP___MEMORY_ALLOCATOR_TRAITS_H
+
+#include <__config>
+#include <__memory/construct_at.h>
+#include <__memory/pointer_traits.h>
+#include <__utility/forward.h>
+#include <limits>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#define _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(NAME, PROPERTY)                \
+    template <class _Tp, class = void> struct NAME : false_type { };    \
+    template <class _Tp>               struct NAME<_Tp, typename __void_t<typename _Tp:: PROPERTY >::type> : true_type { }
+
+// __pointer
+_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_pointer, pointer);
+template <class _Tp, class _Alloc,
+          class _RawAlloc = typename remove_reference<_Alloc>::type,
+          bool = __has_pointer<_RawAlloc>::value>
+struct __pointer {
+    using type _LIBCPP_NODEBUG_TYPE = typename _RawAlloc::pointer;
+};
+template <class _Tp, class _Alloc, class _RawAlloc>
+struct __pointer<_Tp, _Alloc, _RawAlloc, false> {
+    using type _LIBCPP_NODEBUG_TYPE = _Tp*;
+};
+
+// __const_pointer
+_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_const_pointer, const_pointer);
+template <class _Tp, class _Ptr, class _Alloc,
+          bool = __has_const_pointer<_Alloc>::value>
+struct __const_pointer {
+    using type _LIBCPP_NODEBUG_TYPE = typename _Alloc::const_pointer;
+};
+template <class _Tp, class _Ptr, class _Alloc>
+struct __const_pointer<_Tp, _Ptr, _Alloc, false> {
+#ifdef _LIBCPP_CXX03_LANG
+    using type = typename pointer_traits<_Ptr>::template rebind<const _Tp>::other;
+#else
+    using type _LIBCPP_NODEBUG_TYPE = typename pointer_traits<_Ptr>::template rebind<const _Tp>;
+#endif
+};
+
+// __void_pointer
+_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_void_pointer, void_pointer);
+template <class _Ptr, class _Alloc,
+          bool = __has_void_pointer<_Alloc>::value>
+struct __void_pointer {
+    using type _LIBCPP_NODEBUG_TYPE = typename _Alloc::void_pointer;
+};
+template <class _Ptr, class _Alloc>
+struct __void_pointer<_Ptr, _Alloc, false> {
+#ifdef _LIBCPP_CXX03_LANG
+    using type _LIBCPP_NODEBUG_TYPE = typename pointer_traits<_Ptr>::template rebind<void>::other;
+#else
+    using type _LIBCPP_NODEBUG_TYPE = typename pointer_traits<_Ptr>::template rebind<void>;
+#endif
+};
+
+// __const_void_pointer
+_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_const_void_pointer, const_void_pointer);
+template <class _Ptr, class _Alloc,
+          bool = __has_const_void_pointer<_Alloc>::value>
+struct __const_void_pointer {
+    using type _LIBCPP_NODEBUG_TYPE = typename _Alloc::const_void_pointer;
+};
+template <class _Ptr, class _Alloc>
+struct __const_void_pointer<_Ptr, _Alloc, false> {
+#ifdef _LIBCPP_CXX03_LANG
+    using type _LIBCPP_NODEBUG_TYPE = typename pointer_traits<_Ptr>::template rebind<const void>::other;
+#else
+    using type _LIBCPP_NODEBUG_TYPE = typename pointer_traits<_Ptr>::template rebind<const void>;
+#endif
+};
+
+// __size_type
+_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_size_type, size_type);
+template <class _Alloc, class _DiffType, bool = __has_size_type<_Alloc>::value>
+struct __size_type : make_unsigned<_DiffType> { };
+template <class _Alloc, class _DiffType>
+struct __size_type<_Alloc, _DiffType, true> {
+    using type _LIBCPP_NODEBUG_TYPE = typename _Alloc::size_type;
+};
+
+// __alloc_traits_difference_type
+_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_alloc_traits_difference_type, difference_type);
+template <class _Alloc, class _Ptr, bool = __has_alloc_traits_difference_type<_Alloc>::value>
+struct __alloc_traits_difference_type {
+    using type _LIBCPP_NODEBUG_TYPE = typename pointer_traits<_Ptr>::difference_type;
+};
+template <class _Alloc, class _Ptr>
+struct __alloc_traits_difference_type<_Alloc, _Ptr, true> {
+    using type _LIBCPP_NODEBUG_TYPE = typename _Alloc::difference_type;
+};
+
+// __propagate_on_container_copy_assignment
+_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_propagate_on_container_copy_assignment, propagate_on_container_copy_assignment);
+template <class _Alloc, bool = __has_propagate_on_container_copy_assignment<_Alloc>::value>
+struct __propagate_on_container_copy_assignment : false_type { };
+template <class _Alloc>
+struct __propagate_on_container_copy_assignment<_Alloc, true> {
+    using type _LIBCPP_NODEBUG_TYPE = typename _Alloc::propagate_on_container_copy_assignment;
+};
+
+// __propagate_on_container_move_assignment
+_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_propagate_on_container_move_assignment, propagate_on_container_move_assignment);
+template <class _Alloc, bool = __has_propagate_on_container_move_assignment<_Alloc>::value>
+struct __propagate_on_container_move_assignment : false_type { };
+template <class _Alloc>
+struct __propagate_on_container_move_assignment<_Alloc, true> {
+    using type _LIBCPP_NODEBUG_TYPE = typename _Alloc::propagate_on_container_move_assignment;
+};
+
+// __propagate_on_container_swap
+_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_propagate_on_container_swap, propagate_on_container_swap);
+template <class _Alloc, bool = __has_propagate_on_container_swap<_Alloc>::value>
+struct __propagate_on_container_swap : false_type { };
+template <class _Alloc>
+struct __propagate_on_container_swap<_Alloc, true> {
+    using type _LIBCPP_NODEBUG_TYPE = typename _Alloc::propagate_on_container_swap;
+};
+
+// __is_always_equal
+_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_is_always_equal, is_always_equal);
+template <class _Alloc, bool = __has_is_always_equal<_Alloc>::value>
+struct __is_always_equal : is_empty<_Alloc> { };
+template <class _Alloc>
+struct __is_always_equal<_Alloc, true> {
+    using type _LIBCPP_NODEBUG_TYPE = typename _Alloc::is_always_equal;
+};
+
+// __allocator_traits_rebind
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Tp, class _Up, class = void>
+struct __has_rebind_other : false_type { };
+template <class _Tp, class _Up>
+struct __has_rebind_other<_Tp, _Up, typename __void_t<
+    typename _Tp::template rebind<_Up>::other
+>::type> : true_type { };
+
+template <class _Tp, class _Up, bool = __has_rebind_other<_Tp, _Up>::value>
+struct __allocator_traits_rebind {
+    using type _LIBCPP_NODEBUG_TYPE = typename _Tp::template rebind<_Up>::other;
+};
+template <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
+struct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, true> {
+    using type _LIBCPP_NODEBUG_TYPE = typename _Alloc<_Tp, _Args...>::template rebind<_Up>::other;
+};
+template <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
+struct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, false> {
+    using type _LIBCPP_NODEBUG_TYPE = _Alloc<_Up, _Args...>;
+};
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+
+template<class _Alloc, class _Tp>
+using __allocator_traits_rebind_t = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+
+// __has_allocate_hint
+template <class _Alloc, class _SizeType, class _ConstVoidPtr, class = void>
+struct __has_allocate_hint : false_type { };
+
+template <class _Alloc, class _SizeType, class _ConstVoidPtr>
+struct __has_allocate_hint<_Alloc, _SizeType, _ConstVoidPtr, decltype(
+    (void)declval<_Alloc>().allocate(declval<_SizeType>(), declval<_ConstVoidPtr>())
+)> : true_type { };
+
+// __has_construct
+template <class, class _Alloc, class ..._Args>
+struct __has_construct_impl : false_type { };
+
+template <class _Alloc, class ..._Args>
+struct __has_construct_impl<decltype(
+    (void)declval<_Alloc>().construct(declval<_Args>()...)
+), _Alloc, _Args...> : true_type { };
+
+template <class _Alloc, class ..._Args>
+struct __has_construct : __has_construct_impl<void, _Alloc, _Args...> { };
+
+// __has_destroy
+template <class _Alloc, class _Pointer, class = void>
+struct __has_destroy : false_type { };
+
+template <class _Alloc, class _Pointer>
+struct __has_destroy<_Alloc, _Pointer, decltype(
+    (void)declval<_Alloc>().destroy(declval<_Pointer>())
+)> : true_type { };
+
+// __has_max_size
+template <class _Alloc, class = void>
+struct __has_max_size : false_type { };
+
+template <class _Alloc>
+struct __has_max_size<_Alloc, decltype(
+    (void)declval<_Alloc&>().max_size()
+)> : true_type { };
+
+// __has_select_on_container_copy_construction
+template <class _Alloc, class = void>
+struct __has_select_on_container_copy_construction : false_type { };
+
+template <class _Alloc>
+struct __has_select_on_container_copy_construction<_Alloc, decltype(
+    (void)declval<_Alloc>().select_on_container_copy_construction()
+)> : true_type { };
+
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+
+template <class _Alloc>
+struct _LIBCPP_TEMPLATE_VIS allocator_traits
+{
+    using allocator_type = _Alloc;
+    using value_type = typename allocator_type::value_type;
+    using pointer = typename __pointer<value_type, allocator_type>::type;
+    using const_pointer = typename __const_pointer<value_type, pointer, allocator_type>::type;
+    using void_pointer = typename __void_pointer<pointer, allocator_type>::type;
+    using const_void_pointer = typename __const_void_pointer<pointer, allocator_type>::type;
+    using difference_type = typename __alloc_traits_difference_type<allocator_type, pointer>::type;
+    using size_type = typename __size_type<allocator_type, difference_type>::type;
+    using propagate_on_container_copy_assignment = typename __propagate_on_container_copy_assignment<allocator_type>::type;
+    using propagate_on_container_move_assignment = typename __propagate_on_container_move_assignment<allocator_type>::type;
+    using propagate_on_container_swap = typename __propagate_on_container_swap<allocator_type>::type;
+    using is_always_equal = typename __is_always_equal<allocator_type>::type;
+
+#ifndef _LIBCPP_CXX03_LANG
+    template <class _Tp>
+    using rebind_alloc = __allocator_traits_rebind_t<allocator_type, _Tp>;
+    template <class _Tp>
+    using rebind_traits = allocator_traits<rebind_alloc<_Tp> >;
+#else  // _LIBCPP_CXX03_LANG
+    template <class _Tp>
+    struct rebind_alloc {
+        using other = __allocator_traits_rebind_t<allocator_type, _Tp>;
+    };
+    template <class _Tp>
+    struct rebind_traits {
+        using other = allocator_traits<typename rebind_alloc<_Tp>::other>;
+    };
+#endif // _LIBCPP_CXX03_LANG
+
+    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static pointer allocate(allocator_type& __a, size_type __n) {
+        return __a.allocate(__n);
+    }
+
+    template <class _Ap = _Alloc, class =
+        _EnableIf<__has_allocate_hint<_Ap, size_type, const_void_pointer>::value> >
+    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer __hint) {
+        _LIBCPP_SUPPRESS_DEPRECATED_PUSH
+        return __a.allocate(__n, __hint);
+        _LIBCPP_SUPPRESS_DEPRECATED_POP
+    }
+    template <class _Ap = _Alloc, class = void, class =
+        _EnableIf<!__has_allocate_hint<_Ap, size_type, const_void_pointer>::value> >
+    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer) {
+        return __a.allocate(__n);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static void deallocate(allocator_type& __a, pointer __p, size_type __n) _NOEXCEPT {
+        __a.deallocate(__p, __n);
+    }
+
+    template <class _Tp, class... _Args, class =
+        _EnableIf<__has_construct<allocator_type, _Tp*, _Args...>::value> >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static void construct(allocator_type& __a, _Tp* __p, _Args&&... __args) {
+        _LIBCPP_SUPPRESS_DEPRECATED_PUSH
+        __a.construct(__p, _VSTD::forward<_Args>(__args)...);
+        _LIBCPP_SUPPRESS_DEPRECATED_POP
+    }
+    template <class _Tp, class... _Args, class = void, class =
+        _EnableIf<!__has_construct<allocator_type, _Tp*, _Args...>::value> >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static void construct(allocator_type&, _Tp* __p, _Args&&... __args) {
+#if _LIBCPP_STD_VER > 17
+        _VSTD::construct_at(__p, _VSTD::forward<_Args>(__args)...);
+#else
+        ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);
+#endif
+    }
+
+    template <class _Tp, class =
+        _EnableIf<__has_destroy<allocator_type, _Tp*>::value> >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static void destroy(allocator_type& __a, _Tp* __p) {
+        _LIBCPP_SUPPRESS_DEPRECATED_PUSH
+        __a.destroy(__p);
+        _LIBCPP_SUPPRESS_DEPRECATED_POP
+    }
+    template <class _Tp, class = void, class =
+        _EnableIf<!__has_destroy<allocator_type, _Tp*>::value> >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static void destroy(allocator_type&, _Tp* __p) {
+#if _LIBCPP_STD_VER > 17
+        _VSTD::destroy_at(__p);
+#else
+        __p->~_Tp();
+#endif
+    }
+
+    template <class _Ap = _Alloc, class =
+        _EnableIf<__has_max_size<const _Ap>::value> >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static size_type max_size(const allocator_type& __a) _NOEXCEPT {
+        _LIBCPP_SUPPRESS_DEPRECATED_PUSH
+        return __a.max_size();
+        _LIBCPP_SUPPRESS_DEPRECATED_POP
+    }
+    template <class _Ap = _Alloc, class = void, class =
+        _EnableIf<!__has_max_size<const _Ap>::value> >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static size_type max_size(const allocator_type&) _NOEXCEPT {
+        return numeric_limits<size_type>::max() / sizeof(value_type);
+    }
+
+    template <class _Ap = _Alloc, class =
+        _EnableIf<__has_select_on_container_copy_construction<const _Ap>::value> >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static allocator_type select_on_container_copy_construction(const allocator_type& __a) {
+        return __a.select_on_container_copy_construction();
+    }
+    template <class _Ap = _Alloc, class = void, class =
+        _EnableIf<!__has_select_on_container_copy_construction<const _Ap>::value> >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static allocator_type select_on_container_copy_construction(const allocator_type& __a) {
+        return __a;
+    }
+};
+
+template <class _Traits, class _Tp>
+struct __rebind_alloc_helper {
+#ifndef _LIBCPP_CXX03_LANG
+    using type _LIBCPP_NODEBUG_TYPE = typename _Traits::template rebind_alloc<_Tp>;
+#else
+    using type = typename _Traits::template rebind_alloc<_Tp>::other;
+#endif
+};
+
+// __is_default_allocator
+template <class _Tp>
+struct __is_default_allocator : false_type { };
+
+template <class> class allocator;
+
+template <class _Tp>
+struct __is_default_allocator<allocator<_Tp> > : true_type { };
+
+// __is_cpp17_move_insertable
+template <class _Alloc, class = void>
+struct __is_cpp17_move_insertable
+    : is_move_constructible<typename _Alloc::value_type>
+{ };
+
+template <class _Alloc>
+struct __is_cpp17_move_insertable<_Alloc, _EnableIf<
+    !__is_default_allocator<_Alloc>::value &&
+    __has_construct<_Alloc, typename _Alloc::value_type*, typename _Alloc::value_type&&>::value
+> > : true_type { };
+
+// __is_cpp17_copy_insertable
+template <class _Alloc, class = void>
+struct __is_cpp17_copy_insertable
+    : integral_constant<bool,
+        is_copy_constructible<typename _Alloc::value_type>::value &&
+        __is_cpp17_move_insertable<_Alloc>::value
+    >
+{ };
+
+template <class _Alloc>
+struct __is_cpp17_copy_insertable<_Alloc, _EnableIf<
+    !__is_default_allocator<_Alloc>::value &&
+    __has_construct<_Alloc, typename _Alloc::value_type*, const typename _Alloc::value_type&>::value
+> >
+    : __is_cpp17_move_insertable<_Alloc>
+{ };
+
+#undef _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_ALLOCATOR_TRAITS_H
diff --git a/include/__memory/auto_ptr.h b/include/__memory/auto_ptr.h
new file mode 100644
index 0000000..f8d2b50
--- /dev/null
+++ b/include/__memory/auto_ptr.h
@@ -0,0 +1,86 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_AUTO_PTR_H
+#define _LIBCPP___MEMORY_AUTO_PTR_H
+
+#include <__config>
+#include <__nullptr>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr_ref
+{
+    _Tp* __ptr_;
+};
+
+template<class _Tp>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr
+{
+private:
+    _Tp* __ptr_;
+public:
+    typedef _Tp element_type;
+
+    _LIBCPP_INLINE_VISIBILITY explicit auto_ptr(_Tp* __p = 0) _NOEXCEPT : __ptr_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr& __p) _NOEXCEPT : __ptr_(__p.release()) {}
+    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr<_Up>& __p) _NOEXCEPT
+        : __ptr_(__p.release()) {}
+    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr& __p) _NOEXCEPT
+        {reset(__p.release()); return *this;}
+    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr<_Up>& __p) _NOEXCEPT
+        {reset(__p.release()); return *this;}
+    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr_ref<_Tp> __p) _NOEXCEPT
+        {reset(__p.__ptr_); return *this;}
+    _LIBCPP_INLINE_VISIBILITY ~auto_ptr() _NOEXCEPT {delete __ptr_;}
+
+    _LIBCPP_INLINE_VISIBILITY _Tp& operator*() const _NOEXCEPT
+        {return *__ptr_;}
+    _LIBCPP_INLINE_VISIBILITY _Tp* operator->() const _NOEXCEPT {return __ptr_;}
+    _LIBCPP_INLINE_VISIBILITY _Tp* get() const _NOEXCEPT {return __ptr_;}
+    _LIBCPP_INLINE_VISIBILITY _Tp* release() _NOEXCEPT
+    {
+        _Tp* __t = __ptr_;
+        __ptr_ = nullptr;
+        return __t;
+    }
+    _LIBCPP_INLINE_VISIBILITY void reset(_Tp* __p = 0) _NOEXCEPT
+    {
+        if (__ptr_ != __p)
+            delete __ptr_;
+        __ptr_ = __p;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr_ref<_Tp> __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
+    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr_ref<_Up>() _NOEXCEPT
+        {auto_ptr_ref<_Up> __t; __t.__ptr_ = release(); return __t;}
+    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr<_Up>() _NOEXCEPT
+        {return auto_ptr<_Up>(release());}
+};
+
+template <>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr<void>
+{
+public:
+    typedef void element_type;
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_AUTO_PTR_H
diff --git a/include/__memory/compressed_pair.h b/include/__memory/compressed_pair.h
new file mode 100644
index 0000000..08f0318
--- /dev/null
+++ b/include/__memory/compressed_pair.h
@@ -0,0 +1,201 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_COMPRESSED_PAIR_H
+#define _LIBCPP___MEMORY_COMPRESSED_PAIR_H
+
+#include <__config>
+#include <__utility/forward.h>
+#include <tuple> // needed in c++03 for some constructors
+#include <type_traits>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Tag used to default initialize one or both of the pair's elements.
+struct __default_init_tag {};
+struct __value_init_tag {};
+
+template <class _Tp, int _Idx,
+          bool _CanBeEmptyBase =
+              is_empty<_Tp>::value && !__libcpp_is_final<_Tp>::value>
+struct __compressed_pair_elem {
+  typedef _Tp _ParamT;
+  typedef _Tp& reference;
+  typedef const _Tp& const_reference;
+
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+  __compressed_pair_elem(__default_init_tag) {}
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+  __compressed_pair_elem(__value_init_tag) : __value_() {}
+
+  template <class _Up, class = typename enable_if<
+      !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
+  >::type>
+  _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_CONSTEXPR explicit
+  __compressed_pair_elem(_Up&& __u)
+      : __value_(_VSTD::forward<_Up>(__u))
+    {
+    }
+
+
+#ifndef _LIBCPP_CXX03_LANG
+  template <class... _Args, size_t... _Indexes>
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+  __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
+                         __tuple_indices<_Indexes...>)
+      : __value_(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
+#endif
+
+
+  _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return __value_; }
+  _LIBCPP_INLINE_VISIBILITY
+  const_reference __get() const _NOEXCEPT { return __value_; }
+
+private:
+  _Tp __value_;
+};
+
+template <class _Tp, int _Idx>
+struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {
+  typedef _Tp _ParamT;
+  typedef _Tp& reference;
+  typedef const _Tp& const_reference;
+  typedef _Tp __value_type;
+
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __compressed_pair_elem() = default;
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+  __compressed_pair_elem(__default_init_tag) {}
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+  __compressed_pair_elem(__value_init_tag) : __value_type() {}
+
+  template <class _Up, class = typename enable_if<
+        !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
+  >::type>
+  _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_CONSTEXPR explicit
+  __compressed_pair_elem(_Up&& __u)
+      : __value_type(_VSTD::forward<_Up>(__u))
+  {}
+
+#ifndef _LIBCPP_CXX03_LANG
+  template <class... _Args, size_t... _Indexes>
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+  __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
+                         __tuple_indices<_Indexes...>)
+      : __value_type(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
+#endif
+
+  _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return *this; }
+  _LIBCPP_INLINE_VISIBILITY
+  const_reference __get() const _NOEXCEPT { return *this; }
+};
+
+template <class _T1, class _T2>
+class __compressed_pair : private __compressed_pair_elem<_T1, 0>,
+                          private __compressed_pair_elem<_T2, 1> {
+public:
+  // NOTE: This static assert should never fire because __compressed_pair
+  // is *almost never* used in a scenario where it's possible for T1 == T2.
+  // (The exception is std::function where it is possible that the function
+  //  object and the allocator have the same type).
+  static_assert((!is_same<_T1, _T2>::value),
+    "__compressed_pair cannot be instantiated when T1 and T2 are the same type; "
+    "The current implementation is NOT ABI-compatible with the previous "
+    "implementation for this configuration");
+
+    typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T1, 0> _Base1;
+    typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T2, 1> _Base2;
+
+    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
+  >
+  _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_CONSTEXPR __compressed_pair() : _Base1(__value_init_tag()), _Base2(__value_init_tag()) {}
+
+  template <class _U1, class _U2>
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+  __compressed_pair(_U1&& __t1, _U2&& __t2)
+      : _Base1(_VSTD::forward<_U1>(__t1)), _Base2(_VSTD::forward<_U2>(__t2)) {}
+
+#ifndef _LIBCPP_CXX03_LANG
+  template <class... _Args1, class... _Args2>
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+  __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
+                    tuple<_Args2...> __second_args)
+      : _Base1(__pc, _VSTD::move(__first_args),
+               typename __make_tuple_indices<sizeof...(_Args1)>::type()),
+        _Base2(__pc, _VSTD::move(__second_args),
+               typename __make_tuple_indices<sizeof...(_Args2)>::type()) {}
+#endif
+
+  _LIBCPP_INLINE_VISIBILITY
+  typename _Base1::reference first() _NOEXCEPT {
+    return static_cast<_Base1&>(*this).__get();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  typename _Base1::const_reference first() const _NOEXCEPT {
+    return static_cast<_Base1 const&>(*this).__get();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  typename _Base2::reference second() _NOEXCEPT {
+    return static_cast<_Base2&>(*this).__get();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  typename _Base2::const_reference second() const _NOEXCEPT {
+    return static_cast<_Base2 const&>(*this).__get();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+  static _Base1* __get_first_base(__compressed_pair* __pair) _NOEXCEPT {
+    return static_cast<_Base1*>(__pair);
+  }
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+  static _Base2* __get_second_base(__compressed_pair* __pair) _NOEXCEPT {
+    return static_cast<_Base2*>(__pair);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void swap(__compressed_pair& __x)
+    _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
+               __is_nothrow_swappable<_T2>::value)
+  {
+    using _VSTD::swap;
+    swap(first(), __x.first());
+    swap(second(), __x.second());
+  }
+};
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+void swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)
+    _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
+               __is_nothrow_swappable<_T2>::value) {
+  __x.swap(__y);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_COMPRESSED_PAIR_H
diff --git a/include/__memory/construct_at.h b/include/__memory/construct_at.h
new file mode 100644
index 0000000..7ab1931
--- /dev/null
+++ b/include/__memory/construct_at.h
@@ -0,0 +1,59 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_CONSTRUCT_AT_H
+#define _LIBCPP___MEMORY_CONSTRUCT_AT_H
+
+#include <__config>
+#include <__debug>
+#include <__utility/forward.h>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// construct_at
+
+#if _LIBCPP_STD_VER > 17
+
+template<class _Tp, class ..._Args, class = decltype(
+    ::new (declval<void*>()) _Tp(declval<_Args>()...)
+)>
+_LIBCPP_INLINE_VISIBILITY
+constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) {
+    _LIBCPP_ASSERT(__location, "null pointer given to construct_at");
+    return ::new ((void*)__location) _Tp(_VSTD::forward<_Args>(__args)...);
+}
+
+#endif
+
+// destroy_at
+
+#if _LIBCPP_STD_VER > 14
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void destroy_at(_Tp* __loc) {
+    _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at");
+    __loc->~_Tp();
+}
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_CONSTRUCT_AT_H
diff --git a/include/__memory/pointer_safety.h b/include/__memory/pointer_safety.h
new file mode 100644
index 0000000..87a6a96
--- /dev/null
+++ b/include/__memory/pointer_safety.h
@@ -0,0 +1,57 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_POINTER_SAFETY_H
+#define _LIBCPP___MEMORY_POINTER_SAFETY_H
+
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_CXX03_LANG)
+
+enum class pointer_safety : unsigned char {
+  relaxed,
+  preferred,
+  strict
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+pointer_safety get_pointer_safety() _NOEXCEPT {
+  return pointer_safety::relaxed;
+}
+
+_LIBCPP_FUNC_VIS void declare_reachable(void* __p);
+_LIBCPP_FUNC_VIS void declare_no_pointers(char* __p, size_t __n);
+_LIBCPP_FUNC_VIS void undeclare_no_pointers(char* __p, size_t __n);
+_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* __p);
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+undeclare_reachable(_Tp* __p)
+{
+    return static_cast<_Tp*>(__undeclare_reachable(__p));
+}
+
+#endif // !C++03
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_POINTER_SAFETY_H
diff --git a/include/__memory/pointer_traits.h b/include/__memory/pointer_traits.h
new file mode 100644
index 0000000..d5442b8
--- /dev/null
+++ b/include/__memory/pointer_traits.h
@@ -0,0 +1,216 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_POINTER_TRAITS_H
+#define _LIBCPP___MEMORY_POINTER_TRAITS_H
+
+#include <__config>
+#include <__memory/addressof.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, class = void>
+struct __has_element_type : false_type {};
+
+template <class _Tp>
+struct __has_element_type<_Tp,
+              typename __void_t<typename _Tp::element_type>::type> : true_type {};
+
+template <class _Ptr, bool = __has_element_type<_Ptr>::value>
+struct __pointer_traits_element_type;
+
+template <class _Ptr>
+struct __pointer_traits_element_type<_Ptr, true>
+{
+    typedef _LIBCPP_NODEBUG_TYPE typename _Ptr::element_type type;
+};
+
+template <template <class, class...> class _Sp, class _Tp, class ..._Args>
+struct __pointer_traits_element_type<_Sp<_Tp, _Args...>, true>
+{
+    typedef _LIBCPP_NODEBUG_TYPE typename _Sp<_Tp, _Args...>::element_type type;
+};
+
+template <template <class, class...> class _Sp, class _Tp, class ..._Args>
+struct __pointer_traits_element_type<_Sp<_Tp, _Args...>, false>
+{
+    typedef _LIBCPP_NODEBUG_TYPE _Tp type;
+};
+
+template <class _Tp, class = void>
+struct __has_difference_type : false_type {};
+
+template <class _Tp>
+struct __has_difference_type<_Tp,
+            typename __void_t<typename _Tp::difference_type>::type> : true_type {};
+
+template <class _Ptr, bool = __has_difference_type<_Ptr>::value>
+struct __pointer_traits_difference_type
+{
+    typedef _LIBCPP_NODEBUG_TYPE ptrdiff_t type;
+};
+
+template <class _Ptr>
+struct __pointer_traits_difference_type<_Ptr, true>
+{
+    typedef _LIBCPP_NODEBUG_TYPE typename _Ptr::difference_type type;
+};
+
+template <class _Tp, class _Up>
+struct __has_rebind
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Xp> static __two __test(...);
+    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
+    template <class _Xp> static char __test(typename _Xp::template rebind<_Up>* = 0);
+    _LIBCPP_SUPPRESS_DEPRECATED_POP
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
+struct __pointer_traits_rebind
+{
+#ifndef _LIBCPP_CXX03_LANG
+    typedef _LIBCPP_NODEBUG_TYPE typename _Tp::template rebind<_Up> type;
+#else
+    typedef _LIBCPP_NODEBUG_TYPE typename _Tp::template rebind<_Up>::other type;
+#endif
+};
+
+template <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>
+struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, true>
+{
+#ifndef _LIBCPP_CXX03_LANG
+    typedef _LIBCPP_NODEBUG_TYPE typename _Sp<_Tp, _Args...>::template rebind<_Up> type;
+#else
+    typedef _LIBCPP_NODEBUG_TYPE typename _Sp<_Tp, _Args...>::template rebind<_Up>::other type;
+#endif
+};
+
+template <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>
+struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, false>
+{
+    typedef _Sp<_Up, _Args...> type;
+};
+
+template <class _Ptr>
+struct _LIBCPP_TEMPLATE_VIS pointer_traits
+{
+    typedef _Ptr                                                     pointer;
+    typedef typename __pointer_traits_element_type<pointer>::type    element_type;
+    typedef typename __pointer_traits_difference_type<pointer>::type difference_type;
+
+#ifndef _LIBCPP_CXX03_LANG
+    template <class _Up> using rebind = typename __pointer_traits_rebind<pointer, _Up>::type;
+#else
+    template <class _Up> struct rebind
+        {typedef typename __pointer_traits_rebind<pointer, _Up>::type other;};
+#endif // _LIBCPP_CXX03_LANG
+
+private:
+    struct __nat {};
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    static pointer pointer_to(typename conditional<is_void<element_type>::value,
+                                           __nat, element_type>::type& __r)
+        {return pointer::pointer_to(__r);}
+};
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS pointer_traits<_Tp*>
+{
+    typedef _Tp*      pointer;
+    typedef _Tp       element_type;
+    typedef ptrdiff_t difference_type;
+
+#ifndef _LIBCPP_CXX03_LANG
+    template <class _Up> using rebind = _Up*;
+#else
+    template <class _Up> struct rebind {typedef _Up* other;};
+#endif
+
+private:
+    struct __nat {};
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static pointer pointer_to(typename conditional<is_void<element_type>::value,
+                                      __nat, element_type>::type& __r) _NOEXCEPT
+        {return _VSTD::addressof(__r);}
+};
+
+template <class _From, class _To>
+struct __rebind_pointer {
+#ifndef _LIBCPP_CXX03_LANG
+    typedef typename pointer_traits<_From>::template rebind<_To>        type;
+#else
+    typedef typename pointer_traits<_From>::template rebind<_To>::other type;
+#endif
+};
+
+// to_address
+
+template <class _Pointer, class = void>
+struct __to_address_helper;
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+_Tp* __to_address(_Tp* __p) _NOEXCEPT {
+    static_assert(!is_function<_Tp>::value, "_Tp is a function type");
+    return __p;
+}
+
+// enable_if is needed here to avoid instantiating checks for fancy pointers on raw pointers
+template <class _Pointer, class = _EnableIf<!is_pointer<_Pointer>::value> >
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+typename decay<decltype(__to_address_helper<_Pointer>::__call(declval<const _Pointer&>()))>::type
+__to_address(const _Pointer& __p) _NOEXCEPT {
+    return __to_address_helper<_Pointer>::__call(__p);
+}
+
+template <class _Pointer, class>
+struct __to_address_helper {
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    static decltype(_VSTD::__to_address(declval<const _Pointer&>().operator->()))
+    __call(const _Pointer&__p) _NOEXCEPT {
+        return _VSTD::__to_address(__p.operator->());
+    }
+};
+
+template <class _Pointer>
+struct __to_address_helper<_Pointer, decltype((void)pointer_traits<_Pointer>::to_address(declval<const _Pointer&>()))> {
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    static decltype(pointer_traits<_Pointer>::to_address(declval<const _Pointer&>()))
+    __call(const _Pointer&__p) _NOEXCEPT {
+        return pointer_traits<_Pointer>::to_address(__p);
+    }
+};
+
+#if _LIBCPP_STD_VER > 17
+template <class _Pointer>
+inline _LIBCPP_INLINE_VISIBILITY constexpr
+auto to_address(const _Pointer& __p) noexcept {
+    return _VSTD::__to_address(__p);
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_POINTER_TRAITS_H
diff --git a/include/__memory/raw_storage_iterator.h b/include/__memory/raw_storage_iterator.h
new file mode 100644
index 0000000..e8f82b2
--- /dev/null
+++ b/include/__memory/raw_storage_iterator.h
@@ -0,0 +1,73 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_RAW_STORAGE_ITERATOR_H
+#define _LIBCPP___MEMORY_RAW_STORAGE_ITERATOR_H
+
+#include <__config>
+#include <__memory/addressof.h>
+#include <cstddef>
+#include <iterator>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR)
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _OutputIterator, class _Tp>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 raw_storage_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
+    : public iterator<output_iterator_tag, void, void, void, void>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+private:
+    _OutputIterator __x_;
+public:
+    typedef output_iterator_tag iterator_category;
+    typedef void                value_type;
+#if _LIBCPP_STD_VER > 17
+    typedef ptrdiff_t           difference_type;
+#else
+    typedef void                difference_type;
+#endif
+    typedef void                pointer;
+    typedef void                reference;
+
+    _LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {}
+    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;}
+    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element)
+        {::new ((void*)_VSTD::addressof(*__x_)) _Tp(__element); return *this;}
+#if _LIBCPP_STD_VER >= 14
+    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(_Tp&& __element)
+        {::new ((void*)_VSTD::addressof(*__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;}
+#if _LIBCPP_STD_VER >= 14
+    _LIBCPP_INLINE_VISIBILITY _OutputIterator base() const { return __x_; }
+#endif
+};
+
+#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_RAW_STORAGE_ITERATOR_H
diff --git a/include/__memory/shared_ptr.h b/include/__memory/shared_ptr.h
new file mode 100644
index 0000000..04161c4
--- /dev/null
+++ b/include/__memory/shared_ptr.h
@@ -0,0 +1,1879 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_SHARED_PTR_H
+#define _LIBCPP___MEMORY_SHARED_PTR_H
+
+#include <__availability>
+#include <__config>
+#include <__functional_base>
+#include <__functional/binary_function.h>
+#include <__functional/operations.h>
+#include <__functional/reference_wrapper.h>
+#include <__memory/addressof.h>
+#include <__memory/allocation_guard.h>
+#include <__memory/allocator_traits.h>
+#include <__memory/allocator.h>
+#include <__memory/compressed_pair.h>
+#include <__memory/pointer_traits.h>
+#include <__memory/unique_ptr.h>
+#include <__utility/forward.h>
+#include <cstddef>
+#include <cstdlib> // abort
+#include <iosfwd>
+#include <stdexcept>
+#include <typeinfo>
+#include <type_traits>
+#include <utility>
+#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
+#  include <atomic>
+#endif
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
+#   include <__memory/auto_ptr.h>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Alloc>
+class __allocator_destructor
+{
+    typedef _LIBCPP_NODEBUG_TYPE allocator_traits<_Alloc> __alloc_traits;
+public:
+    typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::pointer pointer;
+    typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::size_type size_type;
+private:
+    _Alloc& __alloc_;
+    size_type __s_;
+public:
+    _LIBCPP_INLINE_VISIBILITY __allocator_destructor(_Alloc& __a, size_type __s)
+             _NOEXCEPT
+        : __alloc_(__a), __s_(__s) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void operator()(pointer __p) _NOEXCEPT
+        {__alloc_traits::deallocate(__alloc_, __p, __s_);}
+};
+
+// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
+// should be sufficient for thread safety.
+// See https://llvm.org/PR22803
+#if defined(__clang__) && __has_builtin(__atomic_add_fetch)          \
+                       && defined(__ATOMIC_RELAXED)                  \
+                       && defined(__ATOMIC_ACQ_REL)
+#   define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
+#elif defined(_LIBCPP_COMPILER_GCC)
+#   define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
+#endif
+
+template <class _ValueType>
+inline _LIBCPP_INLINE_VISIBILITY
+_ValueType __libcpp_relaxed_load(_ValueType const* __value) {
+#if !defined(_LIBCPP_HAS_NO_THREADS) && \
+    defined(__ATOMIC_RELAXED) &&        \
+    (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
+    return __atomic_load_n(__value, __ATOMIC_RELAXED);
+#else
+    return *__value;
+#endif
+}
+
+template <class _ValueType>
+inline _LIBCPP_INLINE_VISIBILITY
+_ValueType __libcpp_acquire_load(_ValueType const* __value) {
+#if !defined(_LIBCPP_HAS_NO_THREADS) && \
+    defined(__ATOMIC_ACQUIRE) &&        \
+    (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
+    return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
+#else
+    return *__value;
+#endif
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _Tp
+__libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT
+{
+#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
+    return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);
+#else
+    return __t += 1;
+#endif
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _Tp
+__libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT
+{
+#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
+    return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);
+#else
+    return __t -= 1;
+#endif
+}
+
+class _LIBCPP_EXCEPTION_ABI bad_weak_ptr
+    : public std::exception
+{
+public:
+    bad_weak_ptr() _NOEXCEPT = default;
+    bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
+    virtual ~bad_weak_ptr() _NOEXCEPT;
+    virtual const char* what() const  _NOEXCEPT;
+};
+
+_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
+void __throw_bad_weak_ptr()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    throw bad_weak_ptr();
+#else
+    _VSTD::abort();
+#endif
+}
+
+template<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr;
+
+class _LIBCPP_TYPE_VIS __shared_count
+{
+    __shared_count(const __shared_count&);
+    __shared_count& operator=(const __shared_count&);
+
+protected:
+    long __shared_owners_;
+    virtual ~__shared_count();
+private:
+    virtual void __on_zero_shared() _NOEXCEPT = 0;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __shared_count(long __refs = 0) _NOEXCEPT
+        : __shared_owners_(__refs) {}
+
+#if defined(_LIBCPP_BUILDING_LIBRARY) && \
+    defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
+    void __add_shared() _NOEXCEPT;
+    bool __release_shared() _NOEXCEPT;
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    void __add_shared() _NOEXCEPT {
+      __libcpp_atomic_refcount_increment(__shared_owners_);
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    bool __release_shared() _NOEXCEPT {
+      if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
+        __on_zero_shared();
+        return true;
+      }
+      return false;
+    }
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    long use_count() const _NOEXCEPT {
+        return __libcpp_relaxed_load(&__shared_owners_) + 1;
+    }
+};
+
+class _LIBCPP_TYPE_VIS __shared_weak_count
+    : private __shared_count
+{
+    long __shared_weak_owners_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
+        : __shared_count(__refs),
+          __shared_weak_owners_(__refs) {}
+protected:
+    virtual ~__shared_weak_count();
+
+public:
+#if defined(_LIBCPP_BUILDING_LIBRARY) && \
+    defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
+    void __add_shared() _NOEXCEPT;
+    void __add_weak() _NOEXCEPT;
+    void __release_shared() _NOEXCEPT;
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    void __add_shared() _NOEXCEPT {
+      __shared_count::__add_shared();
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    void __add_weak() _NOEXCEPT {
+      __libcpp_atomic_refcount_increment(__shared_weak_owners_);
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    void __release_shared() _NOEXCEPT {
+      if (__shared_count::__release_shared())
+        __release_weak();
+    }
+#endif
+    void __release_weak() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    long use_count() const _NOEXCEPT {return __shared_count::use_count();}
+    __shared_weak_count* lock() _NOEXCEPT;
+
+    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
+private:
+    virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
+};
+
+template <class _Tp, class _Dp, class _Alloc>
+class __shared_ptr_pointer
+    : public __shared_weak_count
+{
+    __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
+        :  __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
+
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
+#endif
+
+private:
+    virtual void __on_zero_shared() _NOEXCEPT;
+    virtual void __on_zero_shared_weak() _NOEXCEPT;
+};
+
+#ifndef _LIBCPP_NO_RTTI
+
+template <class _Tp, class _Dp, class _Alloc>
+const void*
+__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT
+{
+    return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr;
+}
+
+#endif // _LIBCPP_NO_RTTI
+
+template <class _Tp, class _Dp, class _Alloc>
+void
+__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT
+{
+    __data_.first().second()(__data_.first().first());
+    __data_.first().second().~_Dp();
+}
+
+template <class _Tp, class _Dp, class _Alloc>
+void
+__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
+{
+    typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al;
+    typedef allocator_traits<_Al> _ATraits;
+    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
+
+    _Al __a(__data_.second());
+    __data_.second().~_Alloc();
+    __a.deallocate(_PTraits::pointer_to(*this), 1);
+}
+
+template <class _Tp, class _Alloc>
+struct __shared_ptr_emplace
+    : __shared_weak_count
+{
+    template<class ..._Args>
+    _LIBCPP_HIDE_FROM_ABI
+    explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
+        : __storage_(_VSTD::move(__a))
+    {
+#if _LIBCPP_STD_VER > 17
+        using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
+        _TpAlloc __tmp(*__get_alloc());
+        allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...);
+#else
+        ::new ((void*)__get_elem()) _Tp(_VSTD::forward<_Args>(__args)...);
+#endif
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); }
+
+    _LIBCPP_HIDE_FROM_ABI
+    _Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
+
+private:
+    virtual void __on_zero_shared() _NOEXCEPT {
+#if _LIBCPP_STD_VER > 17
+        using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
+        _TpAlloc __tmp(*__get_alloc());
+        allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
+#else
+        __get_elem()->~_Tp();
+#endif
+    }
+
+    virtual void __on_zero_shared_weak() _NOEXCEPT {
+        using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;
+        using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;
+        _ControlBlockAlloc __tmp(*__get_alloc());
+        __storage_.~_Storage();
+        allocator_traits<_ControlBlockAlloc>::deallocate(__tmp,
+            pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1);
+    }
+
+    // This class implements the control block for non-array shared pointers created
+    // through `std::allocate_shared` and `std::make_shared`.
+    //
+    // In previous versions of the library, we used a compressed pair to store
+    // both the _Alloc and the _Tp. This implies using EBO, which is incompatible
+    // with Allocator construction for _Tp. To allow implementing P0674 in C++20,
+    // we now use a properly aligned char buffer while making sure that we maintain
+    // the same layout that we had when we used a compressed pair.
+    using _CompressedPair = __compressed_pair<_Alloc, _Tp>;
+    struct _ALIGNAS_TYPE(_CompressedPair) _Storage {
+        char __blob_[sizeof(_CompressedPair)];
+
+        _LIBCPP_HIDE_FROM_ABI explicit _Storage(_Alloc&& __a) {
+            ::new ((void*)__get_alloc()) _Alloc(_VSTD::move(__a));
+        }
+        _LIBCPP_HIDE_FROM_ABI ~_Storage() {
+            __get_alloc()->~_Alloc();
+        }
+        _Alloc* __get_alloc() _NOEXCEPT {
+            _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
+            typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair);
+            _Alloc *__alloc = reinterpret_cast<_Alloc*>(__first);
+            return __alloc;
+        }
+        _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT {
+            _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
+            typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair);
+            _Tp *__elem = reinterpret_cast<_Tp*>(__second);
+            return __elem;
+        }
+    };
+
+    static_assert(_LIBCPP_ALIGNOF(_Storage) == _LIBCPP_ALIGNOF(_CompressedPair), "");
+    static_assert(sizeof(_Storage) == sizeof(_CompressedPair), "");
+    _Storage __storage_;
+};
+
+struct __shared_ptr_dummy_rebind_allocator_type;
+template <>
+class _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type>
+{
+public:
+    template <class _Other>
+    struct rebind
+    {
+        typedef allocator<_Other> other;
+    };
+};
+
+template<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
+
+template<class _Tp, class _Up>
+struct __compatible_with
+#if _LIBCPP_STD_VER > 14
+    : is_convertible<remove_extent_t<_Tp>*, remove_extent_t<_Up>*> {};
+#else
+    : is_convertible<_Tp*, _Up*> {};
+#endif // _LIBCPP_STD_VER > 14
+
+template <class _Ptr, class = void>
+struct __is_deletable : false_type { };
+template <class _Ptr>
+struct __is_deletable<_Ptr, decltype(delete declval<_Ptr>())> : true_type { };
+
+template <class _Ptr, class = void>
+struct __is_array_deletable : false_type { };
+template <class _Ptr>
+struct __is_array_deletable<_Ptr, decltype(delete[] declval<_Ptr>())> : true_type { };
+
+template <class _Dp, class _Pt,
+    class = decltype(declval<_Dp>()(declval<_Pt>()))>
+static true_type __well_formed_deleter_test(int);
+
+template <class, class>
+static false_type __well_formed_deleter_test(...);
+
+template <class _Dp, class _Pt>
+struct __well_formed_deleter : decltype(__well_formed_deleter_test<_Dp, _Pt>(0)) {};
+
+template<class _Dp, class _Tp, class _Yp>
+struct __shared_ptr_deleter_ctor_reqs
+{
+    static const bool value = __compatible_with<_Tp, _Yp>::value &&
+                              is_move_constructible<_Dp>::value &&
+                              __well_formed_deleter<_Dp, _Tp*>::value;
+};
+
+#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
+#  define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
+#else
+#  define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
+#endif
+
+template<class _Tp>
+class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
+{
+public:
+#if _LIBCPP_STD_VER > 14
+    typedef weak_ptr<_Tp> weak_type;
+    typedef remove_extent_t<_Tp> element_type;
+#else
+    typedef _Tp element_type;
+#endif
+
+private:
+    element_type*      __ptr_;
+    __shared_weak_count* __cntrl_;
+
+    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, class = _EnableIf<
+        _And<
+            __compatible_with<_Yp, _Tp>
+            // In C++03 we get errors when trying to do SFINAE with the
+            // delete operator, so we always pretend that it's deletable.
+            // The same happens on GCC.
+#if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC)
+            , _If<is_array<_Tp>::value, __is_array_deletable<_Yp*>, __is_deletable<_Yp*> >
+#endif
+        >::value
+    > >
+    explicit shared_ptr(_Yp* __p) : __ptr_(__p) {
+        unique_ptr<_Yp> __hold(__p);
+        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
+        typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk;
+        __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());
+        __hold.release();
+        __enable_weak_this(__p, __p);
+    }
+
+    template<class _Yp, class _Dp>
+        shared_ptr(_Yp* __p, _Dp __d,
+                   typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat());
+    template<class _Yp, class _Dp, class _Alloc>
+        shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
+                   typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _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> _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<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
+                       _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    shared_ptr(shared_ptr&& __r) _NOEXCEPT;
+    template<class _Yp> _LIBCPP_INLINE_VISIBILITY  shared_ptr(shared_ptr<_Yp>&& __r,
+                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
+                       _NOEXCEPT;
+    template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
+                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type= __nat());
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
+    template<class _Yp>
+        shared_ptr(auto_ptr<_Yp>&& __r,
+                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
+#endif
+    template <class _Yp, class _Dp>
+        shared_ptr(unique_ptr<_Yp, _Dp>&&,
+                   typename enable_if
+                   <
+                       !is_lvalue_reference<_Dp>::value &&
+                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
+                       __nat
+                   >::type = __nat());
+    template <class _Yp, class _Dp>
+        shared_ptr(unique_ptr<_Yp, _Dp>&&,
+                   typename enable_if
+                   <
+                       is_lvalue_reference<_Dp>::value &&
+                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
+                       __nat
+                   >::type = __nat());
+
+    ~shared_ptr();
+
+    _LIBCPP_INLINE_VISIBILITY
+    shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT;
+    template<class _Yp>
+        typename enable_if
+        <
+            __compatible_with<_Yp, element_type>::value,
+            shared_ptr&
+        >::type
+        _LIBCPP_INLINE_VISIBILITY
+        operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT;
+    template<class _Yp>
+        typename enable_if
+        <
+            __compatible_with<_Yp, element_type>::value,
+            shared_ptr&
+        >::type
+        _LIBCPP_INLINE_VISIBILITY
+        operator=(shared_ptr<_Yp>&& __r);
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
+    template<class _Yp>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            !is_array<_Yp>::value &&
+            is_convertible<_Yp*, element_type*>::value,
+            shared_ptr
+        >::type&
+        operator=(auto_ptr<_Yp>&& __r);
+#endif
+    template <class _Yp, class _Dp>
+        typename enable_if
+        <
+            is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
+            shared_ptr&
+        >::type
+        _LIBCPP_INLINE_VISIBILITY
+        operator=(unique_ptr<_Yp, _Dp>&& __r);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(shared_ptr& __r) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() _NOEXCEPT;
+    template<class _Yp>
+        typename enable_if
+        <
+            __compatible_with<_Yp, element_type>::value,
+            void
+        >::type
+        _LIBCPP_INLINE_VISIBILITY
+        reset(_Yp* __p);
+    template<class _Yp, class _Dp>
+        typename enable_if
+        <
+            __compatible_with<_Yp, element_type>::value,
+            void
+        >::type
+        _LIBCPP_INLINE_VISIBILITY
+        reset(_Yp* __p, _Dp __d);
+    template<class _Yp, class _Dp, class _Alloc>
+        typename enable_if
+        <
+            __compatible_with<_Yp, element_type>::value,
+            void
+        >::type
+        _LIBCPP_INLINE_VISIBILITY
+        reset(_Yp* __p, _Dp __d, _Alloc __a);
+
+    _LIBCPP_INLINE_VISIBILITY
+    element_type* get() const _NOEXCEPT {return __ptr_;}
+    _LIBCPP_INLINE_VISIBILITY
+    typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT
+        {return *__ptr_;}
+    _LIBCPP_INLINE_VISIBILITY
+    element_type* operator->() const _NOEXCEPT
+    {
+        static_assert(!is_array<_Tp>::value,
+                      "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
+        return __ptr_;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool unique() const _NOEXCEPT {return use_count() == 1;}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit operator bool() const _NOEXCEPT {return get() != nullptr;}
+    template <class _Up>
+        _LIBCPP_INLINE_VISIBILITY
+        bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT
+        {return __cntrl_ < __p.__cntrl_;}
+    template <class _Up>
+        _LIBCPP_INLINE_VISIBILITY
+        bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT
+        {return __cntrl_ < __p.__cntrl_;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool
+    __owner_equivalent(const shared_ptr& __p) const
+        {return __cntrl_ == __p.__cntrl_;}
+
+#if _LIBCPP_STD_VER > 14
+    typename add_lvalue_reference<element_type>::type
+    _LIBCPP_INLINE_VISIBILITY
+    operator[](ptrdiff_t __i) const
+    {
+            static_assert(is_array<_Tp>::value,
+                          "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
+            return __ptr_[__i];
+    }
+#endif
+
+#ifndef _LIBCPP_NO_RTTI
+    template <class _Dp>
+        _LIBCPP_INLINE_VISIBILITY
+        _Dp* __get_deleter() const _NOEXCEPT
+            {return static_cast<_Dp*>(__cntrl_
+                    ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
+                      : nullptr);}
+#endif // _LIBCPP_NO_RTTI
+
+    template<class _Yp, class _CntrlBlk>
+    static shared_ptr<_Tp>
+    __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT
+    {
+        shared_ptr<_Tp> __r;
+        __r.__ptr_ = __p;
+        __r.__cntrl_ = __cntrl;
+        __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
+        return __r;
+    }
+
+private:
+    template <class _Yp, bool = is_function<_Yp>::value>
+        struct __shared_ptr_default_allocator
+        {
+            typedef allocator<_Yp> type;
+        };
+
+    template <class _Yp>
+        struct __shared_ptr_default_allocator<_Yp, true>
+        {
+            typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
+        };
+
+    template <class _Yp, class _OrigPtr>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if<is_convertible<_OrigPtr*,
+                                          const enable_shared_from_this<_Yp>*
+        >::value,
+            void>::type
+        __enable_weak_this(const enable_shared_from_this<_Yp>* __e,
+                           _OrigPtr* __ptr) _NOEXCEPT
+        {
+            typedef typename remove_cv<_Yp>::type _RawYp;
+            if (__e && __e->__weak_this_.expired())
+            {
+                __e->__weak_this_ = shared_ptr<_RawYp>(*this,
+                    const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
+            }
+        }
+
+    _LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {}
+
+    template <class, class _Yp>
+        struct __shared_ptr_default_delete
+            : default_delete<_Yp> {};
+
+    template <class _Yp, class _Un, size_t _Sz>
+        struct __shared_ptr_default_delete<_Yp[_Sz], _Un>
+            : default_delete<_Yp[]> {};
+
+    template <class _Yp, class _Un>
+        struct __shared_ptr_default_delete<_Yp[], _Un>
+            : default_delete<_Yp[]> {};
+
+    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
+    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
+};
+
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+template<class _Tp>
+shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
+template<class _Tp, class _Dp>
+shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
+#endif
+
+template<class _Tp>
+inline
+_LIBCPP_CONSTEXPR
+shared_ptr<_Tp>::shared_ptr() _NOEXCEPT
+    : __ptr_(nullptr),
+      __cntrl_(nullptr)
+{
+}
+
+template<class _Tp>
+inline
+_LIBCPP_CONSTEXPR
+shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT
+    : __ptr_(nullptr),
+      __cntrl_(nullptr)
+{
+}
+
+template<class _Tp>
+template<class _Yp, class _Dp>
+shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,
+                            typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type)
+    : __ptr_(__p)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif // _LIBCPP_NO_EXCEPTIONS
+        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
+        typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
+#ifndef _LIBCPP_CXX03_LANG
+        __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
+#else
+        __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
+#endif // not _LIBCPP_CXX03_LANG
+        __enable_weak_this(__p, __p);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __d(__p);
+        throw;
+    }
+#endif // _LIBCPP_NO_EXCEPTIONS
+}
+
+template<class _Tp>
+template<class _Dp>
+shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)
+    : __ptr_(nullptr)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif // _LIBCPP_NO_EXCEPTIONS
+        typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
+        typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk;
+#ifndef _LIBCPP_CXX03_LANG
+        __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
+#else
+        __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
+#endif // not _LIBCPP_CXX03_LANG
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __d(__p);
+        throw;
+    }
+#endif // _LIBCPP_NO_EXCEPTIONS
+}
+
+template<class _Tp>
+template<class _Yp, class _Dp, class _Alloc>
+shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
+                            typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type)
+    : __ptr_(__p)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif // _LIBCPP_NO_EXCEPTIONS
+        typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
+        typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
+        typedef __allocator_destructor<_A2> _D2;
+        _A2 __a2(__a);
+        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
+        ::new ((void*)_VSTD::addressof(*__hold2.get()))
+#ifndef _LIBCPP_CXX03_LANG
+            _CntrlBlk(__p, _VSTD::move(__d), __a);
+#else
+            _CntrlBlk(__p, __d, __a);
+#endif // not _LIBCPP_CXX03_LANG
+        __cntrl_ = _VSTD::addressof(*__hold2.release());
+        __enable_weak_this(__p, __p);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __d(__p);
+        throw;
+    }
+#endif // _LIBCPP_NO_EXCEPTIONS
+}
+
+template<class _Tp>
+template<class _Dp, class _Alloc>
+shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
+    : __ptr_(nullptr)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif // _LIBCPP_NO_EXCEPTIONS
+        typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
+        typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
+        typedef __allocator_destructor<_A2> _D2;
+        _A2 __a2(__a);
+        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
+        ::new ((void*)_VSTD::addressof(*__hold2.get()))
+#ifndef _LIBCPP_CXX03_LANG
+            _CntrlBlk(__p, _VSTD::move(__d), __a);
+#else
+            _CntrlBlk(__p, __d, __a);
+#endif // not _LIBCPP_CXX03_LANG
+        __cntrl_ = _VSTD::addressof(*__hold2.release());
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __d(__p);
+        throw;
+    }
+#endif // _LIBCPP_NO_EXCEPTIONS
+}
+
+template<class _Tp>
+template<class _Yp>
+inline
+shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT
+    : __ptr_(__p),
+      __cntrl_(__r.__cntrl_)
+{
+    if (__cntrl_)
+        __cntrl_->__add_shared();
+}
+
+template<class _Tp>
+inline
+shared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    if (__cntrl_)
+        __cntrl_->__add_shared();
+}
+
+template<class _Tp>
+template<class _Yp>
+inline
+shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,
+                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
+         _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    if (__cntrl_)
+        __cntrl_->__add_shared();
+}
+
+template<class _Tp>
+inline
+shared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    __r.__ptr_ = nullptr;
+    __r.__cntrl_ = nullptr;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline
+shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,
+                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
+         _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    __r.__ptr_ = nullptr;
+    __r.__cntrl_ = nullptr;
+}
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
+template<class _Tp>
+template<class _Yp>
+shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r,
+                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
+    : __ptr_(__r.get())
+{
+    typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;
+    __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>());
+    __enable_weak_this(__r.get(), __r.get());
+    __r.release();
+}
+#endif
+
+template<class _Tp>
+template <class _Yp, class _Dp>
+shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
+                            typename enable_if
+                            <
+                                !is_lvalue_reference<_Dp>::value &&
+                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
+                                __nat
+                            >::type)
+    : __ptr_(__r.get())
+{
+#if _LIBCPP_STD_VER > 11
+    if (__ptr_ == nullptr)
+        __cntrl_ = nullptr;
+    else
+#endif
+    {
+        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
+        typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT > _CntrlBlk;
+        __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT());
+        __enable_weak_this(__r.get(), __r.get());
+    }
+    __r.release();
+}
+
+template<class _Tp>
+template <class _Yp, class _Dp>
+shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
+                            typename enable_if
+                            <
+                                is_lvalue_reference<_Dp>::value &&
+                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
+                                __nat
+                            >::type)
+    : __ptr_(__r.get())
+{
+#if _LIBCPP_STD_VER > 11
+    if (__ptr_ == nullptr)
+        __cntrl_ = nullptr;
+    else
+#endif
+    {
+        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
+        typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer,
+                                     reference_wrapper<typename remove_reference<_Dp>::type>,
+                                     _AllocT > _CntrlBlk;
+        __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT());
+        __enable_weak_this(__r.get(), __r.get());
+    }
+    __r.release();
+}
+
+template<class _Tp>
+shared_ptr<_Tp>::~shared_ptr()
+{
+    if (__cntrl_)
+        __cntrl_->__release_shared();
+}
+
+template<class _Tp>
+inline
+shared_ptr<_Tp>&
+shared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT
+{
+    shared_ptr(__r).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline
+typename enable_if
+<
+    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
+    shared_ptr<_Tp>&
+>::type
+shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
+{
+    shared_ptr(__r).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+inline
+shared_ptr<_Tp>&
+shared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT
+{
+    shared_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline
+typename enable_if
+<
+    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
+    shared_ptr<_Tp>&
+>::type
+shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)
+{
+    shared_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
+template<class _Tp>
+template<class _Yp>
+inline
+typename enable_if
+<
+    !is_array<_Yp>::value &&
+    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
+    shared_ptr<_Tp>
+>::type&
+shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)
+{
+    shared_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+#endif
+
+template<class _Tp>
+template <class _Yp, class _Dp>
+inline
+typename enable_if
+<
+    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer,
+                   typename shared_ptr<_Tp>::element_type*>::value,
+    shared_ptr<_Tp>&
+>::type
+shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r)
+{
+    shared_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+inline
+void
+shared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT
+{
+    _VSTD::swap(__ptr_, __r.__ptr_);
+    _VSTD::swap(__cntrl_, __r.__cntrl_);
+}
+
+template<class _Tp>
+inline
+void
+shared_ptr<_Tp>::reset() _NOEXCEPT
+{
+    shared_ptr().swap(*this);
+}
+
+template<class _Tp>
+template<class _Yp>
+inline
+typename enable_if
+<
+    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
+    void
+>::type
+shared_ptr<_Tp>::reset(_Yp* __p)
+{
+    shared_ptr(__p).swap(*this);
+}
+
+template<class _Tp>
+template<class _Yp, class _Dp>
+inline
+typename enable_if
+<
+    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
+    void
+>::type
+shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
+{
+    shared_ptr(__p, __d).swap(*this);
+}
+
+template<class _Tp>
+template<class _Yp, class _Dp, class _Alloc>
+inline
+typename enable_if
+<
+    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
+    void
+>::type
+shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
+{
+    shared_ptr(__p, __d, __a).swap(*this);
+}
+
+//
+// std::allocate_shared and std::make_shared
+//
+template<class _Tp, class _Alloc, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&& ...__args)
+{
+    using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
+    using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
+    __allocation_guard<_ControlBlockAllocator> __guard(__a, 1);
+    ::new ((void*)_VSTD::addressof(*__guard.__get())) _ControlBlock(__a, _VSTD::forward<_Args>(__args)...);
+    auto __control_block = __guard.__release_ptr();
+    return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTD::addressof(*__control_block));
+}
+
+template<class _Tp, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> make_shared(_Args&& ...__args)
+{
+    return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...);
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    return __x.get() == __y.get();
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    return !(__x == __y);
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+#if _LIBCPP_STD_VER <= 11
+    typedef typename common_type<_Tp*, _Up*>::type _Vp;
+    return less<_Vp>()(__x.get(), __y.get());
+#else
+    return less<>()(__x.get(), __y.get());
+#endif
+
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    return __y < __x;
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    return !(__y < __x);
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    return !(__x < __y);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return !__x;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return !__x;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return static_cast<bool>(__x);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return static_cast<bool>(__x);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return less<_Tp*>()(__x.get(), nullptr);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return less<_Tp*>()(nullptr, __x.get());
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return nullptr < __x;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return __x < nullptr;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return !(nullptr < __x);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return !(__x < nullptr);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return !(__x < nullptr);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return !(nullptr < __x);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT
+{
+    __x.swap(__y);
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>
+static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
+{
+    return shared_ptr<_Tp>(__r,
+                           static_cast<
+                               typename shared_ptr<_Tp>::element_type*>(__r.get()));
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>
+dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
+{
+    typedef typename shared_ptr<_Tp>::element_type _ET;
+    _ET* __p = dynamic_cast<_ET*>(__r.get());
+    return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
+}
+
+template<class _Tp, class _Up>
+shared_ptr<_Tp>
+const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
+{
+    typedef typename shared_ptr<_Tp>::element_type _RTp;
+    return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
+}
+
+template<class _Tp, class _Up>
+shared_ptr<_Tp>
+reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
+{
+    return shared_ptr<_Tp>(__r,
+                           reinterpret_cast<
+                               typename shared_ptr<_Tp>::element_type*>(__r.get()));
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Dp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Dp*
+get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
+{
+    return __p.template __get_deleter<_Dp>();
+}
+
+#endif // _LIBCPP_NO_RTTI
+
+template<class _Tp>
+class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
+{
+public:
+    typedef _Tp element_type;
+private:
+    element_type*        __ptr_;
+    __shared_weak_count* __cntrl_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT;
+    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> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r,
+                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
+                         _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    weak_ptr(weak_ptr&& __r) _NOEXCEPT;
+    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r,
+                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
+                         _NOEXCEPT;
+    ~weak_ptr();
+
+    _LIBCPP_INLINE_VISIBILITY
+    weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            weak_ptr&
+        >::type
+        _LIBCPP_INLINE_VISIBILITY
+        operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            weak_ptr&
+        >::type
+        _LIBCPP_INLINE_VISIBILITY
+        operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;
+
+    template<class _Yp>
+        typename enable_if
+        <
+            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
+    long use_count() const _NOEXCEPT
+        {return __cntrl_ ? __cntrl_->use_count() : 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool expired() const _NOEXCEPT
+        {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;}
+    shared_ptr<_Tp> lock() const _NOEXCEPT;
+    template<class _Up>
+        _LIBCPP_INLINE_VISIBILITY
+        bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT
+        {return __cntrl_ < __r.__cntrl_;}
+    template<class _Up>
+        _LIBCPP_INLINE_VISIBILITY
+        bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT
+        {return __cntrl_ < __r.__cntrl_;}
+
+    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
+    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
+};
+
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+template<class _Tp>
+weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
+#endif
+
+template<class _Tp>
+inline
+_LIBCPP_CONSTEXPR
+weak_ptr<_Tp>::weak_ptr() _NOEXCEPT
+    : __ptr_(nullptr),
+      __cntrl_(nullptr)
+{
+}
+
+template<class _Tp>
+inline
+weak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    if (__cntrl_)
+        __cntrl_->__add_weak();
+}
+
+template<class _Tp>
+template<class _Yp>
+inline
+weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
+                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
+                         _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    if (__cntrl_)
+        __cntrl_->__add_weak();
+}
+
+template<class _Tp>
+template<class _Yp>
+inline
+weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
+                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
+         _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    if (__cntrl_)
+        __cntrl_->__add_weak();
+}
+
+template<class _Tp>
+inline
+weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    __r.__ptr_ = nullptr;
+    __r.__cntrl_ = nullptr;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline
+weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
+                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
+         _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    __r.__ptr_ = nullptr;
+    __r.__cntrl_ = nullptr;
+}
+
+template<class _Tp>
+weak_ptr<_Tp>::~weak_ptr()
+{
+    if (__cntrl_)
+        __cntrl_->__release_weak();
+}
+
+template<class _Tp>
+inline
+weak_ptr<_Tp>&
+weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT
+{
+    weak_ptr(__r).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    weak_ptr<_Tp>&
+>::type
+weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT
+{
+    weak_ptr(__r).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+inline
+weak_ptr<_Tp>&
+weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT
+{
+    weak_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    weak_ptr<_Tp>&
+>::type
+weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT
+{
+    weak_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    weak_ptr<_Tp>&
+>::type
+weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT
+{
+    weak_ptr(__r).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+inline
+void
+weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT
+{
+    _VSTD::swap(__ptr_, __r.__ptr_);
+    _VSTD::swap(__cntrl_, __r.__cntrl_);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT
+{
+    __x.swap(__y);
+}
+
+template<class _Tp>
+inline
+void
+weak_ptr<_Tp>::reset() _NOEXCEPT
+{
+    weak_ptr().swap(*this);
+}
+
+template<class _Tp>
+template<class _Yp>
+shared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r,
+                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
+{
+    if (__cntrl_ == nullptr)
+        __throw_bad_weak_ptr();
+}
+
+template<class _Tp>
+shared_ptr<_Tp>
+weak_ptr<_Tp>::lock() const _NOEXCEPT
+{
+    shared_ptr<_Tp> __r;
+    __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;
+    if (__r.__cntrl_)
+        __r.__ptr_ = __ptr_;
+    return __r;
+}
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp = void> struct owner_less;
+#else
+template <class _Tp> struct owner_less;
+#endif
+
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> >
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> second_argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
+        {return __x.owner_before(__y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
+        {return __x.owner_before(__y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
+        {return __x.owner_before(__y);}
+};
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> >
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
+#endif
+{
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> second_argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(  weak_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
+        {return __x.owner_before(__y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
+        {return __x.owner_before(__y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
+        {return __x.owner_before(__y);}
+};
+
+#if _LIBCPP_STD_VER > 14
+template <>
+struct _LIBCPP_TEMPLATE_VIS owner_less<void>
+{
+    template <class _Tp, class _Up>
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
+        {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 _NOEXCEPT
+        {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 _NOEXCEPT
+        {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 _NOEXCEPT
+        {return __x.owner_before(__y);}
+    typedef void is_transparent;
+};
+#endif
+
+template<class _Tp>
+class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
+{
+    mutable weak_ptr<_Tp> __weak_this_;
+protected:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    enable_shared_from_this() _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY
+    enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY
+    enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT
+        {return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    ~enable_shared_from_this() {}
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    shared_ptr<_Tp> shared_from_this()
+        {return shared_ptr<_Tp>(__weak_this_);}
+    _LIBCPP_INLINE_VISIBILITY
+    shared_ptr<_Tp const> shared_from_this() const
+        {return shared_ptr<const _Tp>(__weak_this_);}
+
+#if _LIBCPP_STD_VER > 14
+    _LIBCPP_INLINE_VISIBILITY
+    weak_ptr<_Tp> weak_from_this() _NOEXCEPT
+       { return __weak_this_; }
+
+    _LIBCPP_INLINE_VISIBILITY
+    weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
+        { return __weak_this_; }
+#endif // _LIBCPP_STD_VER > 14
+
+    template <class _Up> friend class shared_ptr;
+};
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> >
+{
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t          result_type;
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT
+    {
+        return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
+    }
+};
+
+template<class _CharT, class _Traits, class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
+
+
+#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
+
+class _LIBCPP_TYPE_VIS __sp_mut
+{
+    void* __lx;
+public:
+    void lock() _NOEXCEPT;
+    void unlock() _NOEXCEPT;
+
+private:
+    _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT;
+    __sp_mut(const __sp_mut&);
+    __sp_mut& operator=(const __sp_mut&);
+
+    friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
+};
+
+_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+__sp_mut& __get_sp_mut(const void*);
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_is_lock_free(const shared_ptr<_Tp>*)
+{
+    return false;
+}
+
+template <class _Tp>
+_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+shared_ptr<_Tp>
+atomic_load(const shared_ptr<_Tp>* __p)
+{
+    __sp_mut& __m = __get_sp_mut(__p);
+    __m.lock();
+    shared_ptr<_Tp> __q = *__p;
+    __m.unlock();
+    return __q;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+shared_ptr<_Tp>
+atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
+{
+    return atomic_load(__p);
+}
+
+template <class _Tp>
+_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+void
+atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
+{
+    __sp_mut& __m = __get_sp_mut(__p);
+    __m.lock();
+    __p->swap(__r);
+    __m.unlock();
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+void
+atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
+{
+    atomic_store(__p, __r);
+}
+
+template <class _Tp>
+_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+shared_ptr<_Tp>
+atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
+{
+    __sp_mut& __m = __get_sp_mut(__p);
+    __m.lock();
+    __p->swap(__r);
+    __m.unlock();
+    return __r;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+shared_ptr<_Tp>
+atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
+{
+    return atomic_exchange(__p, __r);
+}
+
+template <class _Tp>
+_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+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;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+bool
+atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
+{
+    return atomic_compare_exchange_strong(__p, __v, __w);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+bool
+atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
+                                        shared_ptr<_Tp> __w, memory_order, memory_order)
+{
+    return atomic_compare_exchange_strong(__p, __v, __w);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+bool
+atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
+                                      shared_ptr<_Tp> __w, memory_order, memory_order)
+{
+    return atomic_compare_exchange_weak(__p, __v, __w);
+}
+
+#endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_SHARED_PTR_H
diff --git a/include/__memory/temporary_buffer.h b/include/__memory/temporary_buffer.h
new file mode 100644
index 0000000..6d1884f
--- /dev/null
+++ b/include/__memory/temporary_buffer.h
@@ -0,0 +1,89 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
+#define _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
+
+#include <__config>
+#include <cstddef>
+#include <new>
+#include <utility> // pair
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+_LIBCPP_NODISCARD_EXT _LIBCPP_NO_CFI
+pair<_Tp*, ptrdiff_t>
+get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
+{
+    pair<_Tp*, ptrdiff_t> __r(0, 0);
+    const ptrdiff_t __m = (~ptrdiff_t(0) ^
+                           ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1)))
+                           / sizeof(_Tp);
+    if (__n > __m)
+        __n = __m;
+    while (__n > 0)
+    {
+#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
+    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
+        {
+            align_val_t __al =
+                align_val_t(alignment_of<_Tp>::value);
+            __r.first = static_cast<_Tp*>(::operator new(
+                __n * sizeof(_Tp), __al, nothrow));
+        } else {
+            __r.first = static_cast<_Tp*>(::operator new(
+                __n * sizeof(_Tp), nothrow));
+        }
+#else
+    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
+        {
+            // Since aligned operator new is unavailable, return an empty
+            // buffer rather than one with invalid alignment.
+            return __r;
+        }
+
+        __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow));
+#endif
+
+        if (__r.first)
+        {
+            __r.second = __n;
+            break;
+        }
+        __n /= 2;
+    }
+    return __r;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void return_temporary_buffer(_Tp* __p) _NOEXCEPT
+{
+  _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
+}
+
+struct __return_temporary_buffer
+{
+    template <class _Tp>
+    _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) const {_VSTD::return_temporary_buffer(__p);}
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
diff --git a/include/__memory/uninitialized_algorithms.h b/include/__memory/uninitialized_algorithms.h
new file mode 100644
index 0000000..39edabb
--- /dev/null
+++ b/include/__memory/uninitialized_algorithms.h
@@ -0,0 +1,261 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H
+#define _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H
+
+#include <__config>
+#include <__memory/addressof.h>
+#include <__memory/construct_at.h>
+#include <iterator>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _ForwardIterator>
+_ForwardIterator
+uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    _ForwardIterator __s = __r;
+    try
+    {
+#endif
+        for (; __f != __l; ++__f, (void) ++__r)
+            ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        for (; __s != __r; ++__s)
+            __s->~value_type();
+        throw;
+    }
+#endif
+    return __r;
+}
+
+template <class _InputIterator, class _Size, class _ForwardIterator>
+_ForwardIterator
+uninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    _ForwardIterator __s = __r;
+    try
+    {
+#endif
+        for (; __n > 0; ++__f, (void) ++__r, (void) --__n)
+            ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        for (; __s != __r; ++__s)
+            __s->~value_type();
+        throw;
+    }
+#endif
+    return __r;
+}
+
+template <class _ForwardIterator, class _Tp>
+void
+uninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    _ForwardIterator __s = __f;
+    try
+    {
+#endif
+        for (; __f != __l; ++__f)
+            ::new ((void*)_VSTD::addressof(*__f)) value_type(__x);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        for (; __s != __f; ++__s)
+            __s->~value_type();
+        throw;
+    }
+#endif
+}
+
+template <class _ForwardIterator, class _Size, class _Tp>
+_ForwardIterator
+uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    _ForwardIterator __s = __f;
+    try
+    {
+#endif
+        for (; __n > 0; ++__f, (void) --__n)
+            ::new ((void*)_VSTD::addressof(*__f)) value_type(__x);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        for (; __s != __f; ++__s)
+            __s->~value_type();
+        throw;
+    }
+#endif
+    return __f;
+}
+
+#if _LIBCPP_STD_VER > 14
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+void destroy(_ForwardIterator __first, _ForwardIterator __last) {
+    for (; __first != __last; ++__first)
+        _VSTD::destroy_at(_VSTD::addressof(*__first));
+}
+
+template <class _ForwardIterator, class _Size>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
+    for (; __n > 0; (void)++__first, --__n)
+        _VSTD::destroy_at(_VSTD::addressof(*__first));
+    return __first;
+}
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) {
+    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
+    auto __idx = __first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try {
+#endif
+    for (; __idx != __last; ++__idx)
+        ::new ((void*)_VSTD::addressof(*__idx)) _Vt;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    } catch (...) {
+        _VSTD::destroy(__first, __idx);
+        throw;
+    }
+#endif
+}
+
+template <class _ForwardIterator, class _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
+    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
+    auto __idx = __first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try {
+#endif
+    for (; __n > 0; (void)++__idx, --__n)
+        ::new ((void*)_VSTD::addressof(*__idx)) _Vt;
+    return __idx;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    } catch (...) {
+        _VSTD::destroy(__first, __idx);
+        throw;
+    }
+#endif
+}
+
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) {
+    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
+    auto __idx = __first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try {
+#endif
+    for (; __idx != __last; ++__idx)
+        ::new ((void*)_VSTD::addressof(*__idx)) _Vt();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    } catch (...) {
+        _VSTD::destroy(__first, __idx);
+        throw;
+    }
+#endif
+}
+
+template <class _ForwardIterator, class _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
+    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
+    auto __idx = __first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try {
+#endif
+    for (; __n > 0; (void)++__idx, --__n)
+        ::new ((void*)_VSTD::addressof(*__idx)) _Vt();
+    return __idx;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    } catch (...) {
+        _VSTD::destroy(__first, __idx);
+        throw;
+    }
+#endif
+}
+
+
+template <class _InputIt, class _ForwardIt>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __first_res) {
+    using _Vt = typename iterator_traits<_ForwardIt>::value_type;
+    auto __idx = __first_res;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try {
+#endif
+    for (; __first != __last; (void)++__idx, ++__first)
+        ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first));
+    return __idx;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    } catch (...) {
+        _VSTD::destroy(__first_res, __idx);
+        throw;
+    }
+#endif
+}
+
+template <class _InputIt, class _Size, class _ForwardIt>
+inline _LIBCPP_INLINE_VISIBILITY
+pair<_InputIt, _ForwardIt>
+uninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __first_res) {
+    using _Vt = typename iterator_traits<_ForwardIt>::value_type;
+    auto __idx = __first_res;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try {
+#endif
+    for (; __n > 0; ++__idx, (void)++__first, --__n)
+        ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first));
+    return {__first, __idx};
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    } catch (...) {
+        _VSTD::destroy(__first_res, __idx);
+        throw;
+    }
+#endif
+}
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H
diff --git a/include/__memory/unique_ptr.h b/include/__memory/unique_ptr.h
new file mode 100644
index 0000000..083e0a8
--- /dev/null
+++ b/include/__memory/unique_ptr.h
@@ -0,0 +1,773 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_UNIQUE_PTR_H
+#define _LIBCPP___MEMORY_UNIQUE_PTR_H
+
+#include <__config>
+#include <__functional_base>
+#include <__functional/hash.h>
+#include <__functional/operations.h>
+#include <__memory/allocator_traits.h> // __pointer
+#include <__memory/compressed_pair.h>
+#include <__utility/forward.h>
+#include <cstddef>
+#include <type_traits>
+#include <utility>
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
+#   include <__memory/auto_ptr.h>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS default_delete {
+    static_assert(!is_function<_Tp>::value,
+                  "default_delete cannot be instantiated for function types");
+#ifndef _LIBCPP_CXX03_LANG
+  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
+#else
+  _LIBCPP_INLINE_VISIBILITY default_delete() {}
+#endif
+  template <class _Up>
+  _LIBCPP_INLINE_VISIBILITY
+  default_delete(const default_delete<_Up>&,
+                 typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* =
+                     0) _NOEXCEPT {}
+
+  _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) 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");
+    delete __ptr;
+  }
+};
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
+private:
+  template <class _Up>
+  struct _EnableIfConvertible
+      : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {};
+
+public:
+#ifndef _LIBCPP_CXX03_LANG
+  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
+#else
+  _LIBCPP_INLINE_VISIBILITY default_delete() {}
+#endif
+
+  template <class _Up>
+  _LIBCPP_INLINE_VISIBILITY
+  default_delete(const default_delete<_Up[]>&,
+                 typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
+
+  template <class _Up>
+  _LIBCPP_INLINE_VISIBILITY
+  typename _EnableIfConvertible<_Up>::type
+  operator()(_Up* __ptr) 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 void type");
+    delete[] __ptr;
+  }
+};
+
+template <class _Deleter>
+struct __unique_ptr_deleter_sfinae {
+  static_assert(!is_reference<_Deleter>::value, "incorrect specialization");
+  typedef const _Deleter& __lval_ref_type;
+  typedef _Deleter&& __good_rval_ref_type;
+  typedef true_type __enable_rval_overload;
+};
+
+template <class _Deleter>
+struct __unique_ptr_deleter_sfinae<_Deleter const&> {
+  typedef const _Deleter& __lval_ref_type;
+  typedef const _Deleter&& __bad_rval_ref_type;
+  typedef false_type __enable_rval_overload;
+};
+
+template <class _Deleter>
+struct __unique_ptr_deleter_sfinae<_Deleter&> {
+  typedef _Deleter& __lval_ref_type;
+  typedef _Deleter&& __bad_rval_ref_type;
+  typedef false_type __enable_rval_overload;
+};
+
+#if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
+#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
+#else
+#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
+#endif
+
+template <class _Tp, class _Dp = default_delete<_Tp> >
+class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
+public:
+  typedef _Tp element_type;
+  typedef _Dp deleter_type;
+  typedef _LIBCPP_NODEBUG_TYPE typename __pointer<_Tp, deleter_type>::type pointer;
+
+  static_assert(!is_rvalue_reference<deleter_type>::value,
+                "the specified deleter type cannot be an rvalue reference");
+
+private:
+  __compressed_pair<pointer, deleter_type> __ptr_;
+
+  struct __nat { int __for_bool_; };
+
+  typedef _LIBCPP_NODEBUG_TYPE __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
+
+  template <bool _Dummy>
+  using _LValRefType _LIBCPP_NODEBUG_TYPE =
+      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
+
+  template <bool _Dummy>
+  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
+      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
+
+  template <bool _Dummy>
+  using _BadRValRefType _LIBCPP_NODEBUG_TYPE  =
+      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
+
+  template <bool _Dummy, class _Deleter = typename __dependent_type<
+                             __identity<deleter_type>, _Dummy>::type>
+  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE =
+      typename enable_if<is_default_constructible<_Deleter>::value &&
+                         !is_pointer<_Deleter>::value>::type;
+
+  template <class _ArgType>
+  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
+      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
+
+  template <class _UPtr, class _Up>
+  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
+      is_convertible<typename _UPtr::pointer, pointer>::value &&
+      !is_array<_Up>::value
+  >::type;
+
+  template <class _UDel>
+  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
+      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
+      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
+    >::type;
+
+  template <class _UDel>
+  using _EnableIfDeleterAssignable = typename enable_if<
+      is_assignable<_Dp&, _UDel&&>::value
+    >::type;
+
+public:
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+  _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+  _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+  _LIBCPP_INLINE_VISIBILITY
+  explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __default_init_tag()) {}
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
+      : __ptr_(__p, __d) {}
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
+      : __ptr_(__p, _VSTD::move(__d)) {
+    static_assert(!is_reference<deleter_type>::value,
+                  "rvalue deleter bound to reference");
+  }
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
+
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(unique_ptr&& __u) _NOEXCEPT
+      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
+  }
+
+  template <class _Up, class _Ep,
+      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
+      class = _EnableIfDeleterConvertible<_Ep>
+  >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
+      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
+  template <class _Up>
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(auto_ptr<_Up>&& __p,
+             typename enable_if<is_convertible<_Up*, _Tp*>::value &&
+                                    is_same<_Dp, default_delete<_Tp> >::value,
+                                __nat>::type = __nat()) _NOEXCEPT
+      : __ptr_(__p.release(), __default_init_tag()) {}
+#endif
+
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
+    reset(__u.release());
+    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
+    return *this;
+  }
+
+  template <class _Up, class _Ep,
+      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
+      class = _EnableIfDeleterAssignable<_Ep>
+  >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
+    reset(__u.release());
+    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
+    return *this;
+  }
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
+  template <class _Up>
+  _LIBCPP_INLINE_VISIBILITY
+      typename enable_if<is_convertible<_Up*, _Tp*>::value &&
+                             is_same<_Dp, default_delete<_Tp> >::value,
+                         unique_ptr&>::type
+      operator=(auto_ptr<_Up> __p) {
+    reset(__p.release());
+    return *this;
+  }
+#endif
+
+#ifdef _LIBCPP_CXX03_LANG
+  unique_ptr(unique_ptr const&) = delete;
+  unique_ptr& operator=(unique_ptr const&) = delete;
+#endif
+
+
+  _LIBCPP_INLINE_VISIBILITY
+  ~unique_ptr() { reset(); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
+    reset();
+    return *this;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  typename add_lvalue_reference<_Tp>::type
+  operator*() const {
+    return *__ptr_.first();
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  pointer operator->() const _NOEXCEPT {
+    return __ptr_.first();
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  pointer get() const _NOEXCEPT {
+    return __ptr_.first();
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  deleter_type& get_deleter() _NOEXCEPT {
+    return __ptr_.second();
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  const deleter_type& get_deleter() const _NOEXCEPT {
+    return __ptr_.second();
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  explicit operator bool() const _NOEXCEPT {
+    return __ptr_.first() != nullptr;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  pointer release() _NOEXCEPT {
+    pointer __t = __ptr_.first();
+    __ptr_.first() = pointer();
+    return __t;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void reset(pointer __p = pointer()) _NOEXCEPT {
+    pointer __tmp = __ptr_.first();
+    __ptr_.first() = __p;
+    if (__tmp)
+      __ptr_.second()(__tmp);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void swap(unique_ptr& __u) _NOEXCEPT {
+    __ptr_.swap(__u.__ptr_);
+  }
+};
+
+
+template <class _Tp, class _Dp>
+class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
+public:
+  typedef _Tp element_type;
+  typedef _Dp deleter_type;
+  typedef typename __pointer<_Tp, deleter_type>::type pointer;
+
+private:
+  __compressed_pair<pointer, deleter_type> __ptr_;
+
+  template <class _From>
+  struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
+
+  template <class _FromElem>
+  struct _CheckArrayPointerConversion<_FromElem*>
+      : integral_constant<bool,
+          is_same<_FromElem*, pointer>::value ||
+            (is_same<pointer, element_type*>::value &&
+             is_convertible<_FromElem(*)[], element_type(*)[]>::value)
+      >
+  {};
+
+  typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
+
+  template <bool _Dummy>
+  using _LValRefType _LIBCPP_NODEBUG_TYPE =
+      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
+
+  template <bool _Dummy>
+  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
+      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
+
+  template <bool _Dummy>
+  using _BadRValRefType _LIBCPP_NODEBUG_TYPE =
+      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
+
+  template <bool _Dummy, class _Deleter = typename __dependent_type<
+                             __identity<deleter_type>, _Dummy>::type>
+  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE  =
+      typename enable_if<is_default_constructible<_Deleter>::value &&
+                         !is_pointer<_Deleter>::value>::type;
+
+  template <class _ArgType>
+  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
+      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
+
+  template <class _Pp>
+  using _EnableIfPointerConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
+      _CheckArrayPointerConversion<_Pp>::value
+  >::type;
+
+  template <class _UPtr, class _Up,
+        class _ElemT = typename _UPtr::element_type>
+  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
+      is_array<_Up>::value &&
+      is_same<pointer, element_type*>::value &&
+      is_same<typename _UPtr::pointer, _ElemT*>::value &&
+      is_convertible<_ElemT(*)[], element_type(*)[]>::value
+    >::type;
+
+  template <class _UDel>
+  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
+      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
+      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
+    >::type;
+
+  template <class _UDel>
+  using _EnableIfDeleterAssignable _LIBCPP_NODEBUG_TYPE  = typename enable_if<
+      is_assignable<_Dp&, _UDel&&>::value
+    >::type;
+
+public:
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+  _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+  _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
+
+  template <class _Pp, bool _Dummy = true,
+            class = _EnableIfDeleterDefaultConstructible<_Dummy>,
+            class = _EnableIfPointerConvertible<_Pp> >
+  _LIBCPP_INLINE_VISIBILITY
+  explicit unique_ptr(_Pp __p) _NOEXCEPT
+      : __ptr_(__p, __default_init_tag()) {}
+
+  template <class _Pp, bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
+            class = _EnableIfPointerConvertible<_Pp> >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT
+      : __ptr_(__p, __d) {}
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT
+      : __ptr_(nullptr, __d) {}
+
+  template <class _Pp, bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
+            class = _EnableIfPointerConvertible<_Pp> >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
+      : __ptr_(__p, _VSTD::move(__d)) {
+    static_assert(!is_reference<deleter_type>::value,
+                  "rvalue deleter bound to reference");
+  }
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
+      : __ptr_(nullptr, _VSTD::move(__d)) {
+    static_assert(!is_reference<deleter_type>::value,
+                  "rvalue deleter bound to reference");
+  }
+
+  template <class _Pp, bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,
+            class = _EnableIfPointerConvertible<_Pp> >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
+
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(unique_ptr&& __u) _NOEXCEPT
+      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
+    reset(__u.release());
+    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
+    return *this;
+  }
+
+  template <class _Up, class _Ep,
+      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
+      class = _EnableIfDeleterConvertible<_Ep>
+  >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
+      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {
+  }
+
+  template <class _Up, class _Ep,
+      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
+      class = _EnableIfDeleterAssignable<_Ep>
+  >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr&
+  operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
+    reset(__u.release());
+    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
+    return *this;
+  }
+
+#ifdef _LIBCPP_CXX03_LANG
+  unique_ptr(unique_ptr const&) = delete;
+  unique_ptr& operator=(unique_ptr const&) = delete;
+#endif
+
+public:
+  _LIBCPP_INLINE_VISIBILITY
+  ~unique_ptr() { reset(); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
+    reset();
+    return *this;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  typename add_lvalue_reference<_Tp>::type
+  operator[](size_t __i) const {
+    return __ptr_.first()[__i];
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  pointer get() const _NOEXCEPT {
+    return __ptr_.first();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  deleter_type& get_deleter() _NOEXCEPT {
+    return __ptr_.second();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  const deleter_type& get_deleter() const _NOEXCEPT {
+    return __ptr_.second();
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  explicit operator bool() const _NOEXCEPT {
+    return __ptr_.first() != nullptr;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  pointer release() _NOEXCEPT {
+    pointer __t = __ptr_.first();
+    __ptr_.first() = pointer();
+    return __t;
+  }
+
+  template <class _Pp>
+  _LIBCPP_INLINE_VISIBILITY
+  typename enable_if<
+      _CheckArrayPointerConversion<_Pp>::value
+  >::type
+  reset(_Pp __p) _NOEXCEPT {
+    pointer __tmp = __ptr_.first();
+    __ptr_.first() = __p;
+    if (__tmp)
+      __ptr_.second()(__tmp);
+  }
+
+  _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 swap(unique_ptr& __u) _NOEXCEPT {
+    __ptr_.swap(__u.__ptr_);
+  }
+
+};
+
+template <class _Tp, class _Dp>
+inline _LIBCPP_INLINE_VISIBILITY
+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>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y)
+{
+    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
+    typedef typename unique_ptr<_T2, _D2>::pointer _P2;
+    typedef typename common_type<_P1, _P2>::type _Vp;
+    return less<_Vp>()(__x.get(), __y.get());
+}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
+{
+    return !__x;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
+{
+    return !__x;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
+{
+    return static_cast<bool>(__x);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
+{
+    return static_cast<bool>(__x);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
+    return less<_P1>()(__x.get(), nullptr);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
+    return less<_P1>()(nullptr, __x.get());
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return nullptr < __x;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return __x < nullptr;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return !(nullptr < __x);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return !(__x < nullptr);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return !(__x < nullptr);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return !(nullptr < __x);
+}
+
+#if _LIBCPP_STD_VER > 11
+
+template<class _Tp>
+struct __unique_if
+{
+    typedef unique_ptr<_Tp> __unique_single;
+};
+
+template<class _Tp>
+struct __unique_if<_Tp[]>
+{
+    typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
+};
+
+template<class _Tp, size_t _Np>
+struct __unique_if<_Tp[_Np]>
+{
+    typedef void __unique_array_known_bound;
+};
+
+template<class _Tp, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __unique_if<_Tp>::__unique_single
+make_unique(_Args&&... __args)
+{
+    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __unique_if<_Tp>::__unique_array_unknown_bound
+make_unique(size_t __n)
+{
+    typedef typename remove_extent<_Tp>::type _Up;
+    return unique_ptr<_Tp>(new _Up[__n]());
+}
+
+template<class _Tp, class... _Args>
+    typename __unique_if<_Tp>::__unique_array_known_bound
+    make_unique(_Args&&...) = delete;
+
+#endif // _LIBCPP_STD_VER > 11
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
+
+template <class _Tp, class _Dp>
+#ifdef _LIBCPP_CXX03_LANG
+struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
+#else
+struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
+    unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
+#endif
+{
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef unique_ptr<_Tp, _Dp> argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t               result_type;
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const
+    {
+        typedef typename unique_ptr<_Tp, _Dp>::pointer pointer;
+        return hash<pointer>()(__ptr.get());
+    }
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_UNIQUE_PTR_H
diff --git a/include/__memory/uses_allocator.h b/include/__memory/uses_allocator.h
new file mode 100644
index 0000000..36e7520
--- /dev/null
+++ b/include/__memory/uses_allocator.h
@@ -0,0 +1,60 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_USES_ALLOCATOR_H
+#define _LIBCPP___MEMORY_USES_ALLOCATOR_H
+
+#include <__config>
+#include <cstddef>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct __has_allocator_type
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::allocator_type* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
+struct __uses_allocator
+    : public integral_constant<bool,
+        is_convertible<_Alloc, typename _Tp::allocator_type>::value>
+{
+};
+
+template <class _Tp, class _Alloc>
+struct __uses_allocator<_Tp, _Alloc, false>
+    : public false_type
+{
+};
+
+template <class _Tp, class _Alloc>
+struct _LIBCPP_TEMPLATE_VIS uses_allocator
+    : public __uses_allocator<_Tp, _Alloc>
+{
+};
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, class _Alloc>
+_LIBCPP_INLINE_VAR constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___MEMORY_USES_ALLOCATOR_H
diff --git a/include/__mutex_base b/include/__mutex_base
index 293fead..77590a8 100644
--- a/include/__mutex_base
+++ b/include/__mutex_base
@@ -1,10 +1,9 @@
 // -*- 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.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,62 +11,72 @@
 #define _LIBCPP___MUTEX_BASE
 
 #include <__config>
+#include <__threading_support>
 #include <chrono>
 #include <system_error>
-#include <pthread.h>
+#include <time.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-class _LIBCPP_TYPE_VIS mutex
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex
 {
-    pthread_mutex_t __m_;
+    __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
 
 public:
     _LIBCPP_INLINE_VISIBILITY
-#ifndef _LIBCPP_HAS_NO_CONSTEXPR
-     constexpr mutex() _NOEXCEPT : __m_(PTHREAD_MUTEX_INITIALIZER) {}
+    _LIBCPP_CONSTEXPR mutex() = default;
+
+    mutex(const mutex&) = delete;
+    mutex& operator=(const mutex&) = delete;
+
+#if defined(_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION)
+    ~mutex() = default;
 #else
-     mutex() _NOEXCEPT {__m_ = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;}
+    ~mutex() _NOEXCEPT;
 #endif
-     ~mutex();
 
-private:
-    mutex(const mutex&);// = delete;
-    mutex& operator=(const mutex&);// = delete;
+    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());
 
-public:
-    void lock();
-    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_;}
 };
 
-struct _LIBCPP_TYPE_VIS defer_lock_t {};
-struct _LIBCPP_TYPE_VIS try_to_lock_t {};
-struct _LIBCPP_TYPE_VIS adopt_lock_t {};
+static_assert(is_nothrow_default_constructible<mutex>::value,
+              "the default constructor for std::mutex must be nothrow");
 
-#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MUTEX)
+struct _LIBCPP_TYPE_VIS defer_lock_t { explicit defer_lock_t() = default; };
+struct _LIBCPP_TYPE_VIS try_to_lock_t { explicit try_to_lock_t() = default; };
+struct _LIBCPP_TYPE_VIS adopt_lock_t { explicit adopt_lock_t() = default; };
 
-extern const defer_lock_t  defer_lock;
-extern const try_to_lock_t try_to_lock;
-extern const adopt_lock_t  adopt_lock;
+#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
+
+extern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t  defer_lock;
+extern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock;
+extern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t  adopt_lock;
 
 #else
 
-constexpr defer_lock_t  defer_lock  = defer_lock_t();
-constexpr try_to_lock_t try_to_lock = try_to_lock_t();
-constexpr adopt_lock_t  adopt_lock  = adopt_lock_t();
+/* _LIBCPP_INLINE_VAR */ constexpr defer_lock_t  defer_lock  = defer_lock_t();
+/* _LIBCPP_INLINE_VAR */ constexpr try_to_lock_t try_to_lock = try_to_lock_t();
+/* _LIBCPP_INLINE_VAR */ constexpr adopt_lock_t  adopt_lock  = adopt_lock_t();
 
 #endif
 
 template <class _Mutex>
-class _LIBCPP_TYPE_VIS_ONLY lock_guard
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable)
+lock_guard
 {
 public:
     typedef _Mutex mutex_type;
@@ -76,22 +85,23 @@
     mutex_type& __m_;
 public:
 
-    _LIBCPP_INLINE_VISIBILITY
-    explicit lock_guard(mutex_type& __m)
+    _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY
+    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)
+
+    _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY
+    lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
         : __m_(__m) {}
     _LIBCPP_INLINE_VISIBILITY
-    ~lock_guard() {__m_.unlock();}
+    ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();}
 
 private:
-    lock_guard(lock_guard const&);// = delete;
-    lock_guard& operator=(lock_guard const&);// = delete;
+    lock_guard(lock_guard const&) _LIBCPP_EQUAL_DELETE;
+    lock_guard& operator=(lock_guard const&) _LIBCPP_EQUAL_DELETE;
 };
 
 template <class _Mutex>
-class _LIBCPP_TYPE_VIS_ONLY unique_lock
+class _LIBCPP_TEMPLATE_VIS unique_lock
 {
 public:
     typedef _Mutex mutex_type;
@@ -105,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()
     {
@@ -135,7 +145,6 @@
     unique_lock& operator=(unique_lock const&); // = delete;
 
 public:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     _LIBCPP_INLINE_VISIBILITY
     unique_lock(unique_lock&& __u) _NOEXCEPT
         : __m_(__u.__m_), __owns_(__u.__owns_)
@@ -152,8 +161,6 @@
             return *this;
         }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
     void lock();
     bool try_lock();
 
@@ -182,8 +189,7 @@
     _LIBCPP_INLINE_VISIBILITY
     bool owns_lock() const _NOEXCEPT {return __owns_;}
     _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_EXPLICIT
-        operator bool () const _NOEXCEPT {return __owns_;}
+    explicit operator bool() const _NOEXCEPT {return __owns_;}
     _LIBCPP_INLINE_VISIBILITY
     mutex_type* mutex() const _NOEXCEPT {return __m_;}
 };
@@ -264,74 +270,132 @@
 
 class _LIBCPP_TYPE_VIS condition_variable
 {
-    pthread_cond_t __cv_;
+    __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
 public:
     _LIBCPP_INLINE_VISIBILITY
-#ifndef _LIBCPP_HAS_NO_CONSTEXPR
-    constexpr condition_variable() : __cv_(PTHREAD_COND_INITIALIZER) {}
+    _LIBCPP_CONSTEXPR condition_variable() _NOEXCEPT = default;
+
+#ifdef _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
+    ~condition_variable() = default;
 #else
-    condition_variable() {__cv_ = (pthread_cond_t)PTHREAD_COND_INITIALIZER;}
-#endif
     ~condition_variable();
+#endif
 
-private:
-    condition_variable(const condition_variable&); // = delete;
-    condition_variable& operator=(const condition_variable&); // = delete;
+    condition_variable(const condition_variable&) = delete;
+    condition_variable& operator=(const condition_variable&) = delete;
 
-public:
     void notify_one() _NOEXCEPT;
     void notify_all() _NOEXCEPT;
 
     void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
     template <class _Predicate>
+        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
         void wait(unique_lock<mutex>& __lk, _Predicate __pred);
 
     template <class _Clock, class _Duration>
+        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
         cv_status
         wait_until(unique_lock<mutex>& __lk,
                    const chrono::time_point<_Clock, _Duration>& __t);
 
     template <class _Clock, class _Duration, class _Predicate>
+        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
         bool
         wait_until(unique_lock<mutex>& __lk,
                    const chrono::time_point<_Clock, _Duration>& __t,
                    _Predicate __pred);
 
     template <class _Rep, class _Period>
+        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
         cv_status
         wait_for(unique_lock<mutex>& __lk,
                  const chrono::duration<_Rep, _Period>& __d);
 
     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:
     void __do_timed_wait(unique_lock<mutex>& __lk,
        chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
+#if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
+    void __do_timed_wait(unique_lock<mutex>& __lk,
+       chrono::time_point<chrono::steady_clock, chrono::nanoseconds>) _NOEXCEPT;
+#endif
+    template <class _Clock>
+    void __do_timed_wait(unique_lock<mutex>& __lk,
+       chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT;
 };
+#endif // !_LIBCPP_HAS_NO_THREADS
 
-template <class _To, class _Rep, class _Period>
+template <class _Rep, class _Period>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
-    chrono::__is_duration<_To>::value,
-    _To
+    is_floating_point<_Rep>::value,
+    chrono::nanoseconds
 >::type
-__ceil(chrono::duration<_Rep, _Period> __d)
+__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d)
 {
     using namespace chrono;
-    _To __r = duration_cast<_To>(__d);
-    if (__r < __d)
-        ++__r;
-    return __r;
+    using __ratio = ratio_divide<_Period, nano>;
+    using __ns_rep = nanoseconds::rep;
+    _Rep __result_float = __d.count() * __ratio::num / __ratio::den;
+
+    _Rep __result_max = numeric_limits<__ns_rep>::max();
+    if (__result_float >= __result_max) {
+        return nanoseconds::max();
+    }
+
+    _Rep __result_min = numeric_limits<__ns_rep>::min();
+    if (__result_float <= __result_min) {
+        return nanoseconds::min();
+    }
+
+    return nanoseconds(static_cast<__ns_rep>(__result_float));
 }
 
+template <class _Rep, class _Period>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_floating_point<_Rep>::value,
+    chrono::nanoseconds
+>::type
+__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d)
+{
+    using namespace chrono;
+    if (__d.count() == 0) {
+        return nanoseconds(0);
+    }
+
+    using __ratio = ratio_divide<_Period, nano>;
+    using __ns_rep = nanoseconds::rep;
+    __ns_rep __result_max = numeric_limits<__ns_rep>::max();
+    if (__d.count() > 0 && __d.count() > __result_max / __ratio::num) {
+        return nanoseconds::max();
+    }
+
+    __ns_rep __result_min = numeric_limits<__ns_rep>::min();
+    if (__d.count() < 0 && __d.count() < __result_min / __ratio::num) {
+        return nanoseconds::min();
+    }
+
+    __ns_rep __result = __d.count() * __ratio::num / __ratio::den;
+    if (__result == 0) {
+        return nanoseconds(1);
+    }
+
+    return nanoseconds(__result);
+}
+
+#ifndef _LIBCPP_HAS_NO_THREADS
 template <class _Predicate>
 void
 condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred)
@@ -346,7 +410,15 @@
                                const chrono::time_point<_Clock, _Duration>& __t)
 {
     using namespace chrono;
-    wait_for(__lk, __t - _Clock::now());
+    using __clock_tp_ns = time_point<_Clock, nanoseconds>;
+
+    typename _Clock::time_point __now = _Clock::now();
+    if (__t <= __now)
+        return cv_status::timeout;
+
+    __clock_tp_ns __t_ns = __clock_tp_ns(_VSTD::__safe_nanosecond_cast(__t.time_since_epoch()));
+
+    __do_timed_wait(__lk, __t_ns);
     return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
 }
 
@@ -372,21 +444,31 @@
     using namespace chrono;
     if (__d <= __d.zero())
         return cv_status::timeout;
-    typedef time_point<system_clock, duration<long double, nano> > __sys_tpf;
-    typedef time_point<system_clock, nanoseconds> __sys_tpi;
-    __sys_tpf _Max = __sys_tpi::max();
-    system_clock::time_point __s_now = system_clock::now();
+    using __ns_rep = nanoseconds::rep;
     steady_clock::time_point __c_now = steady_clock::now();
-    if (_Max - __d > __s_now)
-        __do_timed_wait(__lk, __s_now + __ceil<nanoseconds>(__d));
-    else
-        __do_timed_wait(__lk, __sys_tpi::max());
+
+#if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
+    using __clock_tp_ns = time_point<steady_clock, nanoseconds>;
+    __ns_rep __now_count_ns = _VSTD::__safe_nanosecond_cast(__c_now.time_since_epoch()).count();
+#else
+    using __clock_tp_ns = time_point<system_clock, nanoseconds>;
+    __ns_rep __now_count_ns = _VSTD::__safe_nanosecond_cast(system_clock::now().time_since_epoch()).count();
+#endif
+
+    __ns_rep __d_ns_count = _VSTD::__safe_nanosecond_cast(__d).count();
+
+    if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) {
+        __do_timed_wait(__lk, __clock_tp_ns::max());
+    } else {
+        __do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count)));
+    }
+
     return steady_clock::now() - __c_now < __d ? cv_status::no_timeout :
                                                  cv_status::timeout;
 }
 
 template <class _Rep, class _Period, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 bool
 condition_variable::wait_for(unique_lock<mutex>& __lk,
                              const chrono::duration<_Rep, _Period>& __d,
@@ -396,6 +478,50 @@
                       _VSTD::move(__pred));
 }
 
+#if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
+inline
+void
+condition_variable::__do_timed_wait(unique_lock<mutex>& __lk,
+     chrono::time_point<chrono::steady_clock, chrono::nanoseconds> __tp) _NOEXCEPT
+{
+    using namespace chrono;
+    if (!__lk.owns_lock())
+        __throw_system_error(EPERM,
+                            "condition_variable::timed wait: mutex not locked");
+    nanoseconds __d = __tp.time_since_epoch();
+    timespec __ts;
+    seconds __s = duration_cast<seconds>(__d);
+    using __ts_sec = decltype(__ts.tv_sec);
+    const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max();
+    if (__s.count() < __ts_sec_max)
+    {
+        __ts.tv_sec = static_cast<__ts_sec>(__s.count());
+        __ts.tv_nsec = (__d - __s).count();
+    }
+    else
+    {
+        __ts.tv_sec = __ts_sec_max;
+        __ts.tv_nsec = giga::num - 1;
+    }
+    int __ec = pthread_cond_clockwait(&__cv_, __lk.mutex()->native_handle(), CLOCK_MONOTONIC, &__ts);
+    if (__ec != 0 && __ec != ETIMEDOUT)
+        __throw_system_error(__ec, "condition_variable timed_wait failed");
+}
+#endif // _LIBCPP_HAS_COND_CLOCKWAIT
+
+template <class _Clock>
+inline
+void
+condition_variable::__do_timed_wait(unique_lock<mutex>& __lk,
+     chrono::time_point<_Clock, chrono::nanoseconds> __tp) _NOEXCEPT
+{
+    wait_for(__lk, __tp - _Clock::now());
+}
+
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_END_NAMESPACE_STD
 
-#endif  // _LIBCPP___MUTEX_BASE
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MUTEX_BASE
diff --git a/include/__node_handle b/include/__node_handle
new file mode 100644
index 0000000..f3ffa5e
--- /dev/null
+++ b/include/__node_handle
@@ -0,0 +1,209 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___NODE_HANDLE
+#define _LIBCPP___NODE_HANDLE
+
+#include <__config>
+#include <__debug>
+#include <memory>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+// Specialized in __tree & __hash_table for their _NodeType.
+template <class _NodeType, class _Alloc>
+struct __generic_container_node_destructor;
+
+template <class _NodeType, class _Alloc,
+          template <class, class> class _MapOrSetSpecifics>
+class _LIBCPP_TEMPLATE_VIS __basic_node_handle
+    : public _MapOrSetSpecifics<
+          _NodeType,
+          __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>
+{
+    template <class _Tp, class _Compare, class _Allocator>
+        friend class __tree;
+    template <class _Tp, class _Hash, class _Equal, class _Allocator>
+        friend class __hash_table;
+    friend struct _MapOrSetSpecifics<
+        _NodeType, __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>;
+
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    typedef typename __rebind_pointer<typename __alloc_traits::void_pointer,
+                                      _NodeType>::type
+        __node_pointer_type;
+
+public:
+    typedef _Alloc allocator_type;
+
+private:
+    __node_pointer_type __ptr_ = nullptr;
+    optional<allocator_type> __alloc_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __release_ptr()
+    {
+        __ptr_ = nullptr;
+        __alloc_ = _VSTD::nullopt;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __destroy_node_pointer()
+    {
+        if (__ptr_ != nullptr)
+        {
+            typedef typename __allocator_traits_rebind<
+                allocator_type, _NodeType>::type __node_alloc_type;
+            __node_alloc_type __alloc(*__alloc_);
+            __generic_container_node_destructor<_NodeType, __node_alloc_type>(
+                __alloc, true)(__ptr_);
+            __ptr_ = nullptr;
+        }
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __basic_node_handle(__node_pointer_type __ptr,
+                        allocator_type const& __alloc)
+            : __ptr_(__ptr), __alloc_(__alloc)
+    {
+    }
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __basic_node_handle() = default;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __basic_node_handle(__basic_node_handle&& __other) noexcept
+            : __ptr_(__other.__ptr_),
+              __alloc_(_VSTD::move(__other.__alloc_))
+    {
+        __other.__ptr_ = nullptr;
+        __other.__alloc_ = _VSTD::nullopt;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __basic_node_handle& operator=(__basic_node_handle&& __other)
+    {
+        _LIBCPP_ASSERT(
+            __alloc_ == _VSTD::nullopt ||
+            __alloc_traits::propagate_on_container_move_assignment::value ||
+            __alloc_ == __other.__alloc_,
+            "node_type with incompatible allocator passed to "
+            "node_type::operator=(node_type&&)");
+
+        __destroy_node_pointer();
+        __ptr_ = __other.__ptr_;
+
+        if (__alloc_traits::propagate_on_container_move_assignment::value ||
+            __alloc_ == _VSTD::nullopt)
+            __alloc_ = _VSTD::move(__other.__alloc_);
+
+        __other.__ptr_ = nullptr;
+        __other.__alloc_ = _VSTD::nullopt;
+
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const { return *__alloc_; }
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit operator bool() const { return __ptr_ != nullptr; }
+
+    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
+    bool empty() const { return __ptr_ == nullptr; }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(__basic_node_handle& __other) noexcept(
+        __alloc_traits::propagate_on_container_swap::value ||
+        __alloc_traits::is_always_equal::value)
+    {
+        using _VSTD::swap;
+        swap(__ptr_, __other.__ptr_);
+        if (__alloc_traits::propagate_on_container_swap::value ||
+            __alloc_ == _VSTD::nullopt || __other.__alloc_ == _VSTD::nullopt)
+            swap(__alloc_, __other.__alloc_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    friend void swap(__basic_node_handle& __a, __basic_node_handle& __b)
+        noexcept(noexcept(__a.swap(__b))) { __a.swap(__b); }
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__basic_node_handle()
+    {
+        __destroy_node_pointer();
+    }
+};
+
+template <class _NodeType, class _Derived>
+struct __set_node_handle_specifics
+{
+    typedef typename _NodeType::__node_value_type value_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type& value() const
+    {
+        return static_cast<_Derived const*>(this)->__ptr_->__value_;
+    }
+};
+
+template <class _NodeType, class _Derived>
+struct __map_node_handle_specifics
+{
+    typedef typename _NodeType::__node_value_type::key_type key_type;
+    typedef typename _NodeType::__node_value_type::mapped_type mapped_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    key_type& key() const
+    {
+        return static_cast<_Derived const*>(this)->
+            __ptr_->__value_.__ref().first;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    mapped_type& mapped() const
+    {
+        return static_cast<_Derived const*>(this)->
+            __ptr_->__value_.__ref().second;
+    }
+};
+
+template <class _NodeType, class _Alloc>
+using __set_node_handle =
+    __basic_node_handle< _NodeType, _Alloc, __set_node_handle_specifics>;
+
+template <class _NodeType, class _Alloc>
+using __map_node_handle =
+    __basic_node_handle< _NodeType, _Alloc, __map_node_handle_specifics>;
+
+template <class _Iterator, class _NodeType>
+struct _LIBCPP_TEMPLATE_VIS __insert_return_type
+{
+    _Iterator position;
+    bool inserted;
+    _NodeType node;
+};
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
+#endif  // _LIBCPP___NODE_HANDLE
diff --git a/include/__nullptr b/include/__nullptr
new file mode 100644
index 0000000..e147511
--- /dev/null
+++ b/include/__nullptr
@@ -0,0 +1,61 @@
+// -*- C++ -*-
+//===--------------------------- __nullptr --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#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_TEMPLATE_VIS nullptr_t
+{
+    void* __lx;
+
+    struct __nat {int __for_bool_;};
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}
+
+    template <class _Tp>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+        operator _Tp* () const {return 0;}
+
+    template <class _Tp, class _Up>
+        _LIBCPP_INLINE_VISIBILITY
+        operator _Tp _Up::* () const {return 0;}
+
+    friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;}
+    friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;}
+};
+
+inline _LIBCPP_INLINE_VISIBILITY _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/__random/uniform_int_distribution.h b/include/__random/uniform_int_distribution.h
new file mode 100644
index 0000000..a7cfa1e
--- /dev/null
+++ b/include/__random/uniform_int_distribution.h
@@ -0,0 +1,316 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
+#define _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
+
+#include <__bits>
+#include <__config>
+#include <cstddef>
+#include <cstdint>
+#include <iosfwd>
+#include <limits>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// __independent_bits_engine
+
+template <unsigned long long _Xp, size_t _Rp>
+struct __log2_imp
+{
+    static const size_t value = _Xp & ((unsigned long long)(1) << _Rp) ? _Rp
+                                           : __log2_imp<_Xp, _Rp - 1>::value;
+};
+
+template <unsigned long long _Xp>
+struct __log2_imp<_Xp, 0>
+{
+    static const size_t value = 0;
+};
+
+template <size_t _Rp>
+struct __log2_imp<0, _Rp>
+{
+    static const size_t value = _Rp + 1;
+};
+
+template <class _UIntType, _UIntType _Xp>
+struct __log2
+{
+    static const size_t value = __log2_imp<_Xp,
+                                         sizeof(_UIntType) * __CHAR_BIT__ - 1>::value;
+};
+
+template<class _Engine, class _UIntType>
+class __independent_bits_engine
+{
+public:
+    // types
+    typedef _UIntType result_type;
+
+private:
+    typedef typename _Engine::result_type _Engine_result_type;
+    typedef typename conditional
+        <
+            sizeof(_Engine_result_type) <= sizeof(result_type),
+                result_type,
+                _Engine_result_type
+        >::type _Working_result_type;
+
+    _Engine& __e_;
+    size_t __w_;
+    size_t __w0_;
+    size_t __n_;
+    size_t __n0_;
+    _Working_result_type __y0_;
+    _Working_result_type __y1_;
+    _Engine_result_type __mask0_;
+    _Engine_result_type __mask1_;
+
+#ifdef _LIBCPP_CXX03_LANG
+    static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min
+                                          + _Working_result_type(1);
+#else
+    static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()
+                                                      + _Working_result_type(1);
+#endif
+    static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value;
+    static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits;
+    static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits;
+
+public:
+    // constructors and seeding functions
+    __independent_bits_engine(_Engine& __e, size_t __w);
+
+    // generating functions
+    result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
+
+private:
+    result_type __eval(false_type);
+    result_type __eval(true_type);
+};
+
+template<class _Engine, class _UIntType>
+__independent_bits_engine<_Engine, _UIntType>
+    ::__independent_bits_engine(_Engine& __e, size_t __w)
+        : __e_(__e),
+          __w_(__w)
+{
+    __n_ = __w_ / __m + (__w_ % __m != 0);
+    __w0_ = __w_ / __n_;
+    if (_Rp == 0)
+        __y0_ = _Rp;
+    else if (__w0_ < _WDt)
+        __y0_ = (_Rp >> __w0_) << __w0_;
+    else
+        __y0_ = 0;
+    if (_Rp - __y0_ > __y0_ / __n_)
+    {
+        ++__n_;
+        __w0_ = __w_ / __n_;
+        if (__w0_ < _WDt)
+            __y0_ = (_Rp >> __w0_) << __w0_;
+        else
+            __y0_ = 0;
+    }
+    __n0_ = __n_ - __w_ % __n_;
+    if (__w0_ < _WDt - 1)
+        __y1_ = (_Rp >> (__w0_ + 1)) << (__w0_ + 1);
+    else
+        __y1_ = 0;
+    __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) :
+                          _Engine_result_type(0);
+    __mask1_ = __w0_ < _EDt - 1 ?
+                               _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) :
+                               _Engine_result_type(~0);
+}
+
+template<class _Engine, class _UIntType>
+inline
+_UIntType
+__independent_bits_engine<_Engine, _UIntType>::__eval(false_type)
+{
+    return static_cast<result_type>(__e_() & __mask0_);
+}
+
+template<class _Engine, class _UIntType>
+_UIntType
+__independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
+{
+    const size_t _WRt = numeric_limits<result_type>::digits;
+    result_type _Sp = 0;
+    for (size_t __k = 0; __k < __n0_; ++__k)
+    {
+        _Engine_result_type __u;
+        do
+        {
+            __u = __e_() - _Engine::min();
+        } while (__u >= __y0_);
+        if (__w0_ < _WRt)
+            _Sp <<= __w0_;
+        else
+            _Sp = 0;
+        _Sp += __u & __mask0_;
+    }
+    for (size_t __k = __n0_; __k < __n_; ++__k)
+    {
+        _Engine_result_type __u;
+        do
+        {
+            __u = __e_() - _Engine::min();
+        } while (__u >= __y1_);
+        if (__w0_ < _WRt - 1)
+            _Sp <<= __w0_ + 1;
+        else
+            _Sp = 0;
+        _Sp += __u & __mask1_;
+    }
+    return _Sp;
+}
+
+template<class _IntType = int>
+class uniform_int_distribution
+{
+public:
+    // types
+    typedef _IntType result_type;
+
+    class param_type
+    {
+        result_type __a_;
+        result_type __b_;
+    public:
+        typedef uniform_int_distribution distribution_type;
+
+        explicit param_type(result_type __a = 0,
+                            result_type __b = numeric_limits<result_type>::max())
+            : __a_(__a), __b_(__b) {}
+
+        result_type a() const {return __a_;}
+        result_type b() const {return __b_;}
+
+        friend bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
+        friend bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructors and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    uniform_int_distribution() : uniform_int_distribution(0) {}
+    explicit uniform_int_distribution(
+        result_type __a, result_type __b = numeric_limits<result_type>::max())
+        : __p_(param_type(__a, __b)) {}
+#else
+    explicit uniform_int_distribution(
+        result_type __a = 0,
+        result_type __b = numeric_limits<result_type>::max())
+        : __p_(param_type(__a, __b)) {}
+#endif
+    explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}
+    void reset() {}
+
+    // generating functions
+    template<class _URNG> result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    result_type a() const {return __p_.a();}
+    result_type b() const {return __p_.b();}
+
+    param_type param() const {return __p_;}
+    void param(const param_type& __p) {__p_ = __p;}
+
+    result_type min() const {return a();}
+    result_type max() const {return b();}
+
+    friend bool operator==(const uniform_int_distribution& __x,
+                           const uniform_int_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend bool operator!=(const uniform_int_distribution& __x,
+                           const uniform_int_distribution& __y)
+            {return !(__x == __y);}
+};
+
+template<class _IntType>
+template<class _URNG>
+typename uniform_int_distribution<_IntType>::result_type
+uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
+_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
+{
+    typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t),
+                                            uint32_t, uint64_t>::type _UIntType;
+    const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1);
+    if (_Rp == 1)
+        return __p.a();
+    const size_t _Dt = numeric_limits<_UIntType>::digits;
+    typedef __independent_bits_engine<_URNG, _UIntType> _Eng;
+    if (_Rp == 0)
+        return static_cast<result_type>(_Eng(__g, _Dt)());
+    size_t __w = _Dt - __libcpp_clz(_Rp) - 1;
+    if ((_Rp & (numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0)
+        ++__w;
+    _Eng __e(__g, __w);
+    _UIntType __u;
+    do
+    {
+        __u = __e();
+    } while (__u >= _Rp);
+    return static_cast<result_type>(__u + __p.a());
+}
+
+template <class _CharT, class _Traits, class _IT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const uniform_int_distribution<_IT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    typedef basic_ostream<_CharT, _Traits> _Ostream;
+    __os.flags(_Ostream::dec | _Ostream::left);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    return __os << __x.a() << __sp << __x.b();
+}
+
+template <class _CharT, class _Traits, class _IT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           uniform_int_distribution<_IT>& __x)
+{
+    typedef uniform_int_distribution<_IT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    typedef basic_istream<_CharT, _Traits> _Istream;
+    __is.flags(_Istream::dec | _Istream::skipws);
+    result_type __a;
+    result_type __b;
+    __is >> __a >> __b;
+    if (!__is.fail())
+        __x.param(param_type(__a, __b));
+    return __is;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
diff --git a/include/__ranges/access.h b/include/__ranges/access.h
new file mode 100644
index 0000000..add8488
--- /dev/null
+++ b/include/__ranges/access.h
@@ -0,0 +1,222 @@
+// -*- C++ -*-
+//===------------------------ __ranges/access.h ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_ACCESS_H
+#define _LIBCPP___RANGES_ACCESS_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/readable_traits.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__utility/__decay_copy.h>
+#include <__utility/forward.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+// clang-format off
+
+namespace ranges {
+  template <class _Tp>
+  concept __can_borrow =
+      is_lvalue_reference_v<_Tp> || enable_borrowed_range<remove_cvref_t<_Tp> >;
+
+  template<class _Tp>
+  concept __is_complete = requires { sizeof(_Tp); };
+} // namespace ranges
+
+// [range.access.begin]
+namespace ranges::__begin {
+  template <class _Tp>
+  concept __member_begin =
+    __can_borrow<_Tp> &&
+    requires(_Tp&& __t) {
+      { _VSTD::__decay_copy(__t.begin()) } -> input_or_output_iterator;
+    };
+
+  void begin(auto&) = delete;
+  void begin(const auto&) = delete;
+
+  template <class _Tp>
+  concept __unqualified_begin =
+    !__member_begin<_Tp> &&
+    __can_borrow<_Tp> &&
+    __class_or_enum<remove_cvref_t<_Tp> > &&
+    requires(_Tp && __t) {
+      { _VSTD::__decay_copy(begin(__t)) } -> input_or_output_iterator;
+    };
+
+  struct __fn {
+    template <class _Tp>
+    requires is_array_v<remove_cv_t<_Tp>>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const noexcept {
+      constexpr bool __complete = __is_complete<iter_value_t<_Tp> >;
+      if constexpr (__complete) { // used to disable cryptic diagnostic
+        return __t + 0;
+      }
+      else {
+        static_assert(__complete, "`std::ranges::begin` is SFINAE-unfriendly on arrays of an incomplete type.");
+      }
+    }
+
+    template <class _Tp>
+    requires __member_begin<_Tp>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+    noexcept(noexcept(_VSTD::__decay_copy(__t.begin())))
+    {
+      return __t.begin();
+    }
+
+    template <class _Tp>
+    requires __unqualified_begin<_Tp>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+    noexcept(noexcept(_VSTD::__decay_copy(begin(__t))))
+    {
+      return begin(__t);
+    }
+
+    void operator()(auto&&) const = delete;
+  };
+} // namespace ranges::__begin
+
+namespace ranges {
+  inline namespace __cpo {
+    inline constexpr auto begin = __begin::__fn{};
+  } // namespace __cpo
+
+  template <class _Tp>
+  using iterator_t = decltype(ranges::begin(declval<_Tp&>()));
+} // namespace ranges
+
+// [range.access.end]
+namespace ranges::__end {
+  template <class _Tp>
+  concept __member_end =
+    __can_borrow<_Tp> &&
+    requires(_Tp&& __t) {
+      typename iterator_t<_Tp>;
+      { _VSTD::__decay_copy(_VSTD::forward<_Tp>(__t).end()) } -> sentinel_for<iterator_t<_Tp> >;
+    };
+
+  void end(auto&) = delete;
+  void end(const auto&) = delete;
+
+  template <class _Tp>
+  concept __unqualified_end =
+    !__member_end<_Tp> &&
+    __can_borrow<_Tp> &&
+    __class_or_enum<remove_cvref_t<_Tp> > &&
+    requires(_Tp && __t) {
+      typename iterator_t<_Tp>;
+      { _VSTD::__decay_copy(end(_VSTD::forward<_Tp>(__t))) } -> sentinel_for<iterator_t<_Tp> >;
+    };
+
+  class __fn {
+  public:
+    template <class _Tp, size_t _Np>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept {
+      constexpr bool __complete = __is_complete<remove_cv_t<_Tp> >;
+      if constexpr (__complete) { // used to disable cryptic diagnostic
+        return __t + _Np;
+      }
+      else {
+        static_assert(__complete, "`std::ranges::end` is SFINAE-unfriendly on arrays of an incomplete type.");
+      }
+    }
+
+    template <class _Tp>
+    requires __member_end<_Tp>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+    noexcept(noexcept(_VSTD::__decay_copy(__t.end())))
+    {
+      return _VSTD::forward<_Tp>(__t).end();
+    }
+
+    template <class _Tp>
+    requires __unqualified_end<_Tp>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+    noexcept(noexcept(_VSTD::__decay_copy(end(__t))))
+    {
+      return end(__t);
+    }
+
+    void operator()(auto&&) const = delete;
+  };
+} // namespace ranges::__end
+
+namespace ranges::inline __cpo {
+  inline constexpr auto end = __end::__fn{};
+} // namespace ranges::__cpo
+
+namespace ranges::__cbegin {
+  struct __fn {
+    template <class _Tp>
+    requires invocable<decltype(ranges::begin), _Tp const&>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const
+    noexcept(noexcept(ranges::begin(_VSTD::as_const(__t))))
+    {
+      return ranges::begin(_VSTD::as_const(__t));
+    }
+
+    template <class _Tp>
+    requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::begin), _Tp const&&>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+    noexcept(noexcept(ranges::begin(static_cast<_Tp const&&>(__t))))
+    {
+      return ranges::begin(static_cast<_Tp const&&>(__t));
+    }
+  };
+} // namespace ranges::__cbegin
+
+namespace ranges::inline __cpo {
+  inline constexpr auto cbegin = __cbegin::__fn{};
+} // namespace ranges::__cpo
+
+namespace ranges::__cend {
+  struct __fn {
+    template <class _Tp>
+    requires invocable<decltype(ranges::end), _Tp const&>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const
+    noexcept(noexcept(ranges::end(_VSTD::as_const(__t))))
+    {
+      return ranges::end(_VSTD::as_const(__t));
+    }
+
+    template <class _Tp>
+    requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::end), _Tp const&&>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+    noexcept(noexcept(ranges::end(static_cast<_Tp const&&>(__t))))
+    {
+      return ranges::end(static_cast<_Tp const&&>(__t));
+    }
+  };
+} // namespace ranges::__cend
+
+namespace ranges::inline __cpo {
+  inline constexpr auto cend = __cend::__fn{};
+} // namespace ranges::__cpo
+
+// clang-format off
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_ACCESS_H
diff --git a/include/__ranges/all.h b/include/__ranges/all.h
new file mode 100644
index 0000000..d678d3e
--- /dev/null
+++ b/include/__ranges/all.h
@@ -0,0 +1,86 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_ALL_H
+#define _LIBCPP___RANGES_ALL_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/ref_view.h>
+#include <__ranges/subrange.h>
+#include <__utility/__decay_copy.h>
+#include <__utility/declval.h>
+#include <__utility/forward.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace views {
+
+namespace __all {
+  struct __fn {
+    template<class _Tp>
+      requires ranges::view<decay_t<_Tp>>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr auto operator()(_Tp&& __t) const
+      noexcept(noexcept(_VSTD::__decay_copy(_VSTD::forward<_Tp>(__t))))
+    {
+      return _VSTD::forward<_Tp>(__t);
+    }
+
+    template<class _Tp>
+      requires (!ranges::view<decay_t<_Tp>>) &&
+               requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; }
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr auto operator()(_Tp&& __t) const
+      noexcept(noexcept(ranges::ref_view{_VSTD::forward<_Tp>(__t)}))
+    {
+      return ranges::ref_view{_VSTD::forward<_Tp>(__t)};
+    }
+
+    template<class _Tp>
+      requires (!ranges::view<decay_t<_Tp>> &&
+                !requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; } &&
+                 requires (_Tp&& __t) { ranges::subrange{_VSTD::forward<_Tp>(__t)}; })
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr auto operator()(_Tp&& __t) const
+      noexcept(noexcept(ranges::subrange{_VSTD::forward<_Tp>(__t)}))
+    {
+      return ranges::subrange{_VSTD::forward<_Tp>(__t)};
+    }
+  };
+}
+
+inline namespace __cpo {
+  inline constexpr auto all = __all::__fn{};
+} // namespace __cpo
+
+template<ranges::viewable_range _Range>
+using all_t = decltype(views::all(declval<_Range>()));
+
+} // namespace views
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_ALL_H
diff --git a/include/__ranges/common_view.h b/include/__ranges/common_view.h
new file mode 100644
index 0000000..dab8260
--- /dev/null
+++ b/include/__ranges/common_view.h
@@ -0,0 +1,113 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_COMMON_VIEW_H
+#define _LIBCPP___RANGES_COMMON_VIEW_H
+
+#include <__config>
+#include <__iterator/common_iterator.h>
+#include <__iterator/iterator_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/size.h>
+#include <__ranges/view_interface.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+
+template<view _View>
+  requires (!common_range<_View> && copyable<iterator_t<_View>>)
+class common_view : public view_interface<common_view<_View>> {
+  _View __base_ = _View();
+
+public:
+  _LIBCPP_HIDE_FROM_ABI
+  common_view() requires default_initializable<_View> = default;
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr explicit common_view(_View __v) : __base_(_VSTD::move(__v)) { }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _View base() && { return _VSTD::move(__base_); }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto begin() {
+    if constexpr (random_access_range<_View> && sized_range<_View>)
+      return ranges::begin(__base_);
+    else
+      return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::begin(__base_));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto begin() const requires range<const _View> {
+    if constexpr (random_access_range<const _View> && sized_range<const _View>)
+      return ranges::begin(__base_);
+    else
+      return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::begin(__base_));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto end() {
+    if constexpr (random_access_range<_View> && sized_range<_View>)
+      return ranges::begin(__base_) + ranges::size(__base_);
+    else
+      return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::end(__base_));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto end() const requires range<const _View> {
+    if constexpr (random_access_range<const _View> && sized_range<const _View>)
+      return ranges::begin(__base_) + ranges::size(__base_);
+    else
+      return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::end(__base_));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto size() requires sized_range<_View> {
+    return ranges::size(__base_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto size() const requires sized_range<const _View> {
+    return ranges::size(__base_);
+  }
+};
+
+template<class _Range>
+common_view(_Range&&)
+  -> common_view<views::all_t<_Range>>;
+
+template<class _View>
+inline constexpr bool enable_borrowed_range<common_view<_View>> = enable_borrowed_range<_View>;
+
+} // namespace ranges
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_COMMON_VIEW_H
diff --git a/include/__ranges/concepts.h b/include/__ranges/concepts.h
new file mode 100644
index 0000000..2f912c2
--- /dev/null
+++ b/include/__ranges/concepts.h
@@ -0,0 +1,138 @@
+// -*- C++ -*-
+//===--------------------- __ranges/concepts.h ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_CONCEPTS_H
+#define _LIBCPP___RANGES_CONCEPTS_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/readable_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/data.h>
+#include <__ranges/enable_view.h>
+#include <__ranges/size.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// clang-format off
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+  // [range.range]
+  template <class _Tp>
+  concept range = requires(_Tp& __t) {
+    ranges::begin(__t); // sometimes equality-preserving
+    ranges::end(__t);
+  };
+
+  template<class _Range>
+  concept borrowed_range = range<_Range> &&
+    (is_lvalue_reference_v<_Range> || enable_borrowed_range<remove_cvref_t<_Range>>);
+
+  // `iterator_t` defined in <__ranges/access.h>
+
+  template <range _Rp>
+  using sentinel_t = decltype(ranges::end(declval<_Rp&>()));
+
+  template <range _Rp>
+  using range_difference_t = iter_difference_t<iterator_t<_Rp>>;
+
+  template <range _Rp>
+  using range_value_t = iter_value_t<iterator_t<_Rp>>;
+
+  template <range _Rp>
+  using range_reference_t = iter_reference_t<iterator_t<_Rp>>;
+
+  template <range _Rp>
+  using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>;
+
+  // [range.sized]
+  template <class _Tp>
+  concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); };
+
+  template<sized_range _Rp>
+  using range_size_t = decltype(ranges::size(declval<_Rp&>()));
+
+  // `disable_sized_range` defined in `<__ranges/size.h>`
+
+  // [range.view], views
+
+  // `enable_view` defined in <__ranges/enable_view.h>
+  // `view_base` defined in <__ranges/enable_view.h>
+
+  template <class _Tp>
+  concept view =
+    range<_Tp> &&
+    movable<_Tp> &&
+    enable_view<_Tp>;
+
+  template<class _Range>
+  concept __simple_view =
+    view<_Range> && range<const _Range> &&
+    same_as<iterator_t<_Range>, iterator_t<const _Range>> &&
+    same_as<sentinel_t<_Range>, iterator_t<const _Range>>;
+
+  // [range.refinements], other range refinements
+  template <class _Rp, class _Tp>
+  concept output_range = range<_Rp> && output_iterator<iterator_t<_Rp>, _Tp>;
+
+  template <class _Tp>
+  concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
+
+  template <class _Tp>
+  concept forward_range = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;
+
+  template <class _Tp>
+  concept bidirectional_range = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>;
+
+  template <class _Tp>
+  concept random_access_range =
+      bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>;
+
+  template<class _Tp>
+  concept contiguous_range =
+    random_access_range<_Tp> &&
+    contiguous_iterator<iterator_t<_Tp>> &&
+    requires(_Tp& __t) {
+      { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>;
+    };
+
+  template <class _Tp>
+  concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>;
+
+  template<class _Tp>
+  concept viewable_range =
+    range<_Tp> && (
+      (view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>) ||
+      (!view<remove_cvref_t<_Tp>> && borrowed_range<_Tp>)
+    );
+} // namespace ranges
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+// clang-format on
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_CONCEPTS_H
diff --git a/include/__ranges/copyable_box.h b/include/__ranges/copyable_box.h
new file mode 100644
index 0000000..f2d3843
--- /dev/null
+++ b/include/__ranges/copyable_box.h
@@ -0,0 +1,175 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_COPYABLE_BOX_H
+#define _LIBCPP___RANGES_COPYABLE_BOX_H
+
+#include <__config>
+#include <__memory/addressof.h>
+#include <__memory/construct_at.h>
+#include <__utility/move.h>
+#include <concepts>
+#include <optional>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+// __copyable_box allows turning a type that is copy-constructible (but maybe not copy-assignable) into
+// a type that is both copy-constructible and copy-assignable. It does that by introducing an empty state
+// and basically doing destroy-then-copy-construct in the assignment operator. The empty state is necessary
+// to handle the case where the copy construction fails after destroying the object.
+//
+// In some cases, we can completely avoid the use of an empty state; we provide a specialization of
+// __copyable_box that does this, see below for the details.
+
+template<class _Tp>
+concept __copy_constructible_object = copy_constructible<_Tp> && is_object_v<_Tp>;
+
+namespace ranges {
+  // Primary template - uses std::optional and introduces an empty state in case assignment fails.
+  template<__copy_constructible_object _Tp>
+  class __copyable_box {
+    [[no_unique_address]] optional<_Tp> __val_;
+
+  public:
+    template<class ..._Args>
+      requires is_constructible_v<_Tp, _Args...>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
+      noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
+      : __val_(in_place, _VSTD::forward<_Args>(__args)...)
+    { }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
+      requires default_initializable<_Tp>
+      : __val_(in_place)
+    { }
+
+    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default;
+    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default;
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __copyable_box& operator=(__copyable_box const& __other)
+      noexcept(is_nothrow_copy_constructible_v<_Tp>)
+    {
+      if (this != _VSTD::addressof(__other)) {
+        if (__other.__has_value()) __val_.emplace(*__other);
+        else                       __val_.reset();
+      }
+      return *this;
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default;
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __copyable_box& operator=(__copyable_box&& __other)
+      noexcept(is_nothrow_move_constructible_v<_Tp>)
+    {
+      if (this != _VSTD::addressof(__other)) {
+        if (__other.__has_value()) __val_.emplace(_VSTD::move(*__other));
+        else                       __val_.reset();
+      }
+      return *this;
+    }
+
+    _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; }
+    _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; }
+    _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); }
+  };
+
+  // This partial specialization implements an optimization for when we know we don't need to store
+  // an empty state to represent failure to perform an assignment. For copy-assignment, this happens:
+  //
+  // 1. If the type is copyable (which includes copy-assignment), we can use the type's own assignment operator
+  //    directly and avoid using std::optional.
+  // 2. If the type is not copyable, but it is nothrow-copy-constructible, then we can implement assignment as
+  //    destroy-and-then-construct and we know it will never fail, so we don't need an empty state.
+  //
+  // The exact same reasoning can be applied for move-assignment, with copyable replaced by movable and
+  // nothrow-copy-constructible replaced by nothrow-move-constructible. This specialization is enabled
+  // whenever we can apply any of these optimizations for both the copy assignment and the move assignment
+  // operator.
+  template<class _Tp>
+  concept __doesnt_need_empty_state_for_copy = copyable<_Tp> || is_nothrow_copy_constructible_v<_Tp>;
+
+  template<class _Tp>
+  concept __doesnt_need_empty_state_for_move = movable<_Tp> || is_nothrow_move_constructible_v<_Tp>;
+
+  template<__copy_constructible_object _Tp>
+    requires __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp>
+  class __copyable_box<_Tp> {
+    [[no_unique_address]] _Tp __val_;
+
+  public:
+    template<class ..._Args>
+      requires is_constructible_v<_Tp, _Args...>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
+      noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
+      : __val_(_VSTD::forward<_Args>(__args)...)
+    { }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
+      requires default_initializable<_Tp>
+      : __val_()
+    { }
+
+    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default;
+    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default;
+
+    // Implementation of assignment operators in case we perform optimization (1)
+    _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box const&) requires copyable<_Tp> = default;
+    _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default;
+
+    // Implementation of assignment operators in case we perform optimization (2)
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __copyable_box& operator=(__copyable_box const& __other) noexcept {
+      static_assert(is_nothrow_copy_constructible_v<_Tp>);
+      if (this != _VSTD::addressof(__other)) {
+        _VSTD::destroy_at(_VSTD::addressof(__val_));
+        _VSTD::construct_at(_VSTD::addressof(__val_), __other.__val_);
+      }
+      return *this;
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __copyable_box& operator=(__copyable_box&& __other) noexcept {
+      static_assert(is_nothrow_move_constructible_v<_Tp>);
+      if (this != _VSTD::addressof(__other)) {
+        _VSTD::destroy_at(_VSTD::addressof(__val_));
+        _VSTD::construct_at(_VSTD::addressof(__val_), _VSTD::move(__other.__val_));
+      }
+      return *this;
+    }
+
+    _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; }
+    _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; }
+    _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; }
+  };
+} // namespace ranges
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_COPYABLE_BOX_H
diff --git a/include/__ranges/dangling.h b/include/__ranges/dangling.h
new file mode 100644
index 0000000..deb02a1
--- /dev/null
+++ b/include/__ranges/dangling.h
@@ -0,0 +1,47 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_DANGLING_H
+#define _LIBCPP___RANGES_DANGLING_H
+
+#include <__config>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+struct dangling {
+  dangling() = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr dangling(auto&&...) noexcept {}
+};
+
+template <range _Rp>
+using borrowed_iterator_t = _If<borrowed_range<_Rp>, iterator_t<_Rp>, dangling>;
+
+// borrowed_subrange_t defined in <__ranges/subrange.h>
+} // namespace ranges
+
+#endif // !_LIBCPP_HAS_NO_RANGES
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_DANGLING_H
diff --git a/include/__ranges/data.h b/include/__ranges/data.h
new file mode 100644
index 0000000..dae3098
--- /dev/null
+++ b/include/__ranges/data.h
@@ -0,0 +1,86 @@
+// -*- C++ -*-
+//===------------------------ __ranges/data.h ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_DATA_H
+#define _LIBCPP___RANGES_DATA_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/pointer_traits.h>
+#include <__ranges/access.h>
+#include <__utility/forward.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+// clang-format off
+namespace ranges {
+// [range.prim.data]
+namespace __data {
+  template <class _Tp>
+  concept __ptr_to_object = is_pointer_v<_Tp> && is_object_v<remove_pointer_t<_Tp>>;
+
+  template <class _Tp>
+  concept __member_data =
+    requires(_Tp&& __t) {
+      { _VSTD::forward<_Tp>(__t) } -> __can_borrow;
+      { __t.data() } -> __ptr_to_object;
+    };
+
+  template <class _Tp>
+  concept __ranges_begin_invocable =
+    !__member_data<_Tp> &&
+    requires(_Tp&& __t) {
+      { _VSTD::forward<_Tp>(__t) } -> __can_borrow;
+      { ranges::begin(_VSTD::forward<_Tp>(__t)) } -> contiguous_iterator;
+    };
+
+  struct __fn {
+    template <__member_data _Tp>
+      requires __can_borrow<_Tp>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __ptr_to_object auto operator()(_Tp&& __t) const
+        noexcept(noexcept(__t.data())) {
+      return __t.data();
+    }
+
+    template<__ranges_begin_invocable _Tp>
+      requires __can_borrow<_Tp>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __ptr_to_object auto operator()(_Tp&& __t) const
+        noexcept(noexcept(_VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t))))) {
+      return _VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t)));
+    }
+  };
+} // end namespace __data
+
+inline namespace __cpo {
+  inline constexpr const auto data = __data::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+// clang-format off
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_DATA_H
diff --git a/include/__ranges/drop_view.h b/include/__ranges/drop_view.h
new file mode 100644
index 0000000..099fd22
--- /dev/null
+++ b/include/__ranges/drop_view.h
@@ -0,0 +1,131 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_DROP_VIEW_H
+#define _LIBCPP___RANGES_DROP_VIEW_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/non_propagating_cache.h>
+#include <__ranges/size.h>
+#include <__ranges/view_interface.h>
+#include <__utility/move.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+  template<view _View>
+  class drop_view
+    : public view_interface<drop_view<_View>>
+  {
+    // We cache begin() whenever ranges::next is not guaranteed O(1) to provide an
+    // amortized O(1) begin() method. If this is an input_range, then we cannot cache
+    // begin because begin is not equality preserving.
+    // Note: drop_view<input-range>::begin() is still trivially amortized O(1) because
+    // one can't call begin() on it more than once.
+    static constexpr bool _UseCache = forward_range<_View> && !(random_access_range<_View> && sized_range<_View>);
+    using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
+    [[no_unique_address]] _Cache __cached_begin_ = _Cache();
+    range_difference_t<_View> __count_ = 0;
+    _View __base_ = _View();
+
+public:
+    drop_view() requires default_initializable<_View> = default;
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr drop_view(_View __base, range_difference_t<_View> __count)
+      : __count_(__count)
+      , __base_(_VSTD::move(__base))
+    {
+      _LIBCPP_ASSERT(__count_ >= 0, "count must be greater than or equal to zero.");
+    }
+
+    _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
+    _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return _VSTD::move(__base_); }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr auto begin()
+      requires (!(__simple_view<_View> &&
+                  random_access_range<const _View> && sized_range<const _View>))
+    {
+      if constexpr (_UseCache)
+        if (__cached_begin_.__has_value())
+          return *__cached_begin_;
+
+      auto __tmp = ranges::next(ranges::begin(__base_), __count_, ranges::end(__base_));
+      if constexpr (_UseCache)
+        __cached_begin_.__set(__tmp);
+      return __tmp;
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr auto begin() const
+      requires random_access_range<const _View> && sized_range<const _View>
+    {
+      return ranges::next(ranges::begin(__base_), __count_, ranges::end(__base_));
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr auto end()
+      requires (!__simple_view<_View>)
+    { return ranges::end(__base_); }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr auto end() const
+      requires range<const _View>
+    { return ranges::end(__base_); }
+
+    _LIBCPP_HIDE_FROM_ABI
+    static constexpr auto __size(auto& __self) {
+      const auto __s = ranges::size(__self.__base_);
+      const auto __c = static_cast<decltype(__s)>(__self.__count_);
+      return __s < __c ? 0 : __s - __c;
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr auto size()
+      requires sized_range<_View>
+    { return __size(*this); }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr auto size() const
+      requires sized_range<const _View>
+    { return __size(*this); }
+  };
+
+  template<class _Range>
+  drop_view(_Range&&, range_difference_t<_Range>) -> drop_view<views::all_t<_Range>>;
+
+  template<class _Tp>
+  inline constexpr bool enable_borrowed_range<drop_view<_Tp>> = enable_borrowed_range<_Tp>;
+} // namespace ranges
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_DROP_VIEW_H
diff --git a/include/__ranges/empty.h b/include/__ranges/empty.h
new file mode 100644
index 0000000..73892a8
--- /dev/null
+++ b/include/__ranges/empty.h
@@ -0,0 +1,86 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_EMPTY_H
+#define _LIBCPP___RANGES_EMPTY_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__ranges/access.h>
+#include <__ranges/size.h>
+#include <__utility/forward.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+// clang-format off
+namespace ranges {
+// [range.prim.empty]
+namespace __empty {
+  template <class _Tp>
+  concept __member_empty = requires(_Tp&& __t) {
+    bool(_VSTD::forward<_Tp>(__t).empty());
+  };
+
+  template<class _Tp>
+  concept __can_invoke_size =
+    !__member_empty<_Tp> &&
+    requires(_Tp&& __t) { ranges::size(_VSTD::forward<_Tp>(__t)); };
+
+  template <class _Tp>
+  concept __can_compare_begin_end =
+    !__member_empty<_Tp> &&
+    !__can_invoke_size<_Tp> &&
+    requires(_Tp&& __t) {
+      bool(ranges::begin(__t) == ranges::end(__t));
+      { ranges::begin(__t) } -> forward_iterator;
+    };
+
+  struct __fn {
+    template <__member_empty _Tp>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
+        noexcept(noexcept(bool(__t.empty()))) {
+      return __t.empty();
+    }
+
+    template <__can_invoke_size _Tp>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
+        noexcept(noexcept(ranges::size(_VSTD::forward<_Tp>(__t)))) {
+      return ranges::size(_VSTD::forward<_Tp>(__t)) == 0;
+    }
+
+    template<__can_compare_begin_end _Tp>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
+        noexcept(noexcept(bool(ranges::begin(__t) == ranges::end(__t)))) {
+      return ranges::begin(__t) == ranges::end(__t);
+    }
+  };
+}
+
+inline namespace __cpo {
+  inline constexpr auto empty = __empty::__fn{};
+} // namespace __cpo
+} // namespace ranges
+// clang-format off
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_EMPTY_H
diff --git a/include/__ranges/empty_view.h b/include/__ranges/empty_view.h
new file mode 100644
index 0000000..7c0f307
--- /dev/null
+++ b/include/__ranges/empty_view.h
@@ -0,0 +1,46 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_EMPTY_VIEW_H
+#define _LIBCPP___RANGES_EMPTY_VIEW_H
+
+#include <__config>
+#include <__ranges/view_interface.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+  template<class _Tp>
+    requires is_object_v<_Tp>
+  class empty_view : public view_interface<empty_view<_Tp>> {
+  public:
+    _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* begin() noexcept { return nullptr; }
+    _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* end() noexcept { return nullptr; }
+    _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* data() noexcept { return nullptr; }
+    _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 0; }
+    _LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return true; }
+  };
+} // namespace ranges
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_EMPTY_VIEW_H
diff --git a/include/__ranges/enable_borrowed_range.h b/include/__ranges/enable_borrowed_range.h
new file mode 100644
index 0000000..618b222
--- /dev/null
+++ b/include/__ranges/enable_borrowed_range.h
@@ -0,0 +1,46 @@
+// -*- C++ -*-
+//===------------------ __ranges/enable_borrowed_range.h ------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H
+#define _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H
+
+// These customization variables are used in <span> and <string_view>. The
+// separate header is used to avoid including the entire <ranges> header in
+// <span> and <string_view>.
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges
+{
+
+// [range.range], ranges
+
+template <class>
+inline constexpr bool enable_borrowed_range = false;
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H
diff --git a/include/__ranges/enable_view.h b/include/__ranges/enable_view.h
new file mode 100644
index 0000000..2628d51
--- /dev/null
+++ b/include/__ranges/enable_view.h
@@ -0,0 +1,42 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_ENABLE_VIEW_H
+#define _LIBCPP___RANGES_ENABLE_VIEW_H
+
+#include <__config>
+#include <concepts>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+
+struct view_base { };
+
+template <class _Tp>
+inline constexpr bool enable_view = derived_from<_Tp, view_base>;
+
+} // end namespace ranges
+
+#endif // !_LIBCPP_HAS_NO_RANGES
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_ENABLE_VIEW_H
diff --git a/include/__ranges/non_propagating_cache.h b/include/__ranges/non_propagating_cache.h
new file mode 100644
index 0000000..878f707
--- /dev/null
+++ b/include/__ranges/non_propagating_cache.h
@@ -0,0 +1,99 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H
+#define _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H
+
+#include <__config>
+#include <__iterator/concepts.h>        // indirectly_readable
+#include <__iterator/iterator_traits.h> // iter_reference_t
+#include <__memory/addressof.h>
+#include <concepts>                     // constructible_from
+#include <optional>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// clang-format off
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+  // __non_propagating_cache is a helper type that allows storing an optional value in it,
+  // but which does not copy the source's value when it is copy constructed/assigned to,
+  // and which resets the source's value when it is moved-from.
+  //
+  // This type is used as an implementation detail of some views that need to cache the
+  // result of `begin()` in order to provide an amortized O(1) begin() method. Typically,
+  // we don't want to propagate the value of the cache upon copy because the cached iterator
+  // may refer to internal details of the source view.
+  template<class _Tp>
+    requires is_object_v<_Tp>
+  class _LIBCPP_TEMPLATE_VIS __non_propagating_cache {
+    optional<_Tp> __value_ = nullopt;
+
+  public:
+    _LIBCPP_HIDE_FROM_ABI __non_propagating_cache() = default;
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __non_propagating_cache(__non_propagating_cache const&) noexcept
+      : __value_(nullopt)
+    { }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __non_propagating_cache(__non_propagating_cache&& __other) noexcept
+      : __value_(nullopt)
+    {
+      __other.__value_.reset();
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __non_propagating_cache& operator=(__non_propagating_cache const& __other) noexcept {
+      if (this != _VSTD::addressof(__other)) {
+        __value_.reset();
+      }
+      return *this;
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __non_propagating_cache& operator=(__non_propagating_cache&& __other) noexcept {
+      __value_.reset();
+      __other.__value_.reset();
+      return *this;
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr _Tp& operator*() { return *__value_; }
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr _Tp const& operator*() const { return *__value_; }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr bool __has_value() const { return __value_.has_value(); }
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr void __set(_Tp const& __value) { __value_.emplace(__value); }
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr void __set(_Tp&& __value) { __value_.emplace(_VSTD::move(__value)); }
+  };
+
+  struct __empty_cache { };
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H
diff --git a/include/__ranges/ref_view.h b/include/__ranges/ref_view.h
new file mode 100644
index 0000000..fb45a35
--- /dev/null
+++ b/include/__ranges/ref_view.h
@@ -0,0 +1,87 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_REF_VIEW_H
+#define _LIBCPP___RANGES_REF_VIEW_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/data.h>
+#include <__ranges/empty.h>
+#include <__ranges/size.h>
+#include <__ranges/view_interface.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+  template<range _Range>
+    requires is_object_v<_Range>
+  class ref_view : public view_interface<ref_view<_Range>> {
+    _Range *__range_;
+
+    static void __fun(_Range&);
+    static void __fun(_Range&&) = delete;
+
+public:
+    template<class _Tp>
+      requires __different_from<_Tp, ref_view> &&
+        convertible_to<_Tp, _Range&> && requires { __fun(declval<_Tp>()); }
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr ref_view(_Tp&& __t)
+      : __range_(_VSTD::addressof(static_cast<_Range&>(_VSTD::forward<_Tp>(__t))))
+    {}
+
+    _LIBCPP_HIDE_FROM_ABI constexpr _Range& base() const { return *__range_; }
+
+    _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Range> begin() const { return ranges::begin(*__range_); }
+    _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Range> end() const { return ranges::end(*__range_); }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr bool empty() const
+      requires requires { ranges::empty(*__range_); }
+    { return ranges::empty(*__range_); }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr auto size() const
+      requires sized_range<_Range>
+    { return ranges::size(*__range_); }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr auto data() const
+      requires contiguous_range<_Range>
+    { return ranges::data(*__range_); }
+  };
+
+  template<class _Range>
+  ref_view(_Range&) -> ref_view<_Range>;
+
+} // namespace ranges
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_REF_VIEW_H
diff --git a/include/__ranges/size.h b/include/__ranges/size.h
new file mode 100644
index 0000000..ce7183e
--- /dev/null
+++ b/include/__ranges/size.h
@@ -0,0 +1,132 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_SIZE_H
+#define _LIBCPP___RANGES_SIZE_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__ranges/access.h>
+#include <__utility/__decay_copy.h>
+#include <__utility/forward.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+// clang-format off
+namespace ranges {
+template<class>
+inline constexpr bool disable_sized_range = false;
+
+// [range.prim.size]
+namespace __size {
+  void size(auto&) = delete;
+  void size(const auto&) = delete;
+
+  template <class _Tp>
+  concept __size_enabled = !disable_sized_range<remove_cvref_t<_Tp>>;
+
+  template <class _Tp>
+  concept __member_size = __size_enabled<_Tp> && requires(_Tp&& __t) {
+    { _VSTD::__decay_copy(_VSTD::forward<_Tp>(__t).size()) } -> __integer_like;
+  };
+
+  template <class _Tp>
+  concept __unqualified_size =
+    __size_enabled<_Tp> &&
+    !__member_size<_Tp> &&
+    __class_or_enum<remove_cvref_t<_Tp>> &&
+    requires(_Tp&& __t) {
+      { _VSTD::__decay_copy(size(_VSTD::forward<_Tp>(__t))) } -> __integer_like;
+    };
+
+  template <class _Tp>
+  concept __difference =
+    !__member_size<_Tp> &&
+    !__unqualified_size<_Tp> &&
+    __class_or_enum<remove_cvref_t<_Tp>> &&
+    requires(_Tp&& __t) {
+      { ranges::begin(__t) } -> forward_iterator;
+      { ranges::end(__t) } -> sized_sentinel_for<decltype(ranges::begin(declval<_Tp>()))>;
+    };
+
+  struct __fn {
+    template <class _Tp, size_t _Sz>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&&)[_Sz]) const noexcept {
+      return _Sz;
+    }
+
+    template <class _Tp, size_t _Sz>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&)[_Sz]) const noexcept {
+      return _Sz;
+    }
+
+    template <__member_size _Tp>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
+        noexcept(noexcept(_VSTD::forward<_Tp>(__t).size())) {
+      return _VSTD::forward<_Tp>(__t).size();
+    }
+
+    template <__unqualified_size _Tp>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
+        noexcept(noexcept(size(_VSTD::forward<_Tp>(__t)))) {
+      return size(_VSTD::forward<_Tp>(__t));
+    }
+
+    template<__difference _Tp>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
+        noexcept(noexcept(ranges::end(__t) - ranges::begin(__t))) {
+      return _VSTD::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t));
+    }
+  };
+} // end namespace __size
+
+inline namespace __cpo {
+  inline constexpr auto size = __size::__fn{};
+} // namespace __cpo
+
+namespace __ssize {
+  struct __fn {
+    template<class _Tp>
+      requires requires (_Tp&& __t) { ranges::size(__t); }
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr integral auto operator()(_Tp&& __t) const
+        noexcept(noexcept(ranges::size(__t))) {
+      using _Signed = make_signed_t<decltype(ranges::size(__t))>;
+      if constexpr (sizeof(ptrdiff_t) > sizeof(_Signed))
+        return static_cast<ptrdiff_t>(ranges::size(__t));
+      else
+        return static_cast<_Signed>(ranges::size(__t));
+    }
+  };
+}
+
+inline namespace __cpo {
+  inline constexpr const auto ssize = __ssize::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+// clang-format off
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_SIZE_H
diff --git a/include/__ranges/subrange.h b/include/__ranges/subrange.h
new file mode 100644
index 0000000..25d333d
--- /dev/null
+++ b/include/__ranges/subrange.h
@@ -0,0 +1,267 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_SUBRANGE_H
+#define _LIBCPP___RANGES_SUBRANGE_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/advance.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/size.h>
+#include <__ranges/view_interface.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+// clang-format off
+namespace ranges {
+  template<class _From, class _To>
+  concept __convertible_to_non_slicing =
+    convertible_to<_From, _To> &&
+    // If they're both pointers, they must have the same element type.
+    !(is_pointer_v<decay_t<_From>> &&
+      is_pointer_v<decay_t<_To>> &&
+      __different_from<remove_pointer_t<decay_t<_From>>, remove_pointer_t<decay_t<_To>>>);
+
+  template<class _Tp>
+  concept __pair_like =
+    !is_reference_v<_Tp> && requires(_Tp __t) {
+      typename tuple_size<_Tp>::type; // Ensures `tuple_size<T>` is complete.
+      requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>;
+      typename tuple_element_t<0, remove_const_t<_Tp>>;
+      typename tuple_element_t<1, remove_const_t<_Tp>>;
+      { _VSTD::get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>;
+      { _VSTD::get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
+    };
+
+  template<class _Pair, class _Iter, class _Sent>
+  concept __pair_like_convertible_from =
+    !range<_Pair> && __pair_like<_Pair> &&
+    constructible_from<_Pair, _Iter, _Sent> &&
+    __convertible_to_non_slicing<_Iter, tuple_element_t<0, _Pair>> &&
+    convertible_to<_Sent, tuple_element_t<1, _Pair>>;
+
+  enum class _LIBCPP_ENUM_VIS subrange_kind : bool { unsized, sized };
+
+  template<class _Iter, class _Sent, bool>
+  struct __subrange_base {
+    static constexpr bool __store_size = false;
+    _Iter __begin_ = _Iter();
+    _Sent __end_ = _Sent();
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __subrange_base() = default;
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __subrange_base(_Iter __iter, _Sent __sent, make_unsigned_t<iter_difference_t<_Iter>> = 0)
+      : __begin_(_VSTD::move(__iter)), __end_(__sent) { }
+  };
+
+  template<class _Iter, class _Sent>
+  struct __subrange_base<_Iter, _Sent, true> {
+    static constexpr bool __store_size = true;
+    _Iter __begin_ = _Iter();
+    _Sent __end_ = _Sent();
+    make_unsigned_t<iter_difference_t<_Iter>> __size_ = 0;
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __subrange_base() = default;
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr __subrange_base(_Iter __iter, _Sent __sent, decltype(__size_) __size)
+      : __begin_(_VSTD::move(__iter)), __end_(__sent), __size_(__size) { }
+  };
+
+  template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent = _Iter,
+           subrange_kind _Kind = sized_sentinel_for<_Sent, _Iter>
+             ? subrange_kind::sized
+             : subrange_kind::unsized>
+    requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _Iter>)
+  struct _LIBCPP_TEMPLATE_VIS subrange
+    : public view_interface<subrange<_Iter, _Sent, _Kind>>,
+      private __subrange_base<_Iter, _Sent, _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _Iter>> {
+
+    using _Base = __subrange_base<_Iter, _Sent, _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _Iter>>;
+
+    _LIBCPP_HIDE_FROM_ABI
+    subrange() requires default_initializable<_Iter> = default;
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr subrange(__convertible_to_non_slicing<_Iter> auto __iter, _Sent __sent)
+      requires (!_Base::__store_size)
+      : _Base(_VSTD::move(__iter), __sent) {}
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr subrange(__convertible_to_non_slicing<_Iter> auto __iter, _Sent __sent,
+                       make_unsigned_t<iter_difference_t<_Iter>> __n)
+      requires (_Kind == subrange_kind::sized)
+      : _Base(_VSTD::move(__iter), __sent, __n) { }
+
+    template<__different_from<subrange> _Range>
+      requires borrowed_range<_Range> &&
+               __convertible_to_non_slicing<iterator_t<_Range>, _Iter> &&
+               convertible_to<sentinel_t<_Range>, _Sent>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr subrange(_Range&& __range)
+      requires (!_Base::__store_size)
+      : subrange(ranges::begin(__range), ranges::end(__range)) { }
+
+    template<__different_from<subrange> _Range>
+      requires borrowed_range<_Range> &&
+               __convertible_to_non_slicing<iterator_t<_Range>, _Iter> &&
+               convertible_to<sentinel_t<_Range>, _Sent>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr subrange(_Range&& __range)
+      requires _Base::__store_size && sized_range<_Range>
+      : subrange(__range, ranges::size(__range)) { }
+
+
+    template<borrowed_range _Range>
+      requires __convertible_to_non_slicing<iterator_t<_Range>, _Iter> &&
+               convertible_to<sentinel_t<_Range>, _Sent>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr subrange(_Range&& __range, make_unsigned_t<iter_difference_t<_Iter>> __n)
+      requires (_Kind == subrange_kind::sized)
+      : subrange(ranges::begin(__range), ranges::end(__range), __n) { }
+
+    template<__different_from<subrange> _Pair>
+      requires __pair_like_convertible_from<_Pair, const _Iter&, const _Sent&>
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr operator _Pair() const { return _Pair(this->__begin_, this->__end_); }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr _Iter begin() const requires copyable<_Iter> {
+      return this->__begin_;
+    }
+
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter begin() requires (!copyable<_Iter>) {
+      return _VSTD::move(this->__begin_);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr _Sent end() const { return this->__end_; }
+
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const { return this->__begin_ == this->__end_; }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr make_unsigned_t<iter_difference_t<_Iter>> size() const
+      requires (_Kind == subrange_kind::sized)
+    {
+      if constexpr (_Base::__store_size)
+        return this->__size_;
+      else
+        return __to_unsigned_like(this->__end_ - this->__begin_);
+    }
+
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange next(iter_difference_t<_Iter> __n = 1) const&
+      requires forward_iterator<_Iter> {
+      auto __tmp = *this;
+      __tmp.advance(__n);
+      return __tmp;
+    }
+
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange next(iter_difference_t<_Iter> __n = 1) && {
+      advance(__n);
+      return _VSTD::move(*this);
+    }
+
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange prev(iter_difference_t<_Iter> __n = 1) const
+      requires bidirectional_iterator<_Iter> {
+      auto __tmp = *this;
+      __tmp.advance(-__n);
+      return __tmp;
+    }
+
+    _LIBCPP_HIDE_FROM_ABI
+    constexpr subrange& advance(iter_difference_t<_Iter> __n) {
+      if constexpr (bidirectional_iterator<_Iter>) {
+        if (__n < 0) {
+          ranges::advance(this->__begin_, __n);
+          if constexpr (_Base::__store_size)
+            this->__size_ += _VSTD::__to_unsigned_like(-__n);
+          return *this;
+        }
+      }
+
+      auto __d = __n - ranges::advance(this->__begin_, __n, this->__end_);
+      if constexpr (_Base::__store_size)
+        this->__size_ -= _VSTD::__to_unsigned_like(__d);
+      return *this;
+    }
+  };
+
+  template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent>
+  subrange(_Iter, _Sent) -> subrange<_Iter, _Sent>;
+
+  template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent>
+  subrange(_Iter, _Sent, make_unsigned_t<iter_difference_t<_Iter>>)
+    -> subrange<_Iter, _Sent, subrange_kind::sized>;
+
+  template<borrowed_range _Range>
+  subrange(_Range&&) -> subrange<iterator_t<_Range>, sentinel_t<_Range>,
+                                 (sized_range<_Range> || sized_sentinel_for<sentinel_t<_Range>, iterator_t<_Range>>)
+                                   ? subrange_kind::sized : subrange_kind::unsized>;
+
+  template<borrowed_range _Range>
+  subrange(_Range&&, make_unsigned_t<range_difference_t<_Range>>)
+    -> subrange<iterator_t<_Range>, sentinel_t<_Range>, subrange_kind::sized>;
+
+  template<size_t _Index, class _Iter, class _Sent, subrange_kind _Kind>
+    requires (_Index < 2)
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto get(const subrange<_Iter, _Sent, _Kind>& __subrange) {
+    if constexpr (_Index == 0)
+      return __subrange.begin();
+    else
+      return __subrange.end();
+  }
+
+  template<size_t _Index, class _Iter, class _Sent, subrange_kind _Kind>
+    requires (_Index < 2)
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto get(subrange<_Iter, _Sent, _Kind>&& __subrange) {
+    if constexpr (_Index == 0)
+      return __subrange.begin();
+    else
+      return __subrange.end();
+  }
+
+  template<class _Ip, class _Sp, subrange_kind _Kp>
+  inline constexpr bool enable_borrowed_range<subrange<_Ip, _Sp, _Kp>> = true;
+
+  template<range _Rp>
+  using borrowed_subrange_t = _If<borrowed_range<_Rp>, subrange<iterator_t<_Rp> >, dangling>;
+} // namespace ranges
+
+using ranges::get;
+
+// clang-format off
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_SUBRANGE_H
diff --git a/include/__ranges/transform_view.h b/include/__ranges/transform_view.h
new file mode 100644
index 0000000..4243dc0
--- /dev/null
+++ b/include/__ranges/transform_view.h
@@ -0,0 +1,408 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_TRANSFORM_VIEW_H
+#define _LIBCPP___RANGES_TRANSFORM_VIEW_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iter_swap.h>
+#include <__iterator/iterator_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/copyable_box.h>
+#include <__ranges/empty.h>
+#include <__ranges/size.h>
+#include <__ranges/view_interface.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+
+template<class _View, class _Fn>
+concept __transform_view_constraints =
+           view<_View> && is_object_v<_Fn> &&
+           regular_invocable<_Fn&, range_reference_t<_View>> &&
+           __referenceable<invoke_result_t<_Fn&, range_reference_t<_View>>>;
+
+template<input_range _View, copy_constructible _Fn>
+  requires __transform_view_constraints<_View, _Fn>
+class transform_view : public view_interface<transform_view<_View, _Fn>> {
+  template<bool> class __iterator;
+  template<bool> class __sentinel;
+
+  [[no_unique_address]] __copyable_box<_Fn> __func_;
+  [[no_unique_address]] _View __base_ = _View();
+
+public:
+  _LIBCPP_HIDE_FROM_ABI
+  transform_view()
+    requires default_initializable<_View> && default_initializable<_Fn> = default;
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr transform_view(_View __base, _Fn __func)
+    : __func_(_VSTD::in_place, _VSTD::move(__func)), __base_(_VSTD::move(__base)) {}
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _View base() && { return _VSTD::move(__base_); }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __iterator<false> begin() {
+    return __iterator<false>{*this, ranges::begin(__base_)};
+  }
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __iterator<true> begin() const
+    requires range<const _View> &&
+             regular_invocable<const _Fn&, range_reference_t<const _View>>
+  {
+    return __iterator<true>(*this, ranges::begin(__base_));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __sentinel<false> end() {
+    return __sentinel<false>(ranges::end(__base_));
+  }
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __iterator<false> end()
+    requires common_range<_View>
+  {
+    return __iterator<false>(*this, ranges::end(__base_));
+  }
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __sentinel<true> end() const
+    requires range<const _View> &&
+             regular_invocable<const _Fn&, range_reference_t<const _View>>
+  {
+    return __sentinel<true>(ranges::end(__base_));
+  }
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __iterator<true> end() const
+    requires common_range<const _View> &&
+             regular_invocable<const _Fn&, range_reference_t<const _View>>
+  {
+    return __iterator<true>(*this, ranges::end(__base_));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto size() requires sized_range<_View> { return ranges::size(__base_); }
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto size() const requires sized_range<const _View> { return ranges::size(__base_); }
+};
+
+template<class _Range, class _Fn>
+transform_view(_Range&&, _Fn) -> transform_view<views::all_t<_Range>, _Fn>;
+
+template<class _View>
+struct __transform_view_iterator_concept { using type = input_iterator_tag; };
+
+template<random_access_range _View>
+struct __transform_view_iterator_concept<_View> { using type = random_access_iterator_tag; };
+
+template<bidirectional_range _View>
+struct __transform_view_iterator_concept<_View> { using type = bidirectional_iterator_tag; };
+
+template<forward_range _View>
+struct __transform_view_iterator_concept<_View> { using type = forward_iterator_tag; };
+
+template<class, class>
+struct __transform_view_iterator_category_base {};
+
+template<forward_range _View, class _Fn>
+struct __transform_view_iterator_category_base<_View, _Fn> {
+  using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category;
+
+  using iterator_category = conditional_t<
+    is_lvalue_reference_v<invoke_result_t<_Fn&, range_reference_t<_View>>>,
+    conditional_t<
+      derived_from<_Cat, contiguous_iterator_tag>,
+      random_access_iterator_tag,
+      _Cat
+    >,
+    input_iterator_tag
+  >;
+};
+
+template<input_range _View, copy_constructible _Fn>
+  requires __transform_view_constraints<_View, _Fn>
+template<bool _Const>
+class transform_view<_View, _Fn>::__iterator
+  : public __transform_view_iterator_category_base<_View, _Fn> {
+
+  using _Parent = __maybe_const<_Const, transform_view>;
+  using _Base = __maybe_const<_Const, _View>;
+
+  _Parent *__parent_ = nullptr;
+
+  template<bool>
+  friend class transform_view<_View, _Fn>::__iterator;
+
+  template<bool>
+  friend class transform_view<_View, _Fn>::__sentinel;
+
+public:
+  iterator_t<_Base> __current_ = iterator_t<_Base>();
+
+  using iterator_concept = typename __transform_view_iterator_concept<_View>::type;
+  using value_type = remove_cvref_t<invoke_result_t<_Fn&, range_reference_t<_Base>>>;
+  using difference_type = range_difference_t<_Base>;
+
+  _LIBCPP_HIDE_FROM_ABI
+  __iterator() requires default_initializable<iterator_t<_Base>> = default;
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current)
+    : __parent_(_VSTD::addressof(__parent)), __current_(_VSTD::move(__current)) {}
+
+  // Note: `__i` should always be `__iterator<false>`, but directly using
+  // `__iterator<false>` is ill-formed when `_Const` is false
+  // (see http://wg21.link/class.copy.ctor#5).
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __iterator(__iterator<!_Const> __i)
+    requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
+    : __parent_(__i.__parent_), __current_(_VSTD::move(__i.__current_)) {}
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr iterator_t<_Base> base() const&
+    requires copyable<iterator_t<_Base>>
+  {
+    return __current_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr iterator_t<_Base> base() && {
+    return _VSTD::move(__current_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr decltype(auto) operator*() const
+    noexcept(noexcept(_VSTD::invoke(*__parent_->__func_, *__current_)))
+  {
+    return _VSTD::invoke(*__parent_->__func_, *__current_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __iterator& operator++() {
+    ++__current_;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr void operator++(int) { ++__current_; }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __iterator operator++(int)
+    requires forward_range<_Base>
+  {
+    auto __tmp = *this;
+    ++*this;
+    return __tmp;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __iterator& operator--()
+    requires bidirectional_range<_Base>
+  {
+    --__current_;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __iterator operator--(int)
+    requires bidirectional_range<_Base>
+  {
+    auto __tmp = *this;
+    --*this;
+    return __tmp;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __iterator& operator+=(difference_type __n)
+    requires random_access_range<_Base>
+  {
+    __current_ += __n;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __iterator& operator-=(difference_type __n)
+    requires random_access_range<_Base>
+  {
+    __current_ -= __n;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr decltype(auto) operator[](difference_type __n) const
+    noexcept(noexcept(_VSTD::invoke(*__parent_->__func_, __current_[__n])))
+    requires random_access_range<_Base>
+  {
+    return _VSTD::invoke(*__parent_->__func_, __current_[__n]);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
+    requires equality_comparable<iterator_t<_Base>>
+  {
+    return __x.__current_ == __y.__current_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
+    requires random_access_range<_Base>
+  {
+    return __x.__current_ < __y.__current_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
+    requires random_access_range<_Base>
+  {
+    return __x.__current_ > __y.__current_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
+    requires random_access_range<_Base>
+  {
+    return __x.__current_ <= __y.__current_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
+    requires random_access_range<_Base>
+  {
+    return __x.__current_ >= __y.__current_;
+  }
+
+// TODO: Fix this as soon as soon as three_way_comparable is implemented.
+//   _LIBCPP_HIDE_FROM_ABI
+//   friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
+//     requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
+//   {
+//     return __x.__current_ <=> __y.__current_;
+//   }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr __iterator operator+(__iterator __i, difference_type __n)
+    requires random_access_range<_Base>
+  {
+    return __iterator{*__i.__parent_, __i.__current_ + __n};
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr __iterator operator+(difference_type __n, __iterator __i)
+    requires random_access_range<_Base>
+  {
+    return __iterator{*__i.__parent_, __i.__current_ + __n};
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr __iterator operator-(__iterator __i, difference_type __n)
+    requires random_access_range<_Base>
+  {
+    return __iterator{*__i.__parent_, __i.__current_ - __n};
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
+    requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
+  {
+    return __x.__current_ - __y.__current_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr decltype(auto) iter_move(const __iterator& __i)
+    noexcept(noexcept(*__i))
+  {
+    if constexpr (is_lvalue_reference_v<decltype(*__i)>)
+      return _VSTD::move(*__i);
+    else
+      return *__i;
+  }
+};
+
+template<input_range _View, copy_constructible _Fn>
+  requires __transform_view_constraints<_View, _Fn>
+template<bool _Const>
+class transform_view<_View, _Fn>::__sentinel {
+  using _Parent = __maybe_const<_Const, transform_view>;
+  using _Base = __maybe_const<_Const, _View>;
+
+  sentinel_t<_Base> __end_ = sentinel_t<_Base>();
+
+  template<bool>
+  friend class transform_view<_View, _Fn>::__iterator;
+
+  template<bool>
+  friend class transform_view<_View, _Fn>::__sentinel;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI
+  __sentinel() = default;
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(__end) {}
+
+  // Note: `__i` should always be `__sentinel<false>`, but directly using
+  // `__sentinel<false>` is ill-formed when `_Const` is false
+  // (see http://wg21.link/class.copy.ctor#5).
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr __sentinel(__sentinel<!_Const> __i)
+    requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
+    : __end_(_VSTD::move(__i.__end_)) {}
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr sentinel_t<_Base> base() const { return __end_; }
+
+  template<bool _OtherConst>
+    requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+    return __x.__current_ == __y.__end_;
+  }
+
+  template<bool _OtherConst>
+    requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
+  operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+    return __x.__current_ - __y.__end_;
+  }
+
+  template<bool _OtherConst>
+    requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+  _LIBCPP_HIDE_FROM_ABI
+  friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
+  operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) {
+    return __x.__end_ - __y.__current_;
+  }
+};
+
+} // namespace ranges
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_TRANSFORM_VIEW_H
diff --git a/include/__ranges/view_interface.h b/include/__ranges/view_interface.h
new file mode 100644
index 0000000..62cc5fd
--- /dev/null
+++ b/include/__ranges/view_interface.h
@@ -0,0 +1,198 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP___RANGES_VIEW_INTERFACE_H
+#define _LIBCPP___RANGES_VIEW_INTERFACE_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/prev.h>
+#include <__memory/pointer_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/empty.h>
+#include <__ranges/enable_view.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+
+template<class _Tp>
+concept __can_empty = requires(_Tp __t) { ranges::empty(__t); };
+
+template<class _Tp>
+void __implicitly_convert_to(type_identity_t<_Tp>) noexcept;
+
+template<class _Derived>
+  requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
+class view_interface : public view_base {
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _Derived& __derived() noexcept {
+    return static_cast<_Derived&>(*this);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr _Derived const& __derived() const noexcept {
+    return static_cast<_Derived const&>(*this);
+  }
+
+public:
+  template<class _D2 = _Derived>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
+    noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived()))))
+    requires forward_range<_D2>
+  {
+    return ranges::begin(__derived()) == ranges::end(__derived());
+  }
+
+  template<class _D2 = _Derived>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
+    noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived()))))
+    requires forward_range<const _D2>
+  {
+    return ranges::begin(__derived()) == ranges::end(__derived());
+  }
+
+  template<class _D2 = _Derived>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr explicit operator bool()
+    noexcept(noexcept(ranges::empty(declval<_D2>())))
+    requires __can_empty<_D2>
+  {
+    return !ranges::empty(__derived());
+  }
+
+  template<class _D2 = _Derived>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr explicit operator bool() const
+    noexcept(noexcept(ranges::empty(declval<const _D2>())))
+    requires __can_empty<const _D2>
+  {
+    return !ranges::empty(__derived());
+  }
+
+  template<class _D2 = _Derived>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto data()
+    noexcept(noexcept(_VSTD::to_address(ranges::begin(__derived()))))
+    requires contiguous_iterator<iterator_t<_D2>>
+  {
+    return _VSTD::to_address(ranges::begin(__derived()));
+  }
+
+  template<class _D2 = _Derived>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto data() const
+    noexcept(noexcept(_VSTD::to_address(ranges::begin(__derived()))))
+    requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>>
+  {
+    return _VSTD::to_address(ranges::begin(__derived()));
+  }
+
+  template<class _D2 = _Derived>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto size()
+    noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived())))
+    requires forward_range<_D2>
+      && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
+  {
+    return ranges::end(__derived()) - ranges::begin(__derived());
+  }
+
+  template<class _D2 = _Derived>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr auto size() const
+    noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived())))
+    requires forward_range<const _D2>
+      && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
+  {
+    return ranges::end(__derived()) - ranges::begin(__derived());
+  }
+
+  template<class _D2 = _Derived>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr decltype(auto) front()
+    noexcept(noexcept(*ranges::begin(__derived())))
+    requires forward_range<_D2>
+  {
+    _LIBCPP_ASSERT(!empty(),
+        "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
+    return *ranges::begin(__derived());
+  }
+
+  template<class _D2 = _Derived>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr decltype(auto) front() const
+    noexcept(noexcept(*ranges::begin(__derived())))
+    requires forward_range<const _D2>
+  {
+    _LIBCPP_ASSERT(!empty(),
+        "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
+    return *ranges::begin(__derived());
+  }
+
+  template<class _D2 = _Derived>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr decltype(auto) back()
+    noexcept(noexcept(*ranges::prev(ranges::end(__derived()))))
+    requires bidirectional_range<_D2> && common_range<_D2>
+  {
+    _LIBCPP_ASSERT(!empty(),
+        "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
+    return *ranges::prev(ranges::end(__derived()));
+  }
+
+  template<class _D2 = _Derived>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr decltype(auto) back() const
+    noexcept(noexcept(*ranges::prev(ranges::end(__derived()))))
+    requires bidirectional_range<const _D2> && common_range<const _D2>
+  {
+    _LIBCPP_ASSERT(!empty(),
+        "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
+    return *ranges::prev(ranges::end(__derived()));
+  }
+
+  template<random_access_range _RARange = _Derived>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr decltype(auto) operator[](range_difference_t<_RARange> __index)
+    noexcept(noexcept(ranges::begin(__derived())[__index]))
+  {
+    return ranges::begin(__derived())[__index];
+  }
+
+  template<random_access_range _RARange = const _Derived>
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const
+    noexcept(noexcept(ranges::begin(__derived())[__index]))
+  {
+    return ranges::begin(__derived())[__index];
+  }
+};
+
+}
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_VIEW_INTERFACE_H
diff --git a/include/__refstring b/include/__refstring
deleted file mode 100644
index 6866bf1..0000000
--- a/include/__refstring
+++ /dev/null
@@ -1,139 +0,0 @@
-//===------------------------ __refstring ---------------------------------===//
-//
-//                     The 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___REFSTRING
-#define _LIBCPP___REFSTRING
-
-#include <__config>
-#include <cstddef>
-#include <cstring>
-#if __APPLE__
-#include <dlfcn.h>
-#include <mach-o/dyld.h>
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-class _LIBCPP_HIDDEN __libcpp_refstring
-{
-private:
-    const char* str_;
-
-    typedef int count_t;
-
-    struct _Rep_base
-    {
-        std::size_t len;
-        std::size_t cap;
-        count_t     count;
-    };
-
-    static
-    _Rep_base*
-    rep_from_data(const char *data_) _NOEXCEPT
-    {
-        char *data = const_cast<char *>(data_);
-        return reinterpret_cast<_Rep_base *>(data - sizeof(_Rep_base));
-    }
-    static
-    char *
-    data_from_rep(_Rep_base *rep) _NOEXCEPT
-    {
-        char *data = reinterpret_cast<char *>(rep);
-        return data + sizeof(*rep);
-    }
-
-#if __APPLE__
-    static
-    const char*
-    compute_gcc_empty_string_storage() _NOEXCEPT
-    {
-        void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD);
-        if (handle == nullptr)
-            return nullptr;
-        void* sym = dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE");
-        if (sym == nullptr)
-            return nullptr;
-        return data_from_rep(reinterpret_cast<_Rep_base *>(sym));
-    }
-
-    static
-    const char*
-    get_gcc_empty_string_storage() _NOEXCEPT
-    {
-        static const char* p = compute_gcc_empty_string_storage();
-        return p;
-    }
-
-    bool
-    uses_refcount() const
-    {
-        return str_ != get_gcc_empty_string_storage();
-    }
-#else
-    bool
-    uses_refcount() const
-    {
-        return true;
-    }
-#endif
-
-public:
-    explicit __libcpp_refstring(const char* msg) {
-        std::size_t len = strlen(msg);
-        _Rep_base* rep = static_cast<_Rep_base *>(::operator new(sizeof(*rep) + len + 1));
-        rep->len = len;
-        rep->cap = len;
-        rep->count = 0;
-        char *data = data_from_rep(rep);
-        std::memcpy(data, msg, len + 1);
-        str_ = data;
-    }
-
-    __libcpp_refstring(const __libcpp_refstring& s) _NOEXCEPT : str_(s.str_)
-    {
-        if (uses_refcount())
-            __sync_add_and_fetch(&rep_from_data(str_)->count, 1);
-    }
-
-    __libcpp_refstring& operator=(const __libcpp_refstring& s) _NOEXCEPT
-    {
-        bool adjust_old_count = uses_refcount();
-        struct _Rep_base *old_rep = rep_from_data(str_);
-        str_ = s.str_;
-        if (uses_refcount())
-            __sync_add_and_fetch(&rep_from_data(str_)->count, 1);
-        if (adjust_old_count)
-        {
-            if (__sync_add_and_fetch(&old_rep->count, count_t(-1)) < 0)
-            {
-                ::operator delete(old_rep);
-            }
-        }
-        return *this;
-    }
-
-    ~__libcpp_refstring()
-    {
-        if (uses_refcount())
-        {
-            _Rep_base* rep = rep_from_data(str_);
-            if (__sync_add_and_fetch(&rep->count, count_t(-1)) < 0)
-            {
-                ::operator delete(rep);
-            }
-        }
-    }
-
-    const char* c_str() const _NOEXCEPT {return str_;}
-};
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif //_LIBCPP___REFSTRING
diff --git a/include/__split_buffer b/include/__split_buffer
index 1d529cb..901c037 100644
--- a/include/__split_buffer
+++ b/include/__split_buffer
@@ -3,23 +3,26 @@
 #define _LIBCPP_SPLIT_BUFFER
 
 #include <__config>
-#include <type_traits>
+#include <__utility/forward.h>
 #include <algorithm>
-
-#include <__undef_min_max>
+#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <bool>
 class __split_buffer_common
 {
 protected:
-    void __throw_length_error() const;
-    void __throw_out_of_range() const;
+    _LIBCPP_NORETURN void __throw_length_error() const;
+    _LIBCPP_NORETURN void __throw_out_of_range() const;
 };
 
 template <class _Tp, class _Allocator = allocator<_Tp> >
@@ -56,14 +59,16 @@
     _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();
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     __split_buffer(__split_buffer&& __c)
         _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
     __split_buffer(__split_buffer&& __c, const __alloc_rr& __a);
@@ -71,7 +76,6 @@
         _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
                 is_nothrow_move_assignable<allocator_type>::value) ||
                !__alloc_traits::propagate_on_container_move_assignment::value);
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
     _LIBCPP_INLINE_VISIBILITY       iterator begin() _NOEXCEPT       {return __begin_;}
     _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __begin_;}
@@ -96,14 +100,10 @@
     void shrink_to_fit() _NOEXCEPT;
     void push_front(const_reference __x);
     _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
-#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
     void push_front(value_type&& __x);
     void push_back(value_type&& __x);
-#if !defined(_LIBCPP_HAS_NO_VARIADICS)
     template <class... _Args>
         void emplace_back(_Args&&... __args);
-#endif  // !defined(_LIBCPP_HAS_NO_VARIADICS)
-#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
 
     _LIBCPP_INLINE_VISIBILITY void pop_front() {__destruct_at_begin(__begin_+1);}
     _LIBCPP_INLINE_VISIBILITY void pop_back() {__destruct_at_end(__end_-1);}
@@ -113,22 +113,24 @@
     template <class _InputIter>
         typename enable_if
         <
-            __is_input_iterator<_InputIter>::value &&
-           !__is_forward_iterator<_InputIter>::value,
+            __is_cpp17_input_iterator<_InputIter>::value &&
+           !__is_cpp17_forward_iterator<_InputIter>::value,
             void
         >::type
         __construct_at_end(_InputIter __first, _InputIter __last);
     template <class _ForwardIterator>
         typename enable_if
         <
-            __is_forward_iterator<_ForwardIterator>::value,
+            __is_cpp17_forward_iterator<_ForwardIterator>::value,
             void
         >::type
         __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
 
     _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
@@ -157,24 +159,18 @@
     void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT
         {}
 
-    _LIBCPP_INLINE_VISIBILITY
-    static void __swap_alloc(__alloc_rr& __x, __alloc_rr& __y)
-        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
-                   __is_nothrow_swappable<__alloc_rr>::value)
-        {__swap_alloc(__x, __y, integral_constant<bool,
-                      __alloc_traits::propagate_on_container_swap::value>());}
-
-    _LIBCPP_INLINE_VISIBILITY
-    static void __swap_alloc(__alloc_rr& __x, __alloc_rr& __y, true_type)
-        _NOEXCEPT_(__is_nothrow_swappable<__alloc_rr>::value)
-        {
-            using _VSTD::swap;
-            swap(__x, __y);
-        }
-
-    _LIBCPP_INLINE_VISIBILITY
-    static void __swap_alloc(__alloc_rr&, __alloc_rr&, false_type) _NOEXCEPT
-        {}
+    struct _ConstructTransaction {
+      explicit _ConstructTransaction(pointer* __p, size_type __n) _NOEXCEPT
+      : __pos_(*__p), __end_(*__p + __n), __dest_(__p) {
+      }
+      ~_ConstructTransaction() {
+        *__dest_ = __pos_;
+      }
+      pointer __pos_;
+     const pointer __end_;
+    private:
+     pointer *__dest_;
+    };
 };
 
 template <class _Tp, class _Allocator>
@@ -211,13 +207,10 @@
 void
 __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n)
 {
-    __alloc_rr& __a = this->__alloc();
-    do
-    {
-        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));
-        ++this->__end_;
-        --__n;
-    } while (__n > 0);
+    _ConstructTransaction __tx(&this->__end_, __n);
+    for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
+        __alloc_traits::construct(this->__alloc(), _VSTD::__to_address(__tx.__pos_));
+    }
 }
 
 //  Copy constructs __n objects starting at __end_ from __x
@@ -230,21 +223,19 @@
 void
 __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
 {
-    __alloc_rr& __a = this->__alloc();
-    do
-    {
-        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x);
-        ++this->__end_;
-        --__n;
-    } while (__n > 0);
+    _ConstructTransaction __tx(&this->__end_, __n);
+    for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
+        __alloc_traits::construct(this->__alloc(),
+            _VSTD::__to_address(__tx.__pos_), __x);
+    }
 }
 
 template <class _Tp, class _Allocator>
 template <class _InputIter>
 typename enable_if
 <
-     __is_input_iterator<_InputIter>::value &&
-    !__is_forward_iterator<_InputIter>::value,
+     __is_cpp17_input_iterator<_InputIter>::value &&
+    !__is_cpp17_forward_iterator<_InputIter>::value,
     void
 >::type
 __split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last)
@@ -259,10 +250,10 @@
             __split_buffer __buf(__new_cap, 0, __a);
             for (pointer __p = __begin_; __p != __end_; ++__p, ++__buf.__end_)
                 __alloc_traits::construct(__buf.__alloc(),
-                        _VSTD::__to_raw_pointer(__buf.__end_), _VSTD::move(*__p));
+                        _VSTD::__to_address(__buf.__end_), _VSTD::move(*__p));
             swap(__buf);
         }
-        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
+        __alloc_traits::construct(__a, _VSTD::__to_address(this->__end_), *__first);
         ++this->__end_;
     }
 }
@@ -271,30 +262,29 @@
 template <class _ForwardIterator>
 typename enable_if
 <
-    __is_forward_iterator<_ForwardIterator>::value,
+    __is_cpp17_forward_iterator<_ForwardIterator>::value,
     void
 >::type
 __split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
 {
-    __alloc_rr& __a = this->__alloc();
-    for (; __first != __last; ++__first)
-    {
-        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
-        ++this->__end_;
+    _ConstructTransaction __tx(&this->__end_, _VSTD::distance(__first, __last));
+    for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, ++__first) {
+        __alloc_traits::construct(this->__alloc(),
+            _VSTD::__to_address(__tx.__pos_), *__first);
     }
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 __split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type)
 {
     while (__begin_ != __new_begin)
-        __alloc_traits::destroy(__alloc(), __to_raw_pointer(__begin_++));
+        __alloc_traits::destroy(__alloc(), _VSTD::__to_address(__begin_++));
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
 void
 __split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type)
 {
@@ -307,7 +297,7 @@
 __split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT
 {
     while (__new_last != __end_)
-        __alloc_traits::destroy(__alloc(), __to_raw_pointer(--__end_));
+        __alloc_traits::destroy(__alloc(), _VSTD::__to_address(--__end_));
 }
 
 template <class _Tp, class _Allocator>
@@ -328,22 +318,22 @@
 }
 
 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)
+    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __default_init_tag())
 {
 }
 
 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)
 {
@@ -357,8 +347,6 @@
         __alloc_traits::deallocate(__alloc(), __first_, capacity());
 }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Tp, class _Allocator>
 __split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c)
     _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
@@ -375,7 +363,7 @@
 
 template <class _Tp, class _Allocator>
 __split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a)
-    : __end_cap_(__a)
+    : __end_cap_(nullptr, __a)
 {
     if (__a == __c.__alloc())
     {
@@ -419,8 +407,6 @@
     return *this;
 }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Tp, class _Allocator>
 void
 __split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x)
@@ -431,7 +417,7 @@
     _VSTD::swap(__begin_, __x.__begin_);
     _VSTD::swap(__end_, __x.__end_);
     _VSTD::swap(__end_cap(), __x.__end_cap());
-    __swap_alloc(__alloc(), __x.__alloc());
+    _VSTD::__swap_allocator(__alloc(), __x.__alloc());
 }
 
 template <class _Tp, class _Allocator>
@@ -459,7 +445,7 @@
 #ifndef _LIBCPP_NO_EXCEPTIONS
         try
         {
-#endif  // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_NO_EXCEPTIONS
             __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc());
             __t.__construct_at_end(move_iterator<pointer>(__begin_),
                                    move_iterator<pointer>(__end_));
@@ -473,7 +459,7 @@
         catch (...)
         {
         }
-#endif  // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_NO_EXCEPTIONS
     }
 }
 
@@ -502,12 +488,10 @@
             _VSTD::swap(__end_cap(), __t.__end_cap());
         }
     }
-    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), __x);
+    __alloc_traits::construct(__alloc(), _VSTD::__to_address(__begin_-1), __x);
     --__begin_;
 }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Tp, class _Allocator>
 void
 __split_buffer<_Tp, _Allocator>::push_front(value_type&& __x)
@@ -533,13 +517,11 @@
             _VSTD::swap(__end_cap(), __t.__end_cap());
         }
     }
-    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1),
+    __alloc_traits::construct(__alloc(), _VSTD::__to_address(__begin_-1),
             _VSTD::move(__x));
     --__begin_;
 }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Tp, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 void
@@ -566,12 +548,10 @@
             _VSTD::swap(__end_cap(), __t.__end_cap());
         }
     }
-    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), __x);
+    __alloc_traits::construct(__alloc(), _VSTD::__to_address(__end_), __x);
     ++__end_;
 }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Tp, class _Allocator>
 void
 __split_buffer<_Tp, _Allocator>::push_back(value_type&& __x)
@@ -597,13 +577,11 @@
             _VSTD::swap(__end_cap(), __t.__end_cap());
         }
     }
-    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_),
+    __alloc_traits::construct(__alloc(), _VSTD::__to_address(__end_),
             _VSTD::move(__x));
     ++__end_;
 }
 
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-
 template <class _Tp, class _Allocator>
 template <class... _Args>
 void
@@ -630,15 +608,11 @@
             _VSTD::swap(__end_cap(), __t.__end_cap());
         }
     }
-    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_),
+    __alloc_traits::construct(__alloc(), _VSTD::__to_address(__end_),
                               _VSTD::forward<_Args>(__args)...);
     ++__end_;
 }
 
-#endif  // _LIBCPP_HAS_NO_VARIADICS
-
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Tp, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 void
@@ -648,7 +622,8 @@
     __x.swap(__y);
 }
 
-
 _LIBCPP_END_NAMESPACE_STD
 
-#endif  // _LIBCPP_SPLIT_BUFFER
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP_SPLIT_BUFFER
diff --git a/include/__sso_allocator b/include/__sso_allocator
deleted file mode 100644
index 645f2ba..0000000
--- a/include/__sso_allocator
+++ /dev/null
@@ -1,77 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___SSO_ALLOCATOR
-#define _LIBCPP___SSO_ALLOCATOR
-
-#include <__config>
-#include <type_traits>
-#include <new>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Tp, size_t _Np> class _LIBCPP_HIDDEN __sso_allocator;
-
-template <size_t _Np>
-class _LIBCPP_HIDDEN __sso_allocator<void, _Np>
-{
-public:
-    typedef const void*       const_pointer;
-    typedef void              value_type;
-};
-
-template <class _Tp, size_t _Np>
-class _LIBCPP_HIDDEN __sso_allocator
-{
-    typename aligned_storage<sizeof(_Tp) * _Np>::type buf_;
-    bool __allocated_;
-public:
-    typedef size_t            size_type;
-    typedef _Tp*              pointer;
-    typedef _Tp               value_type;
-
-    _LIBCPP_INLINE_VISIBILITY __sso_allocator() throw() : __allocated_(false) {}
-    _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator&) throw() : __allocated_(false) {}
-    template <class _Up> _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator<_Up, _Np>&) throw()
-         : __allocated_(false) {}
-private:
-    __sso_allocator& operator=(const __sso_allocator&);
-public:
-    _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, typename __sso_allocator<void, _Np>::const_pointer = 0)
-    {
-        if (!__allocated_ && __n <= _Np)
-        {
-            __allocated_ = true;
-            return (pointer)&buf_;
-        }
-        return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));
-    }
-    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type)
-    {
-        if (__p == (pointer)&buf_)
-            __allocated_ = false;
-        else
-            _VSTD::__deallocate(__p);
-    }
-    _LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}
-
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator==(__sso_allocator& __a) const {return &buf_ == &__a.buf_;}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator!=(__sso_allocator& __a) const {return &buf_ != &__a.buf_;}
-};
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif  // _LIBCPP___SSO_ALLOCATOR
diff --git a/include/__std_stream b/include/__std_stream
index 5403ada..65e90b7 100644
--- a/include/__std_stream
+++ b/include/__std_stream
@@ -1,10 +1,9 @@
 // -*- 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.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,17 +11,19 @@
 #define _LIBCPP___STD_STREAM
 
 #include <__config>
-#include <ostream>
-#include <istream>
 #include <__locale>
 #include <cstdio>
-
-#include <__undef_min_max>
+#include <istream>
+#include <ostream>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 static const int __limit = 8;
@@ -276,7 +277,6 @@
             codecvt_base::result __r;
             char_type* pbase = &__1buf;
             char_type* pptr = pbase + 1;
-            char_type* epptr = pptr;
             do
             {
                 const char_type* __e;
@@ -298,7 +298,7 @@
                         return traits_type::eof();
                     if (__r == codecvt_base::partial)
                     {
-                        pbase = (char_type*)__e;
+                        pbase = const_cast<char_type*>(__e);
                     }
                 }
                 else
@@ -356,4 +356,6 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif  // _LIBCPP___STD_STREAM
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___STD_STREAM
diff --git a/include/__string b/include/__string
new file mode 100644
index 0000000..b77a7fb
--- /dev/null
+++ b/include/__string
@@ -0,0 +1,1146 @@
+// -*- C++ -*-
+//===-------------------------- __string ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___STRING
+#define _LIBCPP___STRING
+
+#include <__config>
+#include <__algorithm/copy.h>
+#include <__algorithm/copy_backward.h>
+#include <__algorithm/copy_n.h>
+#include <__algorithm/fill_n.h>
+#include <__algorithm/find_first_of.h>
+#include <__algorithm/find_end.h>
+#include <__algorithm/min.h>
+#include <__functional/hash.h>     // for __murmur2_or_cityhash
+#include <__iterator/iterator_traits.h>
+#include <cstdio>      // for EOF
+#include <cstdint>     // for uint_least16_t
+#include <cstring>     // for memcpy
+#include <cwchar>      // for wmemcpy
+#include <type_traits> // for __libcpp_is_constant_evaluated
+
+#include <__debug>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// The the extern template ABI lists are kept outside of <string> to improve the
+// readability of that header.
+
+// The extern template ABI lists are kept outside of <string> to improve the
+// readability of that header. We maintain 2 ABI lists:
+// - _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST
+// - _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST
+// As the name implies, the ABI lists define the V1 (Stable) and unstable ABI.
+//
+// For unstable, we may explicitly remove function that are external in V1,
+// and add (new) external functions to better control inlining and compiler
+// optimization opportunities.
+//
+// For stable, the ABI list should rarely change, except for adding new
+// functions supporting new c++ version / API changes. Typically entries
+// must never be removed from the stable list.
+#define _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, allocator<_CharType> const&)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
+  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
+  _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
+
+#define _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*)) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
+  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
+  _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
+  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
+
+
+// char_traits
+
+template <class _CharT>
+struct _LIBCPP_TEMPLATE_VIS char_traits
+{
+    typedef _CharT    char_type;
+    typedef int       int_type;
+    typedef streamoff off_type;
+    typedef streampos pos_type;
+    typedef mbstate_t state_type;
+
+    static inline void _LIBCPP_CONSTEXPR_AFTER_CXX14
+        assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
+    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 < __c2;}
+
+    static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    int compare(const char_type* __s1, const char_type* __s2, size_t __n);
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    size_t length(const char_type* __s);
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
+    static _LIBCPP_CONSTEXPR_AFTER_CXX17
+    char_type*       move(char_type* __s1, const char_type* __s2, size_t __n);
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR_AFTER_CXX17
+    char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR_AFTER_CXX17
+    char_type*       assign(char_type* __s, size_t __n, char_type __a);
+
+    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+        {return char_type(__c);}
+    static inline _LIBCPP_CONSTEXPR int_type  to_int_type(char_type __c) _NOEXCEPT
+        {return int_type(__c);}
+    static inline _LIBCPP_CONSTEXPR bool      eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    static inline _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
+        {return int_type(EOF);}
+};
+
+template <class _CharT>
+_LIBCPP_CONSTEXPR_AFTER_CXX14 int
+char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
+{
+    for (; __n; --__n, ++__s1, ++__s2)
+    {
+        if (lt(*__s1, *__s2))
+            return -1;
+        if (lt(*__s2, *__s1))
+            return 1;
+    }
+    return 0;
+}
+
+template <class _CharT>
+inline
+_LIBCPP_CONSTEXPR_AFTER_CXX14 size_t
+char_traits<_CharT>::length(const char_type* __s)
+{
+    size_t __len = 0;
+    for (; !eq(*__s, char_type(0)); ++__s)
+        ++__len;
+    return __len;
+}
+
+template <class _CharT>
+inline
+_LIBCPP_CONSTEXPR_AFTER_CXX14 const _CharT*
+char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
+{
+    for (; __n; --__n)
+    {
+        if (eq(*__s, __a))
+            return __s;
+        ++__s;
+    }
+    return nullptr;
+}
+
+template <class _CharT>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _CharT*
+char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
+{
+    if (__n == 0) return __s1;
+    char_type* __r = __s1;
+    if (__s1 < __s2)
+    {
+        for (; __n; --__n, ++__s1, ++__s2)
+            assign(*__s1, *__s2);
+    }
+    else if (__s2 < __s1)
+    {
+        __s1 += __n;
+        __s2 += __n;
+        for (; __n; --__n)
+            assign(*--__s1, *--__s2);
+    }
+    return __r;
+}
+
+template <class _CharT>
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+_CharT*
+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");
+    char_type* __r = __s1;
+    for (; __n; --__n, ++__s1, ++__s2)
+        assign(*__s1, *__s2);
+    return __r;
+}
+
+template <class _CharT>
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+_CharT*
+char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
+{
+    char_type* __r = __s;
+    for (; __n; --__n, ++__s)
+        assign(*__s, __a);
+    return __r;
+}
+
+// constexpr versions of move/copy/assign.
+
+template <class _CharT>
+static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+_CharT* __move_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
+{
+    if (__n == 0) return __s1;
+    if (__s1 < __s2) {
+      _VSTD::copy(__s2, __s2 + __n, __s1);
+    } else if (__s2 < __s1) {
+      _VSTD::copy_backward(__s2, __s2 + __n, __s1 + __n);
+    }
+    return __s1;
+}
+
+template <class _CharT>
+static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+_CharT* __copy_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
+{
+    _VSTD::copy_n(__s2, __n, __s1);
+    return __s1;
+}
+
+template <class _CharT>
+static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+_CharT* __assign_constexpr(_CharT* __s, size_t __n, _CharT __a) _NOEXCEPT
+{
+     _VSTD::fill_n(__s, __n, __a);
+     return __s;
+}
+
+// char_traits<char>
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS char_traits<char>
+{
+    typedef char      char_type;
+    typedef int       int_type;
+    typedef streamoff off_type;
+    typedef streampos pos_type;
+    typedef mbstate_t state_type;
+
+    static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+    void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
+    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+            {return __c1 == __c2;}
+    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+        {return (unsigned char)__c1 < (unsigned char)__c2;}
+
+    static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+    static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14
+    length(const char_type* __s)  _NOEXCEPT {return __builtin_strlen(__s);}
+    static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
+    static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+    char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+        {
+            return __libcpp_is_constant_evaluated()
+                       ? _VSTD::__move_constexpr(__s1, __s2, __n)
+                       : __n == 0 ? __s1 : (char_type*)_VSTD::memmove(__s1, __s2, __n);
+        }
+    static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+    char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+            return __libcpp_is_constant_evaluated()
+                       ? _VSTD::__copy_constexpr(__s1, __s2, __n)
+                       : __n == 0 ? __s1 : (char_type*)_VSTD::memcpy(__s1, __s2, __n);
+        }
+    static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+    char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
+        {
+            return __libcpp_is_constant_evaluated()
+                       ? _VSTD::__assign_constexpr(__s, __n, __a)
+                       : __n == 0 ? __s : (char_type*)_VSTD::memset(__s, to_int_type(__a), __n);
+        }
+
+    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+        {return char_type(__c);}
+    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+        {return int_type((unsigned char)__c);}
+    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    static inline _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
+        {return int_type(EOF);}
+};
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+int
+char_traits<char>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+{
+    if (__n == 0)
+        return 0;
+#if __has_feature(cxx_constexpr_string_builtins)
+    return __builtin_memcmp(__s1, __s2, __n);
+#elif _LIBCPP_STD_VER <= 14
+    return _VSTD::memcmp(__s1, __s2, __n);
+#else
+    for (; __n; --__n, ++__s1, ++__s2)
+    {
+        if (lt(*__s1, *__s2))
+            return -1;
+        if (lt(*__s2, *__s1))
+            return 1;
+    }
+    return 0;
+#endif
+}
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+const char*
+char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
+{
+    if (__n == 0)
+        return nullptr;
+#if __has_feature(cxx_constexpr_string_builtins)
+    return __builtin_char_memchr(__s, to_int_type(__a), __n);
+#elif _LIBCPP_STD_VER <= 14
+    return (const char_type*) _VSTD::memchr(__s, to_int_type(__a), __n);
+#else
+    for (; __n; --__n)
+    {
+        if (eq(*__s, __a))
+            return __s;
+        ++__s;
+    }
+    return nullptr;
+#endif
+}
+
+
+// char_traits<wchar_t>
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
+{
+    typedef wchar_t   char_type;
+    typedef wint_t    int_type;
+    typedef streamoff off_type;
+    typedef streampos pos_type;
+    typedef mbstate_t state_type;
+
+    static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+    void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
+    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 < __c2;}
+
+    static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+    static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    size_t length(const char_type* __s) _NOEXCEPT;
+    static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
+    static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+    char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+        {
+            return __libcpp_is_constant_evaluated()
+                       ? _VSTD::__move_constexpr(__s1, __s2, __n)
+                       : __n == 0 ? __s1 : _VSTD::wmemmove(__s1, __s2, __n);
+        }
+    static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+    char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+            return __libcpp_is_constant_evaluated()
+                       ? _VSTD::__copy_constexpr(__s1, __s2, __n)
+                       : __n == 0 ? __s1 : _VSTD::wmemcpy(__s1, __s2, __n);
+        }
+    static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+    char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
+        {
+            return __libcpp_is_constant_evaluated()
+                       ? _VSTD::__assign_constexpr(__s, __n, __a)
+                       : __n == 0 ? __s : _VSTD::wmemset(__s, __a, __n);
+        }
+    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+        {return char_type(__c);}
+    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+        {return int_type(__c);}
+    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
+        {return int_type(WEOF);}
+};
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+int
+char_traits<wchar_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+{
+    if (__n == 0)
+        return 0;
+#if __has_feature(cxx_constexpr_string_builtins)
+    return __builtin_wmemcmp(__s1, __s2, __n);
+#elif _LIBCPP_STD_VER <= 14
+    return _VSTD::wmemcmp(__s1, __s2, __n);
+#else
+    for (; __n; --__n, ++__s1, ++__s2)
+    {
+        if (lt(*__s1, *__s2))
+            return -1;
+        if (lt(*__s2, *__s1))
+            return 1;
+    }
+    return 0;
+#endif
+}
+
+
+template <class _Traits>
+_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {
+#if _LIBCPP_DEBUG_LEVEL >= 1
+  return __s ? _Traits::length(__s) : (_VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, "p == nullptr", "null pointer pass to non-null argument of char_traits<...>::length")), 0);
+#else
+  return _Traits::length(__s);
+#endif
+}
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+size_t
+char_traits<wchar_t>::length(const char_type* __s) _NOEXCEPT
+{
+#if __has_feature(cxx_constexpr_string_builtins)
+    return __builtin_wcslen(__s);
+#elif _LIBCPP_STD_VER <= 14
+    return _VSTD::wcslen(__s);
+#else
+    size_t __len = 0;
+    for (; !eq(*__s, char_type(0)); ++__s)
+        ++__len;
+    return __len;
+#endif
+}
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+const wchar_t*
+char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
+{
+    if (__n == 0)
+        return nullptr;
+#if __has_feature(cxx_constexpr_string_builtins)
+    return __builtin_wmemchr(__s, __a, __n);
+#elif _LIBCPP_STD_VER <= 14
+    return _VSTD::wmemchr(__s, __a, __n);
+#else
+    for (; __n; --__n)
+    {
+        if (eq(*__s, __a))
+            return __s;
+        ++__s;
+    }
+    return nullptr;
+#endif
+}
+
+
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
+{
+    typedef char8_t        char_type;
+    typedef unsigned int   int_type;
+    typedef streamoff      off_type;
+    typedef u8streampos    pos_type;
+    typedef mbstate_t      state_type;
+
+    static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
+        {__c1 = __c2;}
+    static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
+        {return __c1 == __c2;}
+    static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
+        {return __c1 < __c2;}
+
+    static constexpr
+    int              compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+
+    static constexpr
+    size_t           length(const char_type* __s) _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY static constexpr
+    const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
+
+    static _LIBCPP_CONSTEXPR_AFTER_CXX17
+    char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+        {
+            return __libcpp_is_constant_evaluated()
+                       ? _VSTD::__move_constexpr(__s1, __s2, __n)
+                       : __n == 0 ? __s1 : (char_type*)_VSTD::memmove(__s1, __s2, __n);
+        }
+
+    static _LIBCPP_CONSTEXPR_AFTER_CXX17
+    char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+       {
+            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+            return __libcpp_is_constant_evaluated()
+                       ? _VSTD::__copy_constexpr(__s1, __s2, __n)
+                       : __n == 0 ? __s1 : (char_type*)_VSTD::memcpy(__s1, __s2, __n);
+        }
+
+    static _LIBCPP_CONSTEXPR_AFTER_CXX17
+    char_type*       assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
+        {
+            return __libcpp_is_constant_evaluated()
+                       ? _VSTD::__assign_constexpr(__s, __n, __a)
+                       : __n == 0 ? __s : (char_type*)_VSTD::memset(__s, to_int_type(__a), __n);
+        }
+
+    static inline constexpr int_type  not_eof(int_type __c) noexcept
+        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+    static inline constexpr char_type to_char_type(int_type __c) noexcept
+        {return char_type(__c);}
+    static inline constexpr int_type to_int_type(char_type __c) noexcept
+        {return int_type(__c);}
+    static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
+        {return __c1 == __c2;}
+    static inline constexpr int_type eof() noexcept
+        {return int_type(EOF);}
+};
+
+// TODO use '__builtin_strlen' if it ever supports char8_t ??
+inline constexpr
+size_t
+char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
+{
+    size_t __len = 0;
+    for (; !eq(*__s, char_type(0)); ++__s)
+        ++__len;
+    return __len;
+}
+
+inline constexpr
+int
+char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+{
+#if __has_feature(cxx_constexpr_string_builtins)
+    return __builtin_memcmp(__s1, __s2, __n);
+#else
+    for (; __n; --__n, ++__s1, ++__s2)
+    {
+        if (lt(*__s1, *__s2))
+            return -1;
+        if (lt(*__s2, *__s1))
+            return 1;
+    }
+    return 0;
+#endif
+}
+
+// TODO use '__builtin_char_memchr' if it ever supports char8_t ??
+inline constexpr
+const char8_t*
+char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
+{
+    for (; __n; --__n)
+    {
+        if (eq(*__s, __a))
+            return __s;
+        ++__s;
+    }
+    return nullptr;
+}
+
+#endif // #_LIBCPP_HAS_NO_CHAR8_T
+
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
+{
+    typedef char16_t       char_type;
+    typedef uint_least16_t int_type;
+    typedef streamoff      off_type;
+    typedef u16streampos   pos_type;
+    typedef mbstate_t      state_type;
+
+    static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+    void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
+    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 < __c2;}
+
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    int              compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    size_t           length(const char_type* __s) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static char_type*       assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
+
+    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+        {return char_type(__c);}
+    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+        {return int_type(__c);}
+    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
+        {return int_type(0xFFFF);}
+};
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+int
+char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+{
+    for (; __n; --__n, ++__s1, ++__s2)
+    {
+        if (lt(*__s1, *__s2))
+            return -1;
+        if (lt(*__s2, *__s1))
+            return 1;
+    }
+    return 0;
+}
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+size_t
+char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
+{
+    size_t __len = 0;
+    for (; !eq(*__s, char_type(0)); ++__s)
+        ++__len;
+    return __len;
+}
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+const char16_t*
+char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
+{
+    for (; __n; --__n)
+    {
+        if (eq(*__s, __a))
+            return __s;
+        ++__s;
+    }
+    return nullptr;
+}
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+char16_t*
+char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+{
+    if (__n == 0) return __s1;
+    char_type* __r = __s1;
+    if (__s1 < __s2)
+    {
+        for (; __n; --__n, ++__s1, ++__s2)
+            assign(*__s1, *__s2);
+    }
+    else if (__s2 < __s1)
+    {
+        __s1 += __n;
+        __s2 += __n;
+        for (; __n; --__n)
+            assign(*--__s1, *--__s2);
+    }
+    return __r;
+}
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+char16_t*
+char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+    char_type* __r = __s1;
+    for (; __n; --__n, ++__s1, ++__s2)
+        assign(*__s1, *__s2);
+    return __r;
+}
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+char16_t*
+char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
+{
+    char_type* __r = __s;
+    for (; __n; --__n, ++__s)
+        assign(*__s, __a);
+    return __r;
+}
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
+{
+    typedef char32_t       char_type;
+    typedef uint_least32_t int_type;
+    typedef streamoff      off_type;
+    typedef u32streampos   pos_type;
+    typedef mbstate_t      state_type;
+
+    static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+    void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
+    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 < __c2;}
+
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    int              compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    size_t           length(const char_type* __s) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    static char_type*       assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
+
+    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+        {return char_type(__c);}
+    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+        {return int_type(__c);}
+    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
+        {return int_type(0xFFFFFFFF);}
+};
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+int
+char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+{
+    for (; __n; --__n, ++__s1, ++__s2)
+    {
+        if (lt(*__s1, *__s2))
+            return -1;
+        if (lt(*__s2, *__s1))
+            return 1;
+    }
+    return 0;
+}
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+size_t
+char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
+{
+    size_t __len = 0;
+    for (; !eq(*__s, char_type(0)); ++__s)
+        ++__len;
+    return __len;
+}
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX14
+const char32_t*
+char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
+{
+    for (; __n; --__n)
+    {
+        if (eq(*__s, __a))
+            return __s;
+        ++__s;
+    }
+    return nullptr;
+}
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+char32_t*
+char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+{
+    if (__n == 0) return __s1;
+    char_type* __r = __s1;
+    if (__s1 < __s2)
+    {
+        for (; __n; --__n, ++__s1, ++__s2)
+            assign(*__s1, *__s2);
+    }
+    else if (__s2 < __s1)
+    {
+        __s1 += __n;
+        __s2 += __n;
+        for (; __n; --__n)
+            assign(*--__s1, *--__s2);
+    }
+    return __r;
+}
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+char32_t*
+char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+    char_type* __r = __s1;
+    for (; __n; --__n, ++__s1, ++__s2)
+        assign(*__s1, *__s2);
+    return __r;
+}
+
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+char32_t*
+char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
+{
+    char_type* __r = __s;
+    for (; __n; --__n, ++__s)
+        assign(*__s, __a);
+    return __r;
+}
+
+#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
+
+// helper fns for basic_string and string_view
+
+// __str_find
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_find(const _CharT *__p, _SizeT __sz,
+             _CharT __c, _SizeT __pos) _NOEXCEPT
+{
+    if (__pos >= __sz)
+        return __npos;
+    const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
+    if (__r == nullptr)
+        return __npos;
+    return static_cast<_SizeT>(__r - __p);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT *
+__search_substring(const _CharT *__first1, const _CharT *__last1,
+                   const _CharT *__first2, const _CharT *__last2) _NOEXCEPT {
+  // Take advantage of knowing source and pattern lengths.
+  // Stop short when source is smaller than pattern.
+  const ptrdiff_t __len2 = __last2 - __first2;
+  if (__len2 == 0)
+    return __first1;
+
+  ptrdiff_t __len1 = __last1 - __first1;
+  if (__len1 < __len2)
+    return __last1;
+
+  // First element of __first2 is loop invariant.
+  _CharT __f2 = *__first2;
+  while (true) {
+    __len1 = __last1 - __first1;
+    // Check whether __first1 still has at least __len2 bytes.
+    if (__len1 < __len2)
+      return __last1;
+
+    // Find __f2 the first byte matching in __first1.
+    __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
+    if (__first1 == nullptr)
+      return __last1;
+
+    // It is faster to compare from the first byte of __first1 even if we
+    // already know that it matches the first byte of __first2: this is because
+    // __first2 is most likely aligned, as it is user's "pattern" string, and
+    // __first1 + 1 is most likely not aligned, as the match is in the middle of
+    // the string.
+    if (_Traits::compare(__first1, __first2, __len2) == 0)
+      return __first1;
+
+    ++__first1;
+  }
+}
+
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_find(const _CharT *__p, _SizeT __sz,
+       const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
+{
+    if (__pos > __sz)
+        return __npos;
+
+    if (__n == 0) // There is nothing to search, just return __pos.
+        return __pos;
+
+    const _CharT *__r = __search_substring<_CharT, _Traits>(
+        __p + __pos, __p + __sz, __s, __s + __n);
+
+    if (__r == __p + __sz)
+        return __npos;
+    return static_cast<_SizeT>(__r - __p);
+}
+
+
+// __str_rfind
+
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_rfind(const _CharT *__p, _SizeT __sz,
+              _CharT __c, _SizeT __pos) _NOEXCEPT
+{
+    if (__sz < 1)
+        return __npos;
+    if (__pos < __sz)
+        ++__pos;
+    else
+        __pos = __sz;
+    for (const _CharT* __ps = __p + __pos; __ps != __p;)
+    {
+        if (_Traits::eq(*--__ps, __c))
+            return static_cast<_SizeT>(__ps - __p);
+    }
+    return __npos;
+}
+
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_rfind(const _CharT *__p, _SizeT __sz,
+        const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
+{
+    __pos = _VSTD::min(__pos, __sz);
+    if (__n < __sz - __pos)
+        __pos += __n;
+    else
+        __pos = __sz;
+    const _CharT* __r = _VSTD::__find_end(
+                  __p, __p + __pos, __s, __s + __n, _Traits::eq,
+                        random_access_iterator_tag(), random_access_iterator_tag());
+    if (__n > 0 && __r == __p + __pos)
+        return __npos;
+    return static_cast<_SizeT>(__r - __p);
+}
+
+// __str_find_first_of
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+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
+{
+    if (__pos >= __sz || __n == 0)
+        return __npos;
+    const _CharT* __r = _VSTD::__find_first_of_ce
+        (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
+    if (__r == __p + __sz)
+        return __npos;
+    return static_cast<_SizeT>(__r - __p);
+}
+
+
+// __str_find_last_of
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+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
+    {
+    if (__n != 0)
+    {
+        if (__pos < __sz)
+            ++__pos;
+        else
+            __pos = __sz;
+        for (const _CharT* __ps = __p + __pos; __ps != __p;)
+        {
+            const _CharT* __r = _Traits::find(__s, __n, *--__ps);
+            if (__r)
+                return static_cast<_SizeT>(__ps - __p);
+        }
+    }
+    return __npos;
+}
+
+
+// __str_find_first_not_of
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+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
+{
+    if (__pos < __sz)
+    {
+        const _CharT* __pe = __p + __sz;
+        for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
+            if (_Traits::find(__s, __n, *__ps) == nullptr)
+                return static_cast<_SizeT>(__ps - __p);
+    }
+    return __npos;
+}
+
+
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
+                          _CharT __c, _SizeT __pos) _NOEXCEPT
+{
+    if (__pos < __sz)
+    {
+        const _CharT* __pe = __p + __sz;
+        for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
+            if (!_Traits::eq(*__ps, __c))
+                return static_cast<_SizeT>(__ps - __p);
+    }
+    return __npos;
+}
+
+
+// __str_find_last_not_of
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+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
+{
+    if (__pos < __sz)
+        ++__pos;
+    else
+        __pos = __sz;
+    for (const _CharT* __ps = __p + __pos; __ps != __p;)
+        if (_Traits::find(__s, __n, *--__ps) == nullptr)
+            return static_cast<_SizeT>(__ps - __p);
+    return __npos;
+}
+
+
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
+                         _CharT __c, _SizeT __pos) _NOEXCEPT
+{
+    if (__pos < __sz)
+        ++__pos;
+    else
+        __pos = __sz;
+    for (const _CharT* __ps = __p + __pos; __ps != __p;)
+        if (!_Traits::eq(*--__ps, __c))
+            return static_cast<_SizeT>(__ps - __p);
+    return __npos;
+}
+
+template<class _Ptr>
+inline _LIBCPP_INLINE_VISIBILITY
+size_t __do_string_hash(_Ptr __p, _Ptr __e)
+{
+    typedef typename iterator_traits<_Ptr>::value_type value_type;
+    return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
+}
+
+template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
+struct __quoted_output_proxy
+{
+    _Iter  __first;
+    _Iter  __last;
+    _CharT  __delim;
+    _CharT  __escape;
+
+    __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
+    : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
+    //  This would be a nice place for a string_ref
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___STRING
diff --git a/include/__support/android/locale_bionic.h b/include/__support/android/locale_bionic.h
new file mode 100644
index 0000000..8c6d4bd
--- /dev/null
+++ b/include/__support/android/locale_bionic.h
@@ -0,0 +1,69 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H
+#define _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H
+
+#if defined(__BIONIC__)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <xlocale.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(__ANDROID__)
+
+#include <android/api-level.h>
+#include <android/ndk-version.h>
+#if __ANDROID_API__ < 21
+#include <__support/xlocale/__posix_l_fallback.h>
+#endif
+// In NDK versions later than 16, locale-aware functions are provided by
+// legacy_stdlib_inlines.h
+#if __NDK_MAJOR__ <= 16
+#if __ANDROID_API__ < 21
+#include <__support/xlocale/__strtonum_fallback.h>
+#elif __ANDROID_API__ < 26
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+inline _LIBCPP_INLINE_VISIBILITY float strtof_l(const char* __nptr, char** __endptr,
+                                                locale_t) {
+  return ::strtof(__nptr, __endptr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY double strtod_l(const char* __nptr,
+                                                 char** __endptr, locale_t) {
+  return ::strtod(__nptr, __endptr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY long strtol_l(const char* __nptr, char** __endptr,
+                                               int __base, locale_t) {
+  return ::strtol(__nptr, __endptr, __base);
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // __ANDROID_API__ < 26
+
+#endif // __NDK_MAJOR__ <= 16
+#endif // defined(__ANDROID__)
+
+#endif // defined(__BIONIC__)
+#endif // _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H
diff --git a/include/__support/fuchsia/xlocale.h b/include/__support/fuchsia/xlocale.h
new file mode 100644
index 0000000..e8def81
--- /dev/null
+++ b/include/__support/fuchsia/xlocale.h
@@ -0,0 +1,22 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_FUCHSIA_XLOCALE_H
+#define _LIBCPP_SUPPORT_FUCHSIA_XLOCALE_H
+
+#if defined(__Fuchsia__)
+
+#include <cstdlib>
+#include <cwchar>
+#include <__support/xlocale/__posix_l_fallback.h>
+#include <__support/xlocale/__strtonum_fallback.h>
+
+#endif // defined(__Fuchsia__)
+
+#endif // _LIBCPP_SUPPORT_FUCHSIA_XLOCALE_H
diff --git a/include/__support/ibm/gettod_zos.h b/include/__support/ibm/gettod_zos.h
new file mode 100644
index 0000000..46e02a6
--- /dev/null
+++ b/include/__support/ibm/gettod_zos.h
@@ -0,0 +1,53 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_IBM_GETTOD_ZOS_H
+#define _LIBCPP_SUPPORT_IBM_GETTOD_ZOS_H
+
+#include <time.h>
+
+static inline int gettimeofdayMonotonic(struct timespec64* Output) {
+
+  // The POSIX gettimeofday() function is not available on z/OS. Therefore,
+  // we will call stcke and other hardware instructions in implement equivalent.
+  // Note that nanoseconds alone will overflow when reaching new epoch in 2042.
+
+  struct _t {
+    uint64_t Hi;
+    uint64_t Lo;
+  };
+  struct _t Value = {0, 0};
+  uint64_t CC = 0;
+  asm(" stcke %0\n"
+      " ipm %1\n"
+      " srlg %1,%1,28\n"
+      : "=m"(Value), "+r"(CC)::);
+
+  if (CC != 0) {
+    errno = EMVSTODNOTSET;
+    return CC;
+  }
+  uint64_t us = (Value.Hi >> 4);
+  uint64_t ns = ((Value.Hi & 0x0F) << 8) + (Value.Lo >> 56);
+  ns = (ns * 1000) >> 12;
+  us = us - 2208988800000000;
+
+  register uint64_t DivPair0 asm("r0"); // dividend (upper half), remainder
+  DivPair0 = 0;
+  register uint64_t DivPair1 asm("r1"); // dividend (lower half), quotient
+  DivPair1 = us;
+  uint64_t Divisor = 1000000;
+  asm(" dlgr %0,%2" : "+r"(DivPair0), "+r"(DivPair1) : "r"(Divisor) :);
+
+  Output->tv_sec = DivPair1;
+  Output->tv_nsec = DivPair0 * 1000 + ns;
+  return 0;
+}
+
+#endif // _LIBCPP_SUPPORT_IBM_GETTOD_ZOS_H
diff --git a/include/__support/ibm/limits.h b/include/__support/ibm/limits.h
new file mode 100644
index 0000000..45f1f1e
--- /dev/null
+++ b/include/__support/ibm/limits.h
@@ -0,0 +1,98 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_IBM_LIMITS_H
+#define _LIBCPP_SUPPORT_IBM_LIMITS_H
+
+#if !defined(_AIX) // Linux
+#include <math.h> // for HUGE_VAL, HUGE_VALF, HUGE_VALL, and NAN
+
+static const unsigned int _QNAN_F = 0x7fc00000;
+#define NANF (*((float *)(&_QNAN_F)))
+static const unsigned int _QNAN_LDBL128[4] = {0x7ff80000, 0x0, 0x0, 0x0};
+#define NANL (*((long double *)(&_QNAN_LDBL128)))
+static const unsigned int _SNAN_F= 0x7f855555;
+#define NANSF (*((float *)(&_SNAN_F)))
+static const unsigned int _SNAN_D[2] = {0x7ff55555, 0x55555555};
+#define NANS (*((double *)(&_SNAN_D)))
+static const unsigned int _SNAN_LDBL128[4] = {0x7ff55555, 0x55555555, 0x0, 0x0};
+#define NANSL (*((long double *)(&_SNAN_LDBL128)))
+
+#define __builtin_huge_val()     HUGE_VAL
+#define __builtin_huge_valf()    HUGE_VALF
+#define __builtin_huge_vall()    HUGE_VALL
+#define __builtin_nan(__dummy)   NAN
+#define __builtin_nanf(__dummy)  NANF
+#define __builtin_nanl(__dummy)  NANL
+#define __builtin_nans(__dummy)  NANS
+#define __builtin_nansf(__dummy) NANSF
+#define __builtin_nansl(__dummy) NANSL
+
+#else
+
+#include <math.h>
+#include <float.h> // limit constants
+
+#define __builtin_huge_val()     HUGE_VAL  //0x7ff0000000000000
+#define __builtin_huge_valf()    HUGE_VALF //0x7f800000
+#define __builtin_huge_vall()    HUGE_VALL //0x7ff0000000000000
+#define __builtin_nan(__dummy)   nan(__dummy) //0x7ff8000000000000
+#define __builtin_nanf(__dummy)  nanf(__dummy) // 0x7ff80000
+#define __builtin_nanl(__dummy)  nanl(__dummy) //0x7ff8000000000000
+#define __builtin_nans(__dummy)  DBL_SNAN //0x7ff5555555555555
+#define __builtin_nansf(__dummy) FLT_SNAN //0x7f855555
+#define __builtin_nansl(__dummy) DBL_SNAN //0x7ff5555555555555
+
+#define __FLT_MANT_DIG__   FLT_MANT_DIG
+#define __FLT_DIG__        FLT_DIG
+#define __FLT_RADIX__      FLT_RADIX
+#define __FLT_MIN_EXP__    FLT_MIN_EXP
+#define __FLT_MIN_10_EXP__ FLT_MIN_10_EXP
+#define __FLT_MAX_EXP__    FLT_MAX_EXP
+#define __FLT_MAX_10_EXP__ FLT_MAX_10_EXP
+#define __FLT_MIN__        FLT_MIN
+#define __FLT_MAX__        FLT_MAX
+#define __FLT_EPSILON__    FLT_EPSILON
+// predefined by XLC on LoP
+#define __FLT_DENORM_MIN__ 1.40129846e-45F
+
+#define __DBL_MANT_DIG__   DBL_MANT_DIG
+#define __DBL_DIG__        DBL_DIG
+#define __DBL_MIN_EXP__    DBL_MIN_EXP
+#define __DBL_MIN_10_EXP__ DBL_MIN_10_EXP
+#define __DBL_MAX_EXP__    DBL_MAX_EXP
+#define __DBL_MAX_10_EXP__ DBL_MAX_10_EXP
+#define __DBL_MIN__        DBL_MIN
+#define __DBL_MAX__        DBL_MAX
+#define __DBL_EPSILON__    DBL_EPSILON
+// predefined by XLC on LoP
+#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+
+#define __LDBL_MANT_DIG__   LDBL_MANT_DIG
+#define __LDBL_DIG__        LDBL_DIG
+#define __LDBL_MIN_EXP__    LDBL_MIN_EXP
+#define __LDBL_MIN_10_EXP__ LDBL_MIN_10_EXP
+#define __LDBL_MAX_EXP__    LDBL_MAX_EXP
+#define __LDBL_MAX_10_EXP__ LDBL_MAX_10_EXP
+#define __LDBL_MIN__        LDBL_MIN
+#define __LDBL_MAX__        LDBL_MAX
+#define __LDBL_EPSILON__    LDBL_EPSILON
+// predefined by XLC on LoP
+#if __LONGDOUBLE128
+#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
+#else
+#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
+#endif
+
+// predefined by XLC on LoP
+#define __CHAR_BIT__    8
+
+#endif // _AIX
+
+#endif // _LIBCPP_SUPPORT_IBM_LIMITS_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..4f658c3
--- /dev/null
+++ b/include/__support/ibm/locale_mgmt_aix.h
@@ -0,0 +1,84 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#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/locale_mgmt_zos.h b/include/__support/ibm/locale_mgmt_zos.h
new file mode 100644
index 0000000..90ad2c2
--- /dev/null
+++ b/include/__support/ibm/locale_mgmt_zos.h
@@ -0,0 +1,53 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_IBM_LOCALE_MGMT_ZOS_H
+#define _LIBCPP_SUPPORT_IBM_LOCALE_MGMT_ZOS_H
+
+#if defined(__MVS__)
+#include <locale.h>
+#include <string>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _LC_MAX           LC_MESSAGES          /* highest real category */
+#define _NCAT             (_LC_MAX + 1)        /* maximum + 1 */
+
+#define _CATMASK(n)       (1 << (n))
+#define LC_COLLATE_MASK   _CATMASK(LC_COLLATE)
+#define LC_CTYPE_MASK     _CATMASK(LC_CTYPE)
+#define LC_MONETARY_MASK  _CATMASK(LC_MONETARY)
+#define LC_NUMERIC_MASK   _CATMASK(LC_NUMERIC)
+#define LC_TIME_MASK      _CATMASK(LC_TIME)
+#define LC_MESSAGES_MASK  _CATMASK(LC_MESSAGES)
+#define LC_ALL_MASK       (_CATMASK(_NCAT) - 1)
+
+typedef struct locale_struct {
+  int category_mask;
+  std::string lc_collate;
+  std::string lc_ctype;
+  std::string lc_monetary;
+  std::string lc_numeric;
+  std::string lc_time;
+  std::string lc_messages;
+} * locale_t;
+
+// z/OS does not have newlocale, freelocale and uselocale.
+// The functions below are workarounds in single thread mode.
+locale_t newlocale(int category_mask, const char* locale, locale_t base);
+void freelocale(locale_t locobj);
+locale_t uselocale(locale_t newloc);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // defined(__MVS__)
+#endif // _LIBCPP_SUPPORT_IBM_LOCALE_MGMT_ZOS_H
diff --git a/include/__support/ibm/nanosleep.h b/include/__support/ibm/nanosleep.h
new file mode 100644
index 0000000..ec6379b
--- /dev/null
+++ b/include/__support/ibm/nanosleep.h
@@ -0,0 +1,56 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_IBM_NANOSLEEP_H
+#define _LIBCPP_SUPPORT_IBM_NANOSLEEP_H
+
+#include <unistd.h>
+
+inline int nanosleep(const struct timespec* __req, struct timespec* __rem) {
+  // The nanosleep() function is not available on z/OS. Therefore, we will call
+  // sleep() to sleep for whole seconds and usleep() to sleep for any remaining
+  // fraction of a second. Any remaining nanoseconds will round up to the next
+  // microsecond.
+  if (__req->tv_sec < 0 || __req->tv_nsec < 0 || __req->tv_nsec > 999999999) {
+    errno = EINVAL;
+    return -1;
+  }
+  useconds_t __micro_sec =
+      static_cast<useconds_t>((__req->tv_nsec + 999) / 1000);
+  time_t __sec = __req->tv_sec;
+  if (__micro_sec > 999999) {
+    ++__sec;
+    __micro_sec -= 1000000;
+  }
+  __sec = sleep(static_cast<unsigned int>(__sec));
+  if (__sec) {
+    if (__rem) {
+      // Updating the remaining time to sleep in case of unsuccessful call to sleep().
+      __rem->tv_sec = __sec;
+      __rem->tv_nsec = __micro_sec * 1000;
+    }
+    errno = EINTR;
+    return -1;
+  }
+  if (__micro_sec) {
+    int __rt = usleep(__micro_sec);
+    if (__rt != 0 && __rem) {
+      // The usleep() does not provide the amount of remaining time upon its failure,
+      // so the time slept will be ignored.
+      __rem->tv_sec = 0;
+      __rem->tv_nsec = __micro_sec * 1000;
+      // The errno is already set.
+      return -1;
+    }
+    return __rt;
+  }
+  return 0;
+}
+
+#endif // _LIBCPP_SUPPORT_IBM_NANOSLEEP_H
diff --git a/include/__support/ibm/support.h b/include/__support/ibm/support.h
new file mode 100644
index 0000000..a7751b0
--- /dev/null
+++ b/include/__support/ibm/support.h
@@ -0,0 +1,53 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_IBM_SUPPORT_H
+#define _LIBCPP_SUPPORT_IBM_SUPPORT_H
+
+extern "builtin" int __popcnt4(unsigned int);
+extern "builtin" int __popcnt8(unsigned long long);
+extern "builtin" unsigned int __cnttz4(unsigned int);
+extern "builtin" unsigned int __cnttz8(unsigned long long);
+extern "builtin" unsigned int __cntlz4(unsigned int);
+extern "builtin" unsigned int __cntlz8(unsigned long long);
+
+// Builtin functions for counting population
+#define __builtin_popcount(x) __popcnt4(x)
+#define __builtin_popcountll(x) __popcnt8(x)
+#if defined(__64BIT__)
+#define __builtin_popcountl(x) __builtin_popcountll(x)
+#else
+#define __builtin_popcountl(x) __builtin_popcount(x)
+#endif
+
+// Builtin functions for counting trailing zeros
+#define __builtin_ctz(x) __cnttz4(x)
+#define __builtin_ctzll(x) __cnttz8(x)
+#if defined(__64BIT__)
+#define __builtin_ctzl(x) __builtin_ctzll(x)
+#else
+#define __builtin_ctzl(x) __builtin_ctz(x)
+#endif
+
+// Builtin functions for counting leading zeros
+#define __builtin_clz(x) __cntlz4(x)
+#define __builtin_clzll(x) __cntlz8(x)
+#if defined(__64BIT__)
+#define __builtin_clzl(x) __builtin_clzll(x)
+#else
+#define __builtin_clzl(x) __builtin_clz(x)
+#endif
+
+#if defined(__64BIT__)
+#define __SIZE_WIDTH__ 64
+#else
+#define __SIZE_WIDTH__ 32
+#endif
+
+#endif // _LIBCPP_SUPPORT_IBM_SUPPORT_H
diff --git a/include/__support/ibm/xlocale.h b/include/__support/ibm/xlocale.h
new file mode 100644
index 0000000..58bdc67
--- /dev/null
+++ b/include/__support/ibm/xlocale.h
@@ -0,0 +1,334 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_IBM_XLOCALE_H
+#define _LIBCPP_SUPPORT_IBM_XLOCALE_H
+
+#include <__support/ibm/locale_mgmt_aix.h>
+#include <__support/ibm/locale_mgmt_zos.h>
+#include <stdarg.h>
+
+#include "cstdlib"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(_AIX)
+#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.
+static inline
+int isalnum_l(int c, locale_t locale)
+{
+  return __xisalnum(locale, c);
+}
+static inline
+int isalpha_l(int c, locale_t locale)
+{
+  return __xisalpha(locale, c);
+}
+static inline
+int isblank_l(int c, locale_t locale)
+{
+  return __xisblank(locale, c);
+}
+static inline
+int iscntrl_l(int c, locale_t locale)
+{
+  return __xiscntrl(locale, c);
+}
+static inline
+int isdigit_l(int c, locale_t locale)
+{
+  return __xisdigit(locale, c);
+}
+static inline
+int isgraph_l(int c, locale_t locale)
+{
+  return __xisgraph(locale, c);
+}
+static inline
+int islower_l(int c, locale_t locale)
+{
+  return __xislower(locale, c);
+}
+static inline
+int isprint_l(int c, locale_t locale)
+{
+  return __xisprint(locale, c);
+}
+
+static inline
+int ispunct_l(int c, locale_t locale)
+{
+  return __xispunct(locale, c);
+}
+static inline
+int isspace_l(int c, locale_t locale)
+{
+  return __xisspace(locale, c);
+}
+static inline
+int isupper_l(int c, locale_t locale)
+{
+  return __xisupper(locale, c);
+}
+
+static inline
+int isxdigit_l(int c, locale_t locale)
+{
+  return __xisxdigit(locale, c);
+}
+
+static inline
+int iswalnum_l(wchar_t wc, locale_t locale)
+{
+  return __xiswalnum(locale, wc);
+}
+
+static inline
+int iswalpha_l(wchar_t wc, locale_t locale)
+{
+  return __xiswalpha(locale, wc);
+}
+
+static inline
+int iswblank_l(wchar_t wc, locale_t locale)
+{
+  return __xiswblank(locale, wc);
+}
+
+static inline
+int iswcntrl_l(wchar_t wc, locale_t locale)
+{
+  return __xiswcntrl(locale, wc);
+}
+
+static inline
+int iswdigit_l(wchar_t wc, locale_t locale)
+{
+  return __xiswdigit(locale, wc);
+}
+
+static inline
+int iswgraph_l(wchar_t wc, locale_t locale)
+{
+  return __xiswgraph(locale, wc);
+}
+
+static inline
+int iswlower_l(wchar_t wc, locale_t locale)
+{
+  return __xiswlower(locale, wc);
+}
+
+static inline
+int iswprint_l(wchar_t wc, locale_t locale)
+{
+  return __xiswprint(locale, wc);
+}
+
+static inline
+int iswpunct_l(wchar_t wc, locale_t locale)
+{
+  return __xiswpunct(locale, wc);
+}
+
+static inline
+int iswspace_l(wchar_t wc, locale_t locale)
+{
+  return __xiswspace(locale, wc);
+}
+
+static inline
+int iswupper_l(wchar_t wc, locale_t locale)
+{
+  return __xiswupper(locale, wc);
+}
+
+static inline
+int iswxdigit_l(wchar_t wc, locale_t locale)
+{
+  return __xiswxdigit(locale, wc);
+}
+
+static inline
+int iswctype_l(wint_t wc, wctype_t desc, locale_t locale)
+{
+  return __xiswctype(locale, wc, desc);
+}
+
+static inline
+int toupper_l(int c, locale_t locale)
+{
+  return __xtoupper(locale, c);
+}
+static inline
+int tolower_l(int c, locale_t locale)
+{
+  return __xtolower(locale, c);
+}
+static inline
+wint_t towupper_l(wint_t wc, locale_t locale)
+{
+  return __xtowupper(locale, wc);
+}
+static inline
+wint_t towlower_l(wint_t wc, locale_t locale)
+{
+  return __xtowlower(locale, wc);
+}
+
+static inline
+int strcoll_l(const char *__s1, const char *__s2, locale_t locale)
+{
+  return __xstrcoll(locale, __s1, __s2);
+}
+static inline
+int wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, locale_t locale)
+{
+  return __xwcscoll(locale, __s1, __s2);
+}
+static inline
+size_t strxfrm_l(char *__s1, const char *__s2, size_t __n, locale_t locale)
+{
+  return __xstrxfrm(locale, __s1, __s2, __n);
+}
+
+static inline
+size_t wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n,
+    locale_t locale)
+{
+  return __xwcsxfrm(locale, __ws1, __ws2, __n);
+}
+#endif // !defined(_AIX71)
+
+// strftime_l() is defined by POSIX. However, AIX 7.1 and z/OS do not have it
+// implemented yet. z/OS retrieves it from the POSIX fallbacks.
+#if !defined(_AIX72)
+static inline
+size_t strftime_l(char *__s, size_t __size, const char *__fmt,
+                  const struct tm *__tm, locale_t locale) {
+  return __xstrftime(locale, __s, __size, __fmt, __tm);
+}
+#endif
+
+#elif defined(__MVS__)
+#include <wctype.h>
+// POSIX routines
+#include <__support/xlocale/__posix_l_fallback.h>
+#endif // defined(__MVS__)
+
+namespace {
+
+struct __setAndRestore {
+  explicit __setAndRestore(locale_t locale) {
+    if (locale == (locale_t)0) {
+      __cloc = newlocale(LC_ALL_MASK, "C", /* base */ (locale_t)0);
+      __stored = uselocale(__cloc);
+    } else {
+      __stored = uselocale(locale);
+    }
+  }
+
+  ~__setAndRestore() {
+    uselocale(__stored);
+    if (__cloc)
+      freelocale(__cloc);
+  }
+
+private:
+  locale_t __stored = (locale_t)0;
+  locale_t __cloc = (locale_t)0;
+};
+
+} // namespace
+
+// The following are not POSIX routines.  These are quick-and-dirty hacks
+// to make things pretend to work
+static inline
+long long strtoll_l(const char *__nptr, char **__endptr,
+    int __base, locale_t locale) {
+  __setAndRestore __newloc(locale);
+  return strtoll(__nptr, __endptr, __base);
+}
+
+static inline
+long strtol_l(const char *__nptr, char **__endptr,
+    int __base, locale_t locale) {
+  __setAndRestore __newloc(locale);
+  return strtol(__nptr, __endptr, __base);
+}
+
+static inline
+double strtod_l(const char *__nptr, char **__endptr,
+    locale_t locale) {
+  __setAndRestore __newloc(locale);
+  return strtod(__nptr, __endptr);
+}
+
+static inline
+float strtof_l(const char *__nptr, char **__endptr,
+    locale_t locale) {
+  __setAndRestore __newloc(locale);
+  return strtof(__nptr, __endptr);
+}
+
+static inline
+long double strtold_l(const char *__nptr, char **__endptr,
+    locale_t locale) {
+  __setAndRestore __newloc(locale);
+  return strtold(__nptr, __endptr);
+}
+
+static inline
+unsigned long long strtoull_l(const char *__nptr, char **__endptr,
+    int __base, locale_t locale) {
+  __setAndRestore __newloc(locale);
+  return strtoull(__nptr, __endptr, __base);
+}
+
+static inline
+unsigned long strtoul_l(const char *__nptr, char **__endptr,
+    int __base, locale_t locale) {
+  __setAndRestore __newloc(locale);
+  return strtoul(__nptr, __endptr, __base);
+}
+
+static inline
+int vasprintf(char **strp, const char *fmt, va_list ap) {
+  const size_t buff_size = 256;
+  if ((*strp = (char *)malloc(buff_size)) == NULL) {
+    return -1;
+  }
+
+  va_list ap_copy;
+  // va_copy may not be provided by the C library in C++ 03 mode.
+#if defined(_LIBCPP_CXX03_LANG) && __has_builtin(__builtin_va_copy)
+  __builtin_va_copy(ap_copy, ap);
+#else
+  va_copy(ap_copy, ap);
+#endif
+  int str_size = vsnprintf(*strp, buff_size, fmt,  ap_copy);
+  va_end(ap_copy);
+
+  if ((size_t) str_size >= buff_size) {
+    if ((*strp = (char *)realloc(*strp, str_size + 1)) == NULL) {
+      return -1;
+    }
+    str_size = vsnprintf(*strp, str_size + 1, fmt,  ap);
+  }
+  return str_size;
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif // _LIBCPP_SUPPORT_IBM_XLOCALE_H
diff --git a/include/__support/musl/xlocale.h b/include/__support/musl/xlocale.h
new file mode 100644
index 0000000..2508a8e
--- /dev/null
+++ b/include/__support/musl/xlocale.h
@@ -0,0 +1,57 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// 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
new file mode 100644
index 0000000..b75f926
--- /dev/null
+++ b/include/__support/newlib/xlocale.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_NEWLIB_XLOCALE_H
+#define _LIBCPP_SUPPORT_NEWLIB_XLOCALE_H
+
+#if defined(_NEWLIB_VERSION)
+
+#include <cstdlib>
+#include <clocale>
+#include <cwctype>
+#include <ctype.h>
+#if !defined(__NEWLIB__) || __NEWLIB__ < 2 || \
+    __NEWLIB__ == 2 && __NEWLIB_MINOR__ < 5
+#include <__support/xlocale/__nop_locale_mgmt.h>
+#include <__support/xlocale/__posix_l_fallback.h>
+#include <__support/xlocale/__strtonum_fallback.h>
+#endif
+
+#endif // _NEWLIB_VERSION
+
+#endif
diff --git a/include/__support/nuttx/xlocale.h b/include/__support/nuttx/xlocale.h
new file mode 100644
index 0000000..be738e3
--- /dev/null
+++ b/include/__support/nuttx/xlocale.h
@@ -0,0 +1,18 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_NUTTX_XLOCALE_H
+#define _LIBCPP_SUPPORT_NUTTX_XLOCALE_H
+
+#if defined(__NuttX__)
+#include <__support/xlocale/__posix_l_fallback.h>
+#include <__support/xlocale/__strtonum_fallback.h>
+#endif // __NuttX__
+
+#endif
diff --git a/include/__support/openbsd/xlocale.h b/include/__support/openbsd/xlocale.h
new file mode 100644
index 0000000..49d66fd
--- /dev/null
+++ b/include/__support/openbsd/xlocale.h
@@ -0,0 +1,19 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_OPENBSD_XLOCALE_H
+#define _LIBCPP_SUPPORT_OPENBSD_XLOCALE_H
+
+#include <__support/xlocale/__strtonum_fallback.h>
+#include <clocale>
+#include <cstdlib>
+#include <ctype.h>
+#include <cwctype>
+
+#endif
diff --git a/include/__support/solaris/floatingpoint.h b/include/__support/solaris/floatingpoint.h
new file mode 100644
index 0000000..5f1628f
--- /dev/null
+++ b/include/__support/solaris/floatingpoint.h
@@ -0,0 +1,13 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#define atof sun_atof
+#define strtod sun_strtod
+#include_next "floatingpoint.h"
+#undef atof
+#undef strtod
diff --git a/include/__support/solaris/wchar.h b/include/__support/solaris/wchar.h
new file mode 100644
index 0000000..f01fd74
--- /dev/null
+++ b/include/__support/solaris/wchar.h
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#define iswalpha sun_iswalpha
+#define iswupper sun_iswupper
+#define iswlower sun_iswlower
+#define iswdigit sun_iswdigit
+#define iswxdigit sun_iswxdigit
+#define iswalnum sun_iswalnum
+#define iswspace sun_iswspace
+#define iswpunct sun_iswpunct
+#define iswprint sun_iswprint
+#define iswgraph sun_iswgraph
+#define iswcntrl sun_iswcntrl
+#define iswctype sun_iswctype
+#define towlower sun_towlower
+#define towupper sun_towupper
+#define wcswcs sun_wcswcs
+#define wcswidth sun_wcswidth
+#define wcwidth sun_wcwidth
+#define wctype sun_wctype
+#define _WCHAR_T 1
+#include_next "wchar.h"
+#undef iswalpha
+#undef iswupper
+#undef iswlower
+#undef iswdigit
+#undef iswxdigit
+#undef iswalnum
+#undef iswspace
+#undef iswpunct
+#undef iswprint
+#undef iswgraph
+#undef iswcntrl
+#undef iswctype
+#undef towlower
+#undef towupper
+#undef wcswcs
+#undef wcswidth
+#undef wcwidth
+#undef wctype
diff --git a/include/__support/solaris/xlocale.h b/include/__support/solaris/xlocale.h
new file mode 100644
index 0000000..05131f0
--- /dev/null
+++ b/include/__support/solaris/xlocale.h
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+////////////////////////////////////////////////////////////////////////////////
+// Minimal xlocale implementation for Solaris.  This implements the subset of
+// the xlocale APIs that libc++ depends on.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef __XLOCALE_H_INCLUDED
+#define __XLOCALE_H_INCLUDED
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+int snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...);
+int asprintf_l(char **__s, locale_t __l, const char *__format, ...);
+
+int sscanf_l(const char *__s, locale_t __l, const char *__format, ...);
+
+int toupper_l(int __c, locale_t __l);
+int tolower_l(int __c, locale_t __l);
+
+struct lconv *localeconv(void);
+struct lconv *localeconv_l(locale_t __l);
+
+// FIXME: These are quick-and-dirty hacks to make things pretend to work
+static inline
+long long strtoll_l(const char *__nptr, char **__endptr,
+    int __base, locale_t __loc) {
+  return strtoll(__nptr, __endptr, __base);
+}
+static inline
+long strtol_l(const char *__nptr, char **__endptr,
+    int __base, locale_t __loc) {
+  return strtol(__nptr, __endptr, __base);
+}
+static inline
+unsigned long long strtoull_l(const char *__nptr, char **__endptr,
+    int __base, locale_t __loc) {
+  return strtoull(__nptr, __endptr, __base);
+}
+static inline
+unsigned long strtoul_l(const char *__nptr, char **__endptr,
+    int __base, locale_t __loc) {
+  return strtoul(__nptr, __endptr, __base);
+}
+static inline
+float strtof_l(const char *__nptr, char **__endptr,
+    locale_t __loc) {
+  return strtof(__nptr, __endptr);
+}
+static inline
+double strtod_l(const char *__nptr, char **__endptr,
+    locale_t __loc) {
+  return strtod(__nptr, __endptr);
+}
+static inline
+long double strtold_l(const char *__nptr, char **__endptr,
+    locale_t __loc) {
+  return strtold(__nptr, __endptr);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/__support/win32/limits_msvc_win32.h b/include/__support/win32/limits_msvc_win32.h
new file mode 100644
index 0000000..c80df66
--- /dev/null
+++ b/include/__support/win32/limits_msvc_win32.h
@@ -0,0 +1,71 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_WIN32_LIMITS_MSVC_WIN32_H
+#define _LIBCPP_SUPPORT_WIN32_LIMITS_MSVC_WIN32_H
+
+#if !defined(_LIBCPP_MSVCRT)
+#error "This header complements the Microsoft C Runtime library, and should not be included otherwise."
+#endif
+#if defined(__clang__)
+#error "This header should only be included when using Microsofts C1XX frontend"
+#endif
+
+#include <float.h> // limit constants
+#include <limits.h> // CHAR_BIT
+#include <math.h> // HUGE_VAL
+#include <ymath.h> // internal MSVC header providing the needed functionality
+
+#define __CHAR_BIT__       CHAR_BIT
+
+#define __FLT_MANT_DIG__   FLT_MANT_DIG
+#define __FLT_DIG__        FLT_DIG
+#define __FLT_RADIX__      FLT_RADIX
+#define __FLT_MIN_EXP__    FLT_MIN_EXP
+#define __FLT_MIN_10_EXP__ FLT_MIN_10_EXP
+#define __FLT_MAX_EXP__    FLT_MAX_EXP
+#define __FLT_MAX_10_EXP__ FLT_MAX_10_EXP
+#define __FLT_MIN__        FLT_MIN
+#define __FLT_MAX__        FLT_MAX
+#define __FLT_EPSILON__    FLT_EPSILON
+// predefined by MinGW GCC
+#define __FLT_DENORM_MIN__ 1.40129846432481707092e-45F
+
+#define __DBL_MANT_DIG__   DBL_MANT_DIG
+#define __DBL_DIG__        DBL_DIG
+#define __DBL_RADIX__      DBL_RADIX
+#define __DBL_MIN_EXP__    DBL_MIN_EXP
+#define __DBL_MIN_10_EXP__ DBL_MIN_10_EXP
+#define __DBL_MAX_EXP__    DBL_MAX_EXP
+#define __DBL_MAX_10_EXP__ DBL_MAX_10_EXP
+#define __DBL_MIN__        DBL_MIN
+#define __DBL_MAX__        DBL_MAX
+#define __DBL_EPSILON__    DBL_EPSILON
+// predefined by MinGW GCC
+#define __DBL_DENORM_MIN__ double(4.94065645841246544177e-324L)
+
+#define __LDBL_MANT_DIG__   LDBL_MANT_DIG
+#define __LDBL_DIG__        LDBL_DIG
+#define __LDBL_RADIX__      LDBL_RADIX
+#define __LDBL_MIN_EXP__    LDBL_MIN_EXP
+#define __LDBL_MIN_10_EXP__ LDBL_MIN_10_EXP
+#define __LDBL_MAX_EXP__    LDBL_MAX_EXP
+#define __LDBL_MAX_10_EXP__ LDBL_MAX_10_EXP
+#define __LDBL_MIN__        LDBL_MIN
+#define __LDBL_MAX__        LDBL_MAX
+#define __LDBL_EPSILON__    LDBL_EPSILON
+// predefined by MinGW GCC
+#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
+
+// __builtin replacements/workarounds
+#define __builtin_huge_vall()    _LInf._Long_double
+#define __builtin_nanl(__dummmy) _LNan._Long_double
+#define __builtin_nansl(__dummy) _LSnan._Long_double
+
+#endif // _LIBCPP_SUPPORT_WIN32_LIMITS_MSVC_WIN32_H
diff --git a/include/__support/win32/locale_win32.h b/include/__support/win32/locale_win32.h
new file mode 100644
index 0000000..dd8a600
--- /dev/null
+++ b/include/__support/win32/locale_win32.h
@@ -0,0 +1,283 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H
+#define _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H
+
+#include <__config>
+#include <__nullptr>
+#include <locale.h> // _locale_t
+#include <stdio.h>
+
+#define _X_ALL LC_ALL
+#define _X_COLLATE LC_COLLATE
+#define _X_CTYPE LC_CTYPE
+#define _X_MONETARY LC_MONETARY
+#define _X_NUMERIC LC_NUMERIC
+#define _X_TIME LC_TIME
+#define _X_MAX LC_MAX
+#define _X_MESSAGES 6
+#define _NCAT (_X_MESSAGES + 1)
+
+#define _CATMASK(n) ((1 << (n)) >> 1)
+#define _M_COLLATE _CATMASK(_X_COLLATE)
+#define _M_CTYPE _CATMASK(_X_CTYPE)
+#define _M_MONETARY _CATMASK(_X_MONETARY)
+#define _M_NUMERIC _CATMASK(_X_NUMERIC)
+#define _M_TIME _CATMASK(_X_TIME)
+#define _M_MESSAGES _CATMASK(_X_MESSAGES)
+#define _M_ALL (_CATMASK(_NCAT) - 1)
+
+#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 )
+
+class __lconv_storage {
+public:
+    __lconv_storage(const lconv *__lc_input) {
+        __lc = *__lc_input;
+
+        __decimal_point = __lc_input->decimal_point;
+        __thousands_sep = __lc_input->thousands_sep;
+        __grouping = __lc_input->grouping;
+        __int_curr_symbol = __lc_input->int_curr_symbol;
+        __currency_symbol = __lc_input->currency_symbol;
+        __mon_decimal_point = __lc_input->mon_decimal_point;
+        __mon_thousands_sep = __lc_input->mon_thousands_sep;
+        __mon_grouping = __lc_input->mon_grouping;
+        __positive_sign = __lc_input->positive_sign;
+        __negative_sign = __lc_input->negative_sign;
+
+        __lc.decimal_point = const_cast<char *>(__decimal_point.c_str());
+        __lc.thousands_sep = const_cast<char *>(__thousands_sep.c_str());
+        __lc.grouping = const_cast<char *>(__grouping.c_str());
+        __lc.int_curr_symbol = const_cast<char *>(__int_curr_symbol.c_str());
+        __lc.currency_symbol = const_cast<char *>(__currency_symbol.c_str());
+        __lc.mon_decimal_point = const_cast<char *>(__mon_decimal_point.c_str());
+        __lc.mon_thousands_sep = const_cast<char *>(__mon_thousands_sep.c_str());
+        __lc.mon_grouping = const_cast<char *>(__mon_grouping.c_str());
+        __lc.positive_sign = const_cast<char *>(__positive_sign.c_str());
+        __lc.negative_sign = const_cast<char *>(__negative_sign.c_str());
+    }
+
+    lconv *__get() {
+        return &__lc;
+    }
+private:
+    lconv __lc;
+    std::string __decimal_point;
+    std::string __thousands_sep;
+    std::string __grouping;
+    std::string __int_curr_symbol;
+    std::string __currency_symbol;
+    std::string __mon_decimal_point;
+    std::string __mon_thousands_sep;
+    std::string __mon_grouping;
+    std::string __positive_sign;
+    std::string __negative_sign;
+};
+
+class locale_t {
+public:
+    locale_t()
+        : __locale(nullptr), __locale_str(nullptr), __lc(nullptr) {}
+    locale_t(std::nullptr_t)
+        : __locale(nullptr), __locale_str(nullptr), __lc(nullptr) {}
+    locale_t(_locale_t __xlocale, const char* __xlocale_str)
+        : __locale(__xlocale), __locale_str(__xlocale_str), __lc(nullptr) {}
+    locale_t(const locale_t &__l)
+        : __locale(__l.__locale), __locale_str(__l.__locale_str), __lc(nullptr) {}
+
+    ~locale_t() {
+        delete __lc;
+    }
+
+    locale_t &operator =(const locale_t &__l) {
+        __locale = __l.__locale;
+        __locale_str = __l.__locale_str;
+        // __lc not copied
+        return *this;
+    }
+
+    friend bool operator==(const locale_t& __left, const locale_t& __right) {
+        return __left.__locale == __right.__locale;
+    }
+
+    friend bool operator==(const locale_t& __left, int __right) {
+        return __left.__locale == nullptr && __right == 0;
+    }
+
+    friend bool operator==(const locale_t& __left, long long __right) {
+        return __left.__locale == nullptr && __right == 0;
+    }
+
+    friend bool operator==(const locale_t& __left, std::nullptr_t) {
+        return __left.__locale == nullptr;
+    }
+
+    friend bool operator==(int __left, const locale_t& __right) {
+        return __left == 0 && nullptr == __right.__locale;
+    }
+
+    friend bool operator==(std::nullptr_t, const locale_t& __right) {
+        return nullptr == __right.__locale;
+    }
+
+    friend bool operator!=(const locale_t& __left, const locale_t& __right) {
+        return !(__left == __right);
+    }
+
+    friend bool operator!=(const locale_t& __left, int __right) {
+        return !(__left == __right);
+    }
+
+    friend bool operator!=(const locale_t& __left, long long __right) {
+        return !(__left == __right);
+    }
+
+    friend bool operator!=(const locale_t& __left, std::nullptr_t __right) {
+        return !(__left == __right);
+    }
+
+    friend bool operator!=(int __left, const locale_t& __right) {
+        return !(__left == __right);
+    }
+
+    friend bool operator!=(std::nullptr_t __left, const locale_t& __right) {
+        return !(__left == __right);
+    }
+
+    operator bool() const {
+        return __locale != nullptr;
+    }
+
+    const char* __get_locale() const { return __locale_str; }
+
+    operator _locale_t() const {
+        return __locale;
+    }
+
+    lconv *__store_lconv(const lconv *__input_lc) {
+        delete __lc;
+        __lc = new __lconv_storage(__input_lc);
+        return __lc->__get();
+    }
+private:
+    _locale_t __locale;
+    const char* __locale_str;
+    __lconv_storage *__lc = nullptr;
+};
+
+// Locale management functions
+#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 );
+// uselocale can't be implemented on Windows because Windows allows partial modification
+// of thread-local locale and so _get_current_locale() returns a copy while uselocale does
+// not create any copies.
+// We can still implement raii even without uselocale though.
+
+
+lconv *localeconv_l( locale_t &loc );
+size_t mbrlen_l( const char *__restrict s, size_t n,
+                 mbstate_t *__restrict ps, locale_t loc);
+size_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
+                    size_t len, mbstate_t *__restrict ps, locale_t loc );
+size_t wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps,
+                  locale_t loc);
+size_t mbrtowc_l( wchar_t *__restrict pwc, const char *__restrict s,
+                  size_t n, mbstate_t *__restrict ps, locale_t loc);
+size_t mbsnrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
+                     size_t nms, size_t len, mbstate_t *__restrict ps, locale_t loc);
+size_t wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src,
+                     size_t nwc, size_t len, mbstate_t *__restrict ps, locale_t loc);
+wint_t btowc_l( int c, locale_t loc );
+int wctob_l( wint_t c, locale_t loc );
+
+decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l );
+
+// the *_l functions are prefixed on Windows, only available for msvcr80+, VS2005+
+#define mbtowc_l _mbtowc_l
+#define strtoll_l _strtoi64_l
+#define strtoull_l _strtoui64_l
+#define strtod_l _strtod_l
+#if defined(_LIBCPP_MSVCRT)
+#define strtof_l _strtof_l
+#define strtold_l _strtold_l
+#else
+_LIBCPP_FUNC_VIS float strtof_l(const char*, char**, locale_t);
+_LIBCPP_FUNC_VIS long double strtold_l(const char*, char**, locale_t);
+#endif
+inline _LIBCPP_INLINE_VISIBILITY
+int
+islower_l(int c, _locale_t loc)
+{
+ return _islower_l((int)c, loc);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int
+isupper_l(int c, _locale_t loc)
+{
+ return _isupper_l((int)c, loc);
+}
+
+#define isdigit_l _isdigit_l
+#define isxdigit_l _isxdigit_l
+#define strcoll_l _strcoll_l
+#define strxfrm_l _strxfrm_l
+#define wcscoll_l _wcscoll_l
+#define wcsxfrm_l _wcsxfrm_l
+#define toupper_l _toupper_l
+#define tolower_l _tolower_l
+#define iswspace_l _iswspace_l
+#define iswprint_l _iswprint_l
+#define iswcntrl_l _iswcntrl_l
+#define iswupper_l _iswupper_l
+#define iswlower_l _iswlower_l
+#define iswalpha_l _iswalpha_l
+#define iswdigit_l _iswdigit_l
+#define iswpunct_l _iswpunct_l
+#define iswxdigit_l _iswxdigit_l
+#define towupper_l _towupper_l
+#define towlower_l _towlower_l
+#if defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x0800
+_LIBCPP_FUNC_VIS size_t strftime_l(char *ret, size_t n, const char *format,
+                                   const struct tm *tm, locale_t loc);
+#else
+#define strftime_l _strftime_l
+#endif
+#define sscanf_l( __s, __l, __f, ...) _sscanf_l( __s, __f, __l, __VA_ARGS__ )
+#define sprintf_l( __s, __l, __f, ... ) _sprintf_l( __s, __f, __l, __VA_ARGS__ )
+#define vsprintf_l( __s, __l, __f, ... ) _vsprintf_l( __s, __f, __l, __VA_ARGS__ )
+#define vsnprintf_l( __s, __n, __l, __f, ... ) _vsnprintf_l( __s, __n, __f, __l, __VA_ARGS__ )
+_LIBCPP_FUNC_VIS int snprintf_l(char *ret, size_t n, locale_t loc, const char *format, ...);
+_LIBCPP_FUNC_VIS int asprintf_l( char **ret, locale_t loc, const char *format, ... );
+_LIBCPP_FUNC_VIS int vasprintf_l( char **ret, locale_t loc, const char *format, va_list ap );
+
+// not-so-pressing FIXME: use locale to determine blank characters
+inline int isblank_l( int c, locale_t /*loc*/ )
+{
+    return ( c == ' ' || c == '\t' );
+}
+inline int iswblank_l( wint_t c, locale_t /*loc*/ )
+{
+    return ( c == L' ' || c == L'\t' );
+}
+
+#endif // _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H
diff --git a/include/__support/xlocale/__nop_locale_mgmt.h b/include/__support/xlocale/__nop_locale_mgmt.h
new file mode 100644
index 0000000..57b1884
--- /dev/null
+++ b/include/__support/xlocale/__nop_locale_mgmt.h
@@ -0,0 +1,51 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#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..00d69d1
--- /dev/null
+++ b/include/__support/xlocale/__posix_l_fallback.h
@@ -0,0 +1,164 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// 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_INLINE_VISIBILITY int isalnum_l(int c, locale_t) {
+  return ::isalnum(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int isalpha_l(int c, locale_t) {
+  return ::isalpha(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int isblank_l(int c, locale_t) {
+  return ::isblank(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int iscntrl_l(int c, locale_t) {
+  return ::iscntrl(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int isdigit_l(int c, locale_t) {
+  return ::isdigit(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int isgraph_l(int c, locale_t) {
+  return ::isgraph(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int islower_l(int c, locale_t) {
+  return ::islower(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int isprint_l(int c, locale_t) {
+  return ::isprint(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int ispunct_l(int c, locale_t) {
+  return ::ispunct(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int isspace_l(int c, locale_t) {
+  return ::isspace(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int isupper_l(int c, locale_t) {
+  return ::isupper(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int isxdigit_l(int c, locale_t) {
+  return ::isxdigit(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int iswalnum_l(wint_t c, locale_t) {
+  return ::iswalnum(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int iswalpha_l(wint_t c, locale_t) {
+  return ::iswalpha(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int iswblank_l(wint_t c, locale_t) {
+  return ::iswblank(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int iswcntrl_l(wint_t c, locale_t) {
+  return ::iswcntrl(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int iswdigit_l(wint_t c, locale_t) {
+  return ::iswdigit(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int iswgraph_l(wint_t c, locale_t) {
+  return ::iswgraph(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int iswlower_l(wint_t c, locale_t) {
+  return ::iswlower(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int iswprint_l(wint_t c, locale_t) {
+  return ::iswprint(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int iswpunct_l(wint_t c, locale_t) {
+  return ::iswpunct(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int iswspace_l(wint_t c, locale_t) {
+  return ::iswspace(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int iswupper_l(wint_t c, locale_t) {
+  return ::iswupper(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int iswxdigit_l(wint_t c, locale_t) {
+  return ::iswxdigit(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int toupper_l(int c, locale_t) {
+  return ::toupper(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int tolower_l(int c, locale_t) {
+  return ::tolower(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY wint_t towupper_l(wint_t c, locale_t) {
+  return ::towupper(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY wint_t towlower_l(wint_t c, locale_t) {
+  return ::towlower(c);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int strcoll_l(const char *s1, const char *s2,
+                                               locale_t) {
+  return ::strcoll(s1, s2);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY size_t strxfrm_l(char *dest, const char *src,
+                                                  size_t n, locale_t) {
+  return ::strxfrm(dest, src, n);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY 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_INLINE_VISIBILITY int wcscoll_l(const wchar_t *ws1,
+                                               const wchar_t *ws2, locale_t) {
+  return ::wcscoll(ws1, ws2);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY 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..1172a5d
--- /dev/null
+++ b/include/__support/xlocale/__strtonum_fallback.h
@@ -0,0 +1,66 @@
+// -*- C++ -*-
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// 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_INLINE_VISIBILITY float strtof_l(const char *nptr,
+                                                char **endptr, locale_t) {
+  return ::strtof(nptr, endptr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY double strtod_l(const char *nptr,
+                                                 char **endptr, locale_t) {
+  return ::strtod(nptr, endptr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY long double strtold_l(const char *nptr,
+                                                       char **endptr, locale_t) {
+  return ::strtold(nptr, endptr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY long long
+strtoll_l(const char *nptr, char **endptr, int base, locale_t) {
+  return ::strtoll(nptr, endptr, base);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY unsigned long long
+strtoull_l(const char *nptr, char **endptr, int base, locale_t) {
+  return ::strtoull(nptr, endptr, base);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY long long
+wcstoll_l(const wchar_t *nptr, wchar_t **endptr, int base, locale_t) {
+  return ::wcstoll(nptr, endptr, base);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY unsigned long long
+wcstoull_l(const wchar_t *nptr, wchar_t **endptr, int base, locale_t) {
+  return ::wcstoull(nptr, endptr, base);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY 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/__threading_support b/include/__threading_support
new file mode 100644
index 0000000..4d86716
--- /dev/null
+++ b/include/__threading_support
@@ -0,0 +1,817 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_THREADING_SUPPORT
+#define _LIBCPP_THREADING_SUPPORT
+
+#include <__availability>
+#include <__config>
+#include <chrono>
+#include <errno.h>
+#include <iosfwd>
+#include <limits>
+
+#ifdef __MVS__
+# include <__support/ibm/nanosleep.h>
+#endif
+
+#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
+#pragma GCC system_header
+#endif
+
+#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
+# include <__external_threading>
+#elif !defined(_LIBCPP_HAS_NO_THREADS)
+
+#if defined(__APPLE__) || defined(__MVS__)
+# define _LIBCPP_NO_NATIVE_SEMAPHORES
+#endif
+
+#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+# include <pthread.h>
+# include <sched.h>
+# ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
+#   include <semaphore.h>
+# endif
+#elif defined(_LIBCPP_HAS_THREAD_API_C11)
+# include <threads.h>
+#endif
+
+#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
+    defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
+    defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
+#else
+#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
+#endif
+
+#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
+#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
+#else
+#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
+#endif
+
+typedef ::timespec __libcpp_timespec_t;
+#endif // !defined(_LIBCPP_HAS_NO_THREADS)
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_THREADS)
+
+#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+// Mutex
+typedef pthread_mutex_t __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+
+typedef pthread_mutex_t __libcpp_recursive_mutex_t;
+
+// Condition Variable
+typedef pthread_cond_t __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
+
+#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
+// Semaphore
+typedef sem_t __libcpp_semaphore_t;
+# define _LIBCPP_SEMAPHORE_MAX SEM_VALUE_MAX
+#endif
+
+// Execute once
+typedef pthread_once_t __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
+
+// Thread id
+#if defined(__MVS__)
+  typedef unsigned long long __libcpp_thread_id;
+#else
+  typedef pthread_t __libcpp_thread_id;
+#endif
+
+// Thread
+#define _LIBCPP_NULL_THREAD ((__libcpp_thread_t()))
+typedef pthread_t __libcpp_thread_t;
+
+// Thread Local Storage
+typedef pthread_key_t __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC
+#elif defined(_LIBCPP_HAS_THREAD_API_C11)
+// Mutex
+typedef mtx_t __libcpp_mutex_t;
+// mtx_t is a struct so using {} for initialization is valid.
+#define _LIBCPP_MUTEX_INITIALIZER {}
+
+typedef mtx_t __libcpp_recursive_mutex_t;
+
+// Condition Variable
+typedef cnd_t __libcpp_condvar_t;
+// cnd_t is a struct so using {} for initialization is valid.
+#define _LIBCPP_CONDVAR_INITIALIZER {}
+
+// Execute once
+typedef once_flag __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT
+
+// Thread id
+typedef thrd_t __libcpp_thread_id;
+
+// Thread
+#define _LIBCPP_NULL_THREAD 0U
+
+typedef thrd_t __libcpp_thread_t;
+
+// Thread Local Storage
+typedef tss_t __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC
+#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
+// Mutex
+typedef void* __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER 0
+
+#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
+typedef void* __libcpp_recursive_mutex_t[6];
+#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
+typedef void* __libcpp_recursive_mutex_t[5];
+#else
+# error Unsupported architecture
+#endif
+
+// Condition Variable
+typedef void* __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER 0
+
+// Semaphore
+typedef void* __libcpp_semaphore_t;
+#if defined(_LIBCPP_HAS_THREAD_API_WIN32)
+# define _LIBCPP_SEMAPHORE_MAX (::std::numeric_limits<long>::max())
+#endif
+
+// Execute Once
+typedef void* __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER 0
+
+// Thread ID
+typedef long __libcpp_thread_id;
+
+// Thread
+#define _LIBCPP_NULL_THREAD 0U
+
+typedef void* __libcpp_thread_t;
+
+// Thread Local Storage
+typedef long __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
+#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
+
+#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
+// Mutex
+_LIBCPP_THREAD_ABI_VISIBILITY
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
+
+_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
+
+_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
+bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
+
+_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
+
+_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
+
+_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
+bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
+
+_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
+
+// Condition variable
+_LIBCPP_THREAD_ABI_VISIBILITY
+int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
+
+_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
+int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
+
+_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
+int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
+                               __libcpp_timespec_t *__ts);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
+
+#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
+
+// Semaphore
+_LIBCPP_THREAD_ABI_VISIBILITY
+bool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+bool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+bool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+bool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+bool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns);
+
+#endif // _LIBCPP_NO_NATIVE_SEMAPHORES
+
+// Execute once
+_LIBCPP_THREAD_ABI_VISIBILITY
+int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
+                          void (*init_routine)());
+
+// Thread id
+_LIBCPP_THREAD_ABI_VISIBILITY
+bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
+
+// Thread
+_LIBCPP_THREAD_ABI_VISIBILITY
+bool __libcpp_thread_isnull(const __libcpp_thread_t *__t);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
+                           void *__arg);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+__libcpp_thread_id __libcpp_thread_get_current_id();
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+int __libcpp_thread_join(__libcpp_thread_t *__t);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+int __libcpp_thread_detach(__libcpp_thread_t *__t);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+void __libcpp_thread_yield();
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
+
+// Thread local storage
+_LIBCPP_THREAD_ABI_VISIBILITY
+int __libcpp_tls_create(__libcpp_tls_key* __key,
+                        void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+void *__libcpp_tls_get(__libcpp_tls_key __key);
+
+_LIBCPP_THREAD_ABI_VISIBILITY
+int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
+
+#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
+
+struct __libcpp_timed_backoff_policy {
+  _LIBCPP_INLINE_VISIBILITY
+  bool operator()(chrono::nanoseconds __elapsed) const
+  {
+      if(__elapsed > chrono::milliseconds(128))
+          __libcpp_thread_sleep_for(chrono::milliseconds(8));
+      else if(__elapsed > chrono::microseconds(64))
+          __libcpp_thread_sleep_for(__elapsed / 2);
+      else if(__elapsed > chrono::microseconds(4))
+        __libcpp_thread_yield();
+      else
+        {} // poll
+      return false;
+  }
+};
+
+static _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64;
+
+template<class _Fn, class _BFn>
+_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
+bool __libcpp_thread_poll_with_backoff(
+  _Fn && __f, _BFn && __bf, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero())
+{
+    auto const __start = chrono::high_resolution_clock::now();
+    for(int __count = 0;;) {
+      if(__f())
+        return true; // _Fn completion means success
+      if(__count < __libcpp_polling_count) {
+        __count += 1;
+        continue;
+      }
+      chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start;
+      if(__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed)
+          return false; // timeout failure
+      if(__bf(__elapsed))
+        return false; // _BFn completion means failure
+    }
+}
+
+#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
+     defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL))
+
+
+namespace __thread_detail {
+
+inline __libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns)
+{
+  using namespace chrono;
+  seconds __s = duration_cast<seconds>(__ns);
+  __libcpp_timespec_t __ts;
+  typedef decltype(__ts.tv_sec) __ts_sec;
+  const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max();
+
+  if (__s.count() < __ts_sec_max)
+  {
+    __ts.tv_sec = static_cast<__ts_sec>(__s.count());
+    __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count());
+  }
+  else
+  {
+    __ts.tv_sec = __ts_sec_max;
+    __ts.tv_nsec = 999999999; // (10^9 - 1)
+  }
+
+  return __ts;
+}
+
+}
+
+#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+
+int __libcpp_recursive_mutex_init(__libcpp_recursive_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;
+}
+
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
+{
+  return pthread_mutex_lock(__m);
+}
+
+bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
+{
+  return pthread_mutex_trylock(__m) == 0;
+}
+
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
+{
+  return pthread_mutex_unlock(__m);
+}
+
+int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
+{
+  return pthread_mutex_destroy(__m);
+}
+
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+{
+  return pthread_mutex_lock(__m);
+}
+
+bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+{
+  return pthread_mutex_trylock(__m) == 0;
+}
+
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+{
+  return pthread_mutex_unlock(__m);
+}
+
+int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
+{
+  return pthread_mutex_destroy(__m);
+}
+
+// Condition Variable
+int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
+{
+  return pthread_cond_signal(__cv);
+}
+
+int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
+{
+  return pthread_cond_broadcast(__cv);
+}
+
+int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
+{
+  return pthread_cond_wait(__cv, __m);
+}
+
+int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
+                               __libcpp_timespec_t *__ts)
+{
+  return pthread_cond_timedwait(__cv, __m, __ts);
+}
+
+int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
+{
+  return pthread_cond_destroy(__cv);
+}
+
+#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
+
+// Semaphore
+bool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init)
+{
+    return sem_init(__sem, 0, __init) == 0;
+}
+
+bool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem)
+{
+    return sem_destroy(__sem) == 0;
+}
+
+bool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem)
+{
+    return sem_post(__sem) == 0;
+}
+
+bool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem)
+{
+    return sem_wait(__sem) == 0;
+}
+
+bool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns)
+{
+    auto const __abs_time = chrono::system_clock::now().time_since_epoch() + __ns;
+    __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__abs_time);
+    return sem_timedwait(__sem, &__ts) == 0;
+}
+
+#endif //_LIBCPP_NO_NATIVE_SEMAPHORES
+
+// Execute once
+int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
+                          void (*init_routine)()) {
+  return pthread_once(flag, init_routine);
+}
+
+// Thread id
+// Returns non-zero if the thread ids are equal, otherwise 0
+bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
+{
+  return t1 == t2;
+}
+
+// Returns non-zero if t1 < t2, otherwise 0
+bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
+{
+  return t1 < t2;
+}
+
+// Thread
+bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
+  return __libcpp_thread_get_id(__t) == 0;
+}
+
+int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
+                           void *__arg)
+{
+  return pthread_create(__t, nullptr, __func, __arg);
+}
+
+__libcpp_thread_id __libcpp_thread_get_current_id()
+{
+  const __libcpp_thread_t thread = pthread_self();
+  return __libcpp_thread_get_id(&thread);
+}
+
+__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
+{
+#if defined(__MVS__)
+  return __t->__;
+#else
+  return *__t;
+#endif
+}
+
+int __libcpp_thread_join(__libcpp_thread_t *__t)
+{
+  return pthread_join(*__t, nullptr);
+}
+
+int __libcpp_thread_detach(__libcpp_thread_t *__t)
+{
+  return pthread_detach(*__t);
+}
+
+void __libcpp_thread_yield()
+{
+  sched_yield();
+}
+
+void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
+{
+   __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns);
+   while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
+}
+
+// Thread local storage
+int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
+{
+  return pthread_key_create(__key, __at_exit);
+}
+
+void *__libcpp_tls_get(__libcpp_tls_key __key)
+{
+  return pthread_getspecific(__key);
+}
+
+int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
+{
+    return pthread_setspecific(__key, __p);
+}
+
+#elif defined(_LIBCPP_HAS_THREAD_API_C11)
+
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
+{
+  return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL;
+}
+
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
+{
+  return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
+}
+
+bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
+{
+  return mtx_trylock(__m) == thrd_success;
+}
+
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
+{
+  return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
+}
+
+int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
+{
+  mtx_destroy(__m);
+  return 0;
+}
+
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+{
+  return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
+}
+
+bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+{
+  return mtx_trylock(__m) == thrd_success;
+}
+
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+{
+  return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
+}
+
+int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
+{
+  mtx_destroy(__m);
+  return 0;
+}
+
+// Condition Variable
+int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
+{
+  return cnd_signal(__cv) == thrd_success ? 0 : EINVAL;
+}
+
+int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
+{
+  return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL;
+}
+
+int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
+{
+  return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL;
+}
+
+int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
+                               timespec *__ts)
+{
+  int __ec = cnd_timedwait(__cv, __m, __ts);
+  return __ec == thrd_timedout ? ETIMEDOUT : __ec;
+}
+
+int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
+{
+  cnd_destroy(__cv);
+  return 0;
+}
+
+// Execute once
+int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
+                          void (*init_routine)(void)) {
+  ::call_once(flag, init_routine);
+  return 0;
+}
+
+// Thread id
+// Returns non-zero if the thread ids are equal, otherwise 0
+bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
+{
+  return thrd_equal(t1, t2) != 0;
+}
+
+// Returns non-zero if t1 < t2, otherwise 0
+bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
+{
+  return t1 < t2;
+}
+
+// Thread
+bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
+  return __libcpp_thread_get_id(__t) == 0;
+}
+
+int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
+                           void *__arg)
+{
+  int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg);
+  return __ec == thrd_nomem ? ENOMEM : __ec;
+}
+
+__libcpp_thread_id __libcpp_thread_get_current_id()
+{
+  return thrd_current();
+}
+
+__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
+{
+  return *__t;
+}
+
+int __libcpp_thread_join(__libcpp_thread_t *__t)
+{
+  return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL;
+}
+
+int __libcpp_thread_detach(__libcpp_thread_t *__t)
+{
+  return thrd_detach(*__t) == thrd_success ? 0 : EINVAL;
+}
+
+void __libcpp_thread_yield()
+{
+  thrd_yield();
+}
+
+void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
+{
+   __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns);
+  thrd_sleep(&__ts, nullptr);
+}
+
+// Thread local storage
+int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
+{
+  return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL;
+}
+
+void *__libcpp_tls_get(__libcpp_tls_key __key)
+{
+  return tss_get(__key);
+}
+
+int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
+{
+  return tss_set(__key, __p) == thrd_success ? 0 : EINVAL;
+}
+
+#endif
+
+
+#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
+
+class _LIBCPP_TYPE_VIS thread;
+class _LIBCPP_TYPE_VIS __thread_id;
+
+namespace this_thread
+{
+
+_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;
+
+}  // this_thread
+
+template<> struct hash<__thread_id>;
+
+class _LIBCPP_TEMPLATE_VIS __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.
+    __libcpp_thread_id __id_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __thread_id() _NOEXCEPT : __id_(0) {}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT
+        { // don't pass id==0 to underlying routines
+        if (__x.__id_ == 0) return __y.__id_ == 0;
+        if (__y.__id_ == 0) return false;
+        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
+        { // id==0 is always less than any other thread_id
+        if (__x.__id_ == 0) return __y.__id_ != 0;
+        if (__y.__id_ == 0) return false;
+        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);}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT
+        {return   __y < __x ;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT
+        {return !(__x < __y);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __reset() { __id_ = 0; }
+
+    template<class _CharT, class _Traits>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    __thread_id(__libcpp_thread_id __id) : __id_(__id) {}
+
+    friend __thread_id this_thread::get_id() _NOEXCEPT;
+    friend class _LIBCPP_TYPE_VIS thread;
+    friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
+};
+
+namespace this_thread
+{
+
+inline _LIBCPP_INLINE_VISIBILITY
+__thread_id
+get_id() _NOEXCEPT
+{
+    return __libcpp_thread_get_current_id();
+}
+
+}  // this_thread
+
+#endif // !_LIBCPP_HAS_NO_THREADS
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP_THREADING_SUPPORT
diff --git a/include/__tree b/include/__tree
index 8e5447a..6113322 100644
--- a/include/__tree
+++ b/include/__tree
@@ -1,10 +1,9 @@
 // -*- 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.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,30 +11,46 @@
 #define _LIBCPP___TREE
 
 #include <__config>
+#include <__utility/forward.h>
+#include <algorithm>
 #include <iterator>
+#include <limits>
 #include <memory>
 #include <stdexcept>
-#include <algorithm>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#if defined(__GNUC__) && !defined(__clang__) // gcc.gnu.org/PR37804
+template <class, class, class, class> class _LIBCPP_TEMPLATE_VIS map;
+template <class, class, class, class> class _LIBCPP_TEMPLATE_VIS multimap;
+template <class, class, class> class _LIBCPP_TEMPLATE_VIS set;
+template <class, class, class> class _LIBCPP_TEMPLATE_VIS multiset;
+#endif
+
 template <class _Tp, class _Compare, class _Allocator> class __tree;
 template <class _Tp, class _NodePtr, class _DiffType>
-    class _LIBCPP_TYPE_VIS_ONLY __tree_iterator;
+    class _LIBCPP_TEMPLATE_VIS __tree_iterator;
 template <class _Tp, class _ConstNodePtr, class _DiffType>
-    class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;
-template <class _Key, class _Tp, class _Compare, class _Allocator>
-    class _LIBCPP_TYPE_VIS_ONLY map;
-template <class _Key, class _Tp, class _Compare, class _Allocator>
-    class _LIBCPP_TYPE_VIS_ONLY multimap;
-template <class _Key, class _Compare, class _Allocator>
-    class _LIBCPP_TYPE_VIS_ONLY set;
-template <class _Key, class _Compare, class _Allocator>
-    class _LIBCPP_TYPE_VIS_ONLY multiset;
+    class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
+
+template <class _Pointer> class __tree_end_node;
+template <class _VoidPtr> class __tree_node_base;
+template <class _Tp, class _VoidPtr> class __tree_node;
+
+template <class _Key, class _Value>
+struct __value_type;
+
+template <class _Allocator> class __map_node_destructor;
+template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator;
+template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
 
 /*
 
@@ -68,7 +83,7 @@
     return __x == __x->__parent_->__left_;
 }
 
-// Determintes if the subtree rooted at __x is a proper red black subtree.  If
+// Determines if the subtree rooted at __x is a proper red black subtree.  If
 //    __x is a proper subtree, returns the black height (null counts as 1).  If
 //    __x is an improper subtree, returns 0.
 template <class _NodePtr>
@@ -95,15 +110,15 @@
         if (__x->__right_ && !__x->__right_->__is_black_)
             return 0;
     }
-    unsigned __h = __tree_sub_invariant(__x->__left_);
+    unsigned __h = _VSTD::__tree_sub_invariant(__x->__left_);
     if (__h == 0)
         return 0;  // invalid left subtree
-    if (__h != __tree_sub_invariant(__x->__right_))
+    if (__h != _VSTD::__tree_sub_invariant(__x->__right_))
         return 0;  // invalid or different height right subtree
     return __h + __x->__is_black_;  // return black height of this node
 }
 
-// Determintes if the red black tree rooted at __root is a proper red black tree.
+// Determines if the red black tree rooted at __root is a proper red black tree.
 //    __root == nullptr is a proper tree.  Returns true is __root is a proper
 //    red black tree, else returns false.
 template <class _NodePtr>
@@ -115,13 +130,13 @@
     // check __x->__parent_ consistency
     if (__root->__parent_ == nullptr)
         return false;
-    if (!__tree_is_left_child(__root))
+    if (!_VSTD::__tree_is_left_child(__root))
         return false;
     // root must be black
     if (!__root->__is_black_)
         return false;
     // do normal node checks
-    return __tree_sub_invariant(__root) != 0;
+    return _VSTD::__tree_sub_invariant(__root) != 0;
 }
 
 // Returns:  pointer to the left-most node under __x.
@@ -155,23 +170,38 @@
 __tree_next(_NodePtr __x) _NOEXCEPT
 {
     if (__x->__right_ != nullptr)
-        return __tree_min(__x->__right_);
-    while (!__tree_is_left_child(__x))
-        __x = __x->__parent_;
-    return __x->__parent_;
+        return _VSTD::__tree_min(__x->__right_);
+    while (!_VSTD::__tree_is_left_child(__x))
+        __x = __x->__parent_unsafe();
+    return __x->__parent_unsafe();
+}
+
+template <class _EndNodePtr, class _NodePtr>
+inline _LIBCPP_INLINE_VISIBILITY
+_EndNodePtr
+__tree_next_iter(_NodePtr __x) _NOEXCEPT
+{
+    if (__x->__right_ != nullptr)
+        return static_cast<_EndNodePtr>(_VSTD::__tree_min(__x->__right_));
+    while (!_VSTD::__tree_is_left_child(__x))
+        __x = __x->__parent_unsafe();
+    return static_cast<_EndNodePtr>(__x->__parent_);
 }
 
 // Returns:  pointer to the previous in-order node before __x.
 // Precondition:  __x != nullptr.
-template <class _NodePtr>
+// Note: __x may be the end node.
+template <class _NodePtr, class _EndNodePtr>
+inline _LIBCPP_INLINE_VISIBILITY
 _NodePtr
-__tree_prev(_NodePtr __x) _NOEXCEPT
+__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT
 {
     if (__x->__left_ != nullptr)
-        return __tree_max(__x->__left_);
-    while (__tree_is_left_child(__x))
-        __x = __x->__parent_;
-    return __x->__parent_;
+        return _VSTD::__tree_max(__x->__left_);
+    _NodePtr __xx = static_cast<_NodePtr>(__x);
+    while (_VSTD::__tree_is_left_child(__xx))
+        __xx = __xx->__parent_unsafe();
+    return __xx->__parent_unsafe();
 }
 
 // Returns:  pointer to a node which has no children
@@ -207,14 +237,14 @@
     _NodePtr __y = __x->__right_;
     __x->__right_ = __y->__left_;
     if (__x->__right_ != nullptr)
-        __x->__right_->__parent_ = __x;
+        __x->__right_->__set_parent(__x);
     __y->__parent_ = __x->__parent_;
-    if (__tree_is_left_child(__x))
+    if (_VSTD::__tree_is_left_child(__x))
         __x->__parent_->__left_ = __y;
     else
-        __x->__parent_->__right_ = __y;
+        __x->__parent_unsafe()->__right_ = __y;
     __y->__left_ = __x;
-    __x->__parent_ = __y;
+    __x->__set_parent(__y);
 }
 
 // Effects:  Makes __x->__left_ the subtree root with __x as its right child
@@ -227,14 +257,14 @@
     _NodePtr __y = __x->__left_;
     __x->__left_ = __y->__right_;
     if (__x->__left_ != nullptr)
-        __x->__left_->__parent_ = __x;
+        __x->__left_->__set_parent(__x);
     __y->__parent_ = __x->__parent_;
-    if (__tree_is_left_child(__x))
+    if (_VSTD::__tree_is_left_child(__x))
         __x->__parent_->__left_ = __y;
     else
-        __x->__parent_->__right_ = __y;
+        __x->__parent_unsafe()->__right_ = __y;
     __y->__right_ = __x;
-    __x->__parent_ = __y;
+    __x->__set_parent(__y);
 }
 
 // Effects:  Rebalances __root after attaching __x to a leaf.
@@ -250,58 +280,58 @@
 __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
 {
     __x->__is_black_ = __x == __root;
-    while (__x != __root && !__x->__parent_->__is_black_)
+    while (__x != __root && !__x->__parent_unsafe()->__is_black_)
     {
         // __x->__parent_ != __root because __x->__parent_->__is_black == false
-        if (__tree_is_left_child(__x->__parent_))
+        if (_VSTD::__tree_is_left_child(__x->__parent_unsafe()))
         {
-            _NodePtr __y = __x->__parent_->__parent_->__right_;
+            _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_;
             if (__y != nullptr && !__y->__is_black_)
             {
-                __x = __x->__parent_;
+                __x = __x->__parent_unsafe();
                 __x->__is_black_ = true;
-                __x = __x->__parent_;
+                __x = __x->__parent_unsafe();
                 __x->__is_black_ = __x == __root;
                 __y->__is_black_ = true;
             }
             else
             {
-                if (!__tree_is_left_child(__x))
+                if (!_VSTD::__tree_is_left_child(__x))
                 {
-                    __x = __x->__parent_;
-                    __tree_left_rotate(__x);
+                    __x = __x->__parent_unsafe();
+                    _VSTD::__tree_left_rotate(__x);
                 }
-                __x = __x->__parent_;
+                __x = __x->__parent_unsafe();
                 __x->__is_black_ = true;
-                __x = __x->__parent_;
+                __x = __x->__parent_unsafe();
                 __x->__is_black_ = false;
-                __tree_right_rotate(__x);
+                _VSTD::__tree_right_rotate(__x);
                 break;
             }
         }
         else
         {
-            _NodePtr __y = __x->__parent_->__parent_->__left_;
+            _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_;
             if (__y != nullptr && !__y->__is_black_)
             {
-                __x = __x->__parent_;
+                __x = __x->__parent_unsafe();
                 __x->__is_black_ = true;
-                __x = __x->__parent_;
+                __x = __x->__parent_unsafe();
                 __x->__is_black_ = __x == __root;
                 __y->__is_black_ = true;
             }
             else
             {
-                if (__tree_is_left_child(__x))
+                if (_VSTD::__tree_is_left_child(__x))
                 {
-                    __x = __x->__parent_;
-                    __tree_right_rotate(__x);
+                    __x = __x->__parent_unsafe();
+                    _VSTD::__tree_right_rotate(__x);
                 }
-                __x = __x->__parent_;
+                __x = __x->__parent_unsafe();
                 __x->__is_black_ = true;
-                __x = __x->__parent_;
+                __x = __x->__parent_unsafe();
                 __x->__is_black_ = false;
-                __tree_left_rotate(__x);
+                _VSTD::__tree_left_rotate(__x);
                 break;
             }
         }
@@ -324,7 +354,7 @@
     // __y will have at most one child.
     // __y will be the initial hole in the tree (make the hole at a leaf)
     _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ?
-                    __z : __tree_next(__z);
+                    __z : _VSTD::__tree_next(__z);
     // __x is __y's possibly null single child
     _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_;
     // __w is __x's possibly null uncle (will become __x's sibling)
@@ -332,17 +362,17 @@
     // link __x to __y's parent, and find __w
     if (__x != nullptr)
         __x->__parent_ = __y->__parent_;
-    if (__tree_is_left_child(__y))
+    if (_VSTD::__tree_is_left_child(__y))
     {
         __y->__parent_->__left_ = __x;
         if (__y != __root)
-            __w = __y->__parent_->__right_;
+            __w = __y->__parent_unsafe()->__right_;
         else
             __root = __x;  // __w == nullptr
     }
     else
     {
-        __y->__parent_->__right_ = __x;
+        __y->__parent_unsafe()->__right_ = __x;
         // __y can't be root if it is a right child
         __w = __y->__parent_->__left_;
     }
@@ -353,15 +383,15 @@
     {
         // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr
         __y->__parent_ = __z->__parent_;
-        if (__tree_is_left_child(__z))
+        if (_VSTD::__tree_is_left_child(__z))
             __y->__parent_->__left_ = __y;
         else
-            __y->__parent_->__right_ = __y;
+            __y->__parent_unsafe()->__right_ = __y;
         __y->__left_ = __z->__left_;
-        __y->__left_->__parent_ = __y;
+        __y->__left_->__set_parent(__y);
         __y->__right_ = __z->__right_;
         if (__y->__right_ != nullptr)
-            __y->__right_->__parent_ = __y;
+            __y->__right_->__set_parent(__y);
         __y->__is_black_ = __z->__is_black_;
         if (__root == __z)
             __root = __y;
@@ -393,13 +423,13 @@
             //     with a non-null black child).
             while (true)
             {
-                if (!__tree_is_left_child(__w))  // if x is left child
+                if (!_VSTD::__tree_is_left_child(__w))  // if x is left child
                 {
                     if (!__w->__is_black_)
                     {
                         __w->__is_black_ = true;
-                        __w->__parent_->__is_black_ = false;
-                        __tree_left_rotate(__w->__parent_);
+                        __w->__parent_unsafe()->__is_black_ = false;
+                        _VSTD::__tree_left_rotate(__w->__parent_unsafe());
                         // __x is still valid
                         // reset __root only if necessary
                         if (__root == __w->__left_)
@@ -412,7 +442,7 @@
                         (__w->__right_ == nullptr || __w->__right_->__is_black_))
                     {
                         __w->__is_black_ = false;
-                        __x = __w->__parent_;
+                        __x = __w->__parent_unsafe();
                         // __x can no longer be null
                         if (__x == __root || !__x->__is_black_)
                         {
@@ -420,8 +450,8 @@
                             break;
                         }
                         // reset sibling, and it still can't be null
-                        __w = __tree_is_left_child(__x) ?
-                                    __x->__parent_->__right_ :
+                        __w = _VSTD::__tree_is_left_child(__x) ?
+                                    __x->__parent_unsafe()->__right_ :
                                     __x->__parent_->__left_;
                         // continue;
                     }
@@ -432,16 +462,16 @@
                             // __w left child is non-null and red
                             __w->__left_->__is_black_ = true;
                             __w->__is_black_ = false;
-                            __tree_right_rotate(__w);
+                            _VSTD::__tree_right_rotate(__w);
                             // __w is known not to be root, so root hasn't changed
                             // reset sibling, and it still can't be null
-                            __w = __w->__parent_;
+                            __w = __w->__parent_unsafe();
                         }
                         // __w has a right red child, left child may be null
-                        __w->__is_black_ = __w->__parent_->__is_black_;
-                        __w->__parent_->__is_black_ = true;
+                        __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
+                        __w->__parent_unsafe()->__is_black_ = true;
                         __w->__right_->__is_black_ = true;
-                        __tree_left_rotate(__w->__parent_);
+                        _VSTD::__tree_left_rotate(__w->__parent_unsafe());
                         break;
                     }
                 }
@@ -450,8 +480,8 @@
                     if (!__w->__is_black_)
                     {
                         __w->__is_black_ = true;
-                        __w->__parent_->__is_black_ = false;
-                        __tree_right_rotate(__w->__parent_);
+                        __w->__parent_unsafe()->__is_black_ = false;
+                        _VSTD::__tree_right_rotate(__w->__parent_unsafe());
                         // __x is still valid
                         // reset __root only if necessary
                         if (__root == __w->__right_)
@@ -464,7 +494,7 @@
                         (__w->__right_ == nullptr || __w->__right_->__is_black_))
                     {
                         __w->__is_black_ = false;
-                        __x = __w->__parent_;
+                        __x = __w->__parent_unsafe();
                         // __x can no longer be null
                         if (!__x->__is_black_ || __x == __root)
                         {
@@ -472,8 +502,8 @@
                             break;
                         }
                         // reset sibling, and it still can't be null
-                        __w = __tree_is_left_child(__x) ?
-                                    __x->__parent_->__right_ :
+                        __w = _VSTD::__tree_is_left_child(__x) ?
+                                    __x->__parent_unsafe()->__right_ :
                                     __x->__parent_->__left_;
                         // continue;
                     }
@@ -484,16 +514,16 @@
                             // __w right child is non-null and red
                             __w->__right_->__is_black_ = true;
                             __w->__is_black_ = false;
-                            __tree_left_rotate(__w);
+                            _VSTD::__tree_left_rotate(__w);
                             // __w is known not to be root, so root hasn't changed
                             // reset sibling, and it still can't be null
-                            __w = __w->__parent_;
+                            __w = __w->__parent_unsafe();
                         }
                         // __w has a left red child, right child may be null
-                        __w->__is_black_ = __w->__parent_->__is_black_;
-                        __w->__parent_->__is_black_ = true;
+                        __w->__is_black_ = __w->__parent_unsafe()->__is_black_;
+                        __w->__parent_unsafe()->__is_black_ = true;
                         __w->__left_->__is_black_ = true;
-                        __tree_right_rotate(__w->__parent_);
+                        _VSTD::__tree_right_rotate(__w->__parent_unsafe());
                         break;
                     }
                 }
@@ -502,41 +532,174 @@
     }
 }
 
-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;
+
+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> {};
+
+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);
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  static __container_value_type&& __move(__node_value_type& __v) {
+    return _VSTD::move(__v);
+  }
+};
+
+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 __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.__get_value().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.__get_value();
+  }
+
+  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.__get_value());
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) {
+    return __v.__move();
+  }
+};
+
+template <class _VoidPtr>
+struct __tree_node_base_types {
+  typedef _VoidPtr                                               __void_pointer;
+
+  typedef __tree_node_base<__void_pointer>                      __node_base_type;
+  typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type
+                                                             __node_base_pointer;
+
+  typedef __tree_end_node<__node_base_pointer>                  __end_node_type;
+  typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type
+                                                             __end_node_pointer;
+#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
+  typedef __end_node_pointer __parent_pointer;
+#else
+  typedef typename conditional<
+      is_pointer<__end_node_pointer>::value,
+        __end_node_pointer,
+        __node_base_pointer>::type __parent_pointer;
+#endif
+
 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) _NOEXCEPT
-        : __na_(__na),
-          __value_constructed(false)
-        {}
+  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;
+#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
+  typedef typename __base::__end_node_pointer __iter_pointer;
+#else
+  typedef typename conditional<
+      is_pointer<__node_pointer>::value,
+        typename __base::__end_node_pointer,
+        __node_pointer>::type __iter_pointer;
+#endif
+private:
+    static_assert(!is_const<__node_type>::value,
+                "_NodePtr should never be a pointer to const");
+    static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type,
+                          _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr.");
+};
 
-    template <class> friend class __map_node_destructor;
+template <class _ValueTp, class _VoidPtr>
+struct __make_tree_node_types {
+  typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type
+                                                                        _NodePtr;
+  typedef __tree_node_types<_NodePtr> type;
 };
 
 // node
@@ -553,93 +716,116 @@
 };
 
 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
-             >
+class _LIBCPP_STANDALONE_DEBUG __tree_node_base
+    : public __tree_node_base_types<_VoidPtr>::__end_node_type
 {
-    __tree_node_base(const __tree_node_base&);
-    __tree_node_base& operator=(const __tree_node_base&);
-public:
-    typedef typename 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 __tree_node_base_types<_VoidPtr> _NodeBaseTypes;
 
-    pointer __right_;
-    pointer __parent_;
+public:
+    typedef typename _NodeBaseTypes::__node_base_pointer pointer;
+    typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer;
+
+    pointer          __right_;
+    __parent_pointer __parent_;
     bool __is_black_;
 
     _LIBCPP_INLINE_VISIBILITY
-    __tree_node_base() _NOEXCEPT
-        : __right_(), __parent_(), __is_black_(false) {}
+    pointer __parent_unsafe() const { return static_cast<pointer>(__parent_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __set_parent(pointer __p) {
+        __parent_ = static_cast<__parent_pointer>(__p);
+    }
+
+private:
+  ~__tree_node_base() _LIBCPP_EQUAL_DELETE;
+  __tree_node_base(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
+  __tree_node_base& operator=(__tree_node_base const&) _LIBCPP_EQUAL_DELETE;
 };
 
 template <class _Tp, class _VoidPtr>
-class __tree_node
+class _LIBCPP_STANDALONE_DEBUG __tree_node
     : public __tree_node_base<_VoidPtr>
 {
 public:
-    typedef __tree_node_base<_VoidPtr> base;
-    typedef _Tp value_type;
+    typedef _Tp __node_value_type;
 
-    value_type __value_;
+    __node_value_type __value_;
 
-#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_;
+
+
+public:
+    bool __value_constructed;
+
+
+    __tree_node_destructor(const __tree_node_destructor &) = default;
+    __tree_node_destructor& operator=(const __tree_node_destructor&) = delete;
+
+    _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;
+};
+
+#if _LIBCPP_STD_VER > 14
+template <class _NodeType, class _Alloc>
+struct __generic_container_node_destructor;
+template <class _Tp, class _VoidPtr, class _Alloc>
+struct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc>
+    : __tree_node_destructor<_Alloc>
+{
+    using __tree_node_destructor<_Alloc>::__tree_node_destructor;
+};
+#endif
 
 template <class _Tp, class _NodePtr, class _DiffType>
-class _LIBCPP_TYPE_VIS_ONLY __tree_iterator
+class _LIBCPP_TEMPLATE_VIS __tree_iterator
 {
-    typedef _NodePtr                                              __node_pointer;
-    typedef typename pointer_traits<__node_pointer>::element_type __node;
-    typedef typename __node::base                                 __node_base;
-    typedef typename __node_base::pointer                         __node_base_pointer;
-
-    __node_pointer __ptr_;
-
+    typedef __tree_node_types<_NodePtr>                     _NodeTypes;
+    typedef _NodePtr                                        __node_pointer;
+    typedef typename _NodeTypes::__node_base_pointer        __node_base_pointer;
+    typedef typename _NodeTypes::__end_node_pointer         __end_node_pointer;
+    typedef typename _NodeTypes::__iter_pointer             __iter_pointer;
     typedef pointer_traits<__node_pointer> __pointer_traits;
+
+    __iter_pointer __ptr_;
+
 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
@@ -647,27 +833,32 @@
 #endif
     {}
 
-    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;}
+    _LIBCPP_INLINE_VISIBILITY reference operator*() const
+        {return __get_np()->__value_;}
     _LIBCPP_INLINE_VISIBILITY pointer operator->() const
-        {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
+        {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
 
     _LIBCPP_INLINE_VISIBILITY
-    __tree_iterator& operator++()
-        {__ptr_ = static_cast<__node_pointer>(__tree_next(static_cast<__node_base_pointer>(__ptr_)));
-         return *this;}
+    __tree_iterator& operator++() {
+      __ptr_ = static_cast<__iter_pointer>(
+          _VSTD::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
+      return *this;
+    }
     _LIBCPP_INLINE_VISIBILITY
     __tree_iterator operator++(int)
         {__tree_iterator __t(*this); ++(*this); return __t;}
 
     _LIBCPP_INLINE_VISIBILITY
-    __tree_iterator& operator--()
-        {__ptr_ = static_cast<__node_pointer>(__tree_prev(static_cast<__node_base_pointer>(__ptr_)));
-         return *this;}
+    __tree_iterator& operator--() {
+      __ptr_ = static_cast<__iter_pointer>(_VSTD::__tree_prev_iter<__node_base_pointer>(
+          static_cast<__end_node_pointer>(__ptr_)));
+      return *this;
+    }
     _LIBCPP_INLINE_VISIBILITY
     __tree_iterator operator--(int)
         {__tree_iterator __t(*this); --(*this); return __t;}
 
-    friend _LIBCPP_INLINE_VISIBILITY 
+    friend _LIBCPP_INLINE_VISIBILITY
         bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)
         {return __x.__ptr_ == __y.__ptr_;}
     friend _LIBCPP_INLINE_VISIBILITY
@@ -677,44 +868,37 @@
 private:
     _LIBCPP_INLINE_VISIBILITY
     explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
     template <class, class, class> friend class __tree;
-    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;
-    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_iterator;
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
-    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;
-    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset;
+    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
+    template <class> friend class _LIBCPP_TEMPLATE_VIS __map_iterator;
+    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
+    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
+    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
+    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
 };
 
-template <class _Tp, class _ConstNodePtr, class _DiffType>
-class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator
+template <class _Tp, class _NodePtr, class _DiffType>
+class _LIBCPP_TEMPLATE_VIS __tree_const_iterator
 {
-    typedef _ConstNodePtr                                         __node_pointer;
-    typedef typename pointer_traits<__node_pointer>::element_type __node;
-    typedef typename __node::base                                 __node_base;
-    typedef typename pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<__node_base>
-#else
-            rebind<__node_base>::other
-#endif
-                                                                  __node_base_pointer;
-
-    __node_pointer __ptr_;
-
+    typedef __tree_node_types<_NodePtr>                     _NodeTypes;
+    typedef typename _NodeTypes::__node_pointer             __node_pointer;
+    typedef typename _NodeTypes::__node_base_pointer        __node_base_pointer;
+    typedef typename _NodeTypes::__end_node_pointer         __end_node_pointer;
+    typedef typename _NodeTypes::__iter_pointer             __iter_pointer;
     typedef pointer_traits<__node_pointer> __pointer_traits;
+
+    __iter_pointer __ptr_;
+
 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
@@ -723,37 +907,36 @@
     {}
 
 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
         : __ptr_(__p.__ptr_) {}
 
-    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;}
+    _LIBCPP_INLINE_VISIBILITY reference operator*() const
+        {return __get_np()->__value_;}
     _LIBCPP_INLINE_VISIBILITY pointer operator->() const
-        {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
+        {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);}
 
     _LIBCPP_INLINE_VISIBILITY
-    __tree_const_iterator& operator++()
-        {__ptr_ = static_cast<__node_pointer>(__tree_next(static_cast<__node_base_pointer>(__ptr_)));
-         return *this;}
+    __tree_const_iterator& operator++() {
+      __ptr_ = static_cast<__iter_pointer>(
+          _VSTD::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_)));
+      return *this;
+    }
+
     _LIBCPP_INLINE_VISIBILITY
     __tree_const_iterator operator++(int)
         {__tree_const_iterator __t(*this); ++(*this); return __t;}
 
     _LIBCPP_INLINE_VISIBILITY
-    __tree_const_iterator& operator--()
-        {__ptr_ = static_cast<__node_pointer>(__tree_prev(static_cast<__node_base_pointer>(__ptr_)));
-         return *this;}
+    __tree_const_iterator& operator--() {
+      __ptr_ = static_cast<__iter_pointer>(_VSTD::__tree_prev_iter<__node_base_pointer>(
+          static_cast<__end_node_pointer>(__ptr_)));
+      return *this;
+    }
+
     _LIBCPP_INLINE_VISIBILITY
     __tree_const_iterator operator--(int)
         {__tree_const_iterator __t(*this); --(*this); return __t;}
@@ -769,14 +952,28 @@
     _LIBCPP_INLINE_VISIBILITY
     explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT
         : __ptr_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT
+        : __ptr_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); }
+
     template <class, class, class> friend class __tree;
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
-    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;
-    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset;
-    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
+    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
+    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
+    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS set;
+    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS multiset;
+    template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
+
 };
 
+template<class _Tp, class _Compare>
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Compare const&, _Tp const&, _Tp const&>::value,
+        "the specified comparator type does not provide a viable const call operator")
+#endif
+int __diagnose_non_const_comparator();
+
 template <class _Tp, class _Compare, class _Allocator>
 class __tree
 {
@@ -784,65 +981,73 @@
     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 __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind_alloc<__node>
-#else
-            rebind_alloc<__node>::other
-#endif
-                                                     __node_allocator;
-    typedef allocator_traits<__node_allocator>       __node_traits;
-    typedef typename __node_traits::pointer          __node_pointer;
-    typedef typename __node_traits::pointer          __node_const_pointer;
-    typedef typename __node_base::pointer            __node_base_pointer;
-    typedef typename __node_base::pointer            __node_base_const_pointer;
+    typedef typename _NodeTypes::__node_type           __node;
+    typedef typename _NodeTypes::__node_pointer        __node_pointer;
+
+    typedef typename _NodeTypes::__node_base_type      __node_base;
+    typedef typename _NodeTypes::__node_base_pointer   __node_base_pointer;
+
+    typedef typename _NodeTypes::__end_node_type       __end_node_t;
+    typedef typename _NodeTypes::__end_node_pointer    __end_node_ptr;
+
+    typedef typename _NodeTypes::__parent_pointer      __parent_pointer;
+    typedef typename _NodeTypes::__iter_pointer        __iter_pointer;
+
+    typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
+    typedef allocator_traits<__node_allocator>         __node_traits;
+
 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;
+    // check for sane allocator pointer rebinding semantics. Rebinding the
+    // allocator for a new pointer type should be exactly the same as rebinding
+    // the pointer using 'pointer_traits'.
+    static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
+                  "Allocator does not rebind pointers in a sane manner.");
+    typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type
+        __node_base_allocator;
+    typedef allocator_traits<__node_base_allocator> __node_base_traits;
+    static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
+                 "Allocator does not rebind pointers in a sane manner.");
 
-    __node_pointer                                          __begin_node_;
+private:
+    __iter_pointer                                     __begin_node_;
     __compressed_pair<__end_node_t, __node_allocator>  __pair1_;
     __compressed_pair<size_type, value_compare>        __pair3_;
 
 public:
     _LIBCPP_INLINE_VISIBILITY
-    __node_pointer __end_node() _NOEXCEPT
+    __iter_pointer __end_node() _NOEXCEPT
     {
-        return static_cast<__node_pointer>
-               (
-                   pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
-               );
+        return static_cast<__iter_pointer>(
+                pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
+        );
     }
     _LIBCPP_INLINE_VISIBILITY
-    __node_const_pointer __end_node() const _NOEXCEPT
+    __iter_pointer __end_node() const _NOEXCEPT
     {
-        return static_cast<__node_const_pointer>
-               (
-                   pointer_traits<__end_node_const_ptr>::pointer_to(const_cast<__end_node_t&>(__pair1_.first()))
-               );
+        return static_cast<__iter_pointer>(
+            pointer_traits<__end_node_ptr>::pointer_to(
+                const_cast<__end_node_t&>(__pair1_.first())
+            )
+        );
     }
     _LIBCPP_INLINE_VISIBILITY
           __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();}
@@ -851,9 +1056,9 @@
     const __node_allocator& __node_alloc() const _NOEXCEPT
         {return __pair1_.second();}
     _LIBCPP_INLINE_VISIBILITY
-          __node_pointer& __begin_node() _NOEXCEPT {return __begin_node_;}
+          __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;}
     _LIBCPP_INLINE_VISIBILITY
-    const __node_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;}
+    const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;}
 public:
     _LIBCPP_INLINE_VISIBILITY
     allocator_type __alloc() const _NOEXCEPT
@@ -870,12 +1075,14 @@
     const value_compare& value_comp() const _NOEXCEPT
         {return __pair3_.second();}
 public:
+
     _LIBCPP_INLINE_VISIBILITY
-    __node_pointer __root() _NOEXCEPT
-        {return static_cast<__node_pointer>      (__end_node()->__left_);}
-    _LIBCPP_INLINE_VISIBILITY
-    __node_const_pointer __root() const _NOEXCEPT
-        {return static_cast<__node_const_pointer>(__end_node()->__left_);}
+    __node_pointer __root() const _NOEXCEPT
+        {return static_cast<__node_pointer>(__end_node()->__left_);}
+
+    __node_base_pointer* __root_ptr() const _NOEXCEPT {
+        return _VSTD::addressof(__end_node()->__left_);
+    }
 
     typedef __tree_iterator<value_type, __node_pointer, difference_type>             iterator;
     typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
@@ -888,11 +1095,10 @@
     __tree(const value_compare& __comp, const allocator_type& __a);
     __tree(const __tree& __t);
     __tree& operator=(const __tree& __t);
-    template <class _InputIterator>
-        void __assign_unique(_InputIterator __first, _InputIterator __last);
+    template <class _ForwardIterator>
+        void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
     template <class _InputIterator>
         void __assign_multi(_InputIterator __first, _InputIterator __last);
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     __tree(__tree&& __t)
         _NOEXCEPT_(
             is_nothrow_move_constructible<__node_allocator>::value &&
@@ -903,8 +1109,6 @@
             __node_traits::propagate_on_container_move_assignment::value &&
             is_nothrow_move_assignable<value_compare>::value &&
             is_nothrow_move_assignable<__node_allocator>::value);
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
     ~__tree();
 
     _LIBCPP_INLINE_VISIBILITY
@@ -918,55 +1122,235 @@
 
     _LIBCPP_INLINE_VISIBILITY
     size_type max_size() const _NOEXCEPT
-        {return __node_traits::max_size(__node_alloc());}
+        {return _VSTD::min<size_type>(
+                __node_traits::max_size(__node_alloc()),
+                numeric_limits<difference_type >::max());}
 
     void clear() _NOEXCEPT;
 
     void swap(__tree& __t)
+#if _LIBCPP_STD_VER <= 11
         _NOEXCEPT_(
-            __is_nothrow_swappable<value_compare>::value &&
-            (!__node_traits::propagate_on_container_swap::value ||
-             __is_nothrow_swappable<__node_allocator>::value));
+            __is_nothrow_swappable<value_compare>::value
+            && (!__node_traits::propagate_on_container_swap::value ||
+                 __is_nothrow_swappable<__node_allocator>::value)
+            );
+#else
+        _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value);
+#endif
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class _Key, class ..._Args>
+    pair<iterator, bool>
+    __emplace_unique_key_args(_Key const&, _Args&&... __args);
+    template <class _Key, class ..._Args>
+    pair<iterator, bool>
+    __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)).first;
+    }
+
     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)).first;
+    }
+
+    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)).first;
+    }
+
+    _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).first;
+    }
+
+    _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)).first;
+    }
+
+    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));
+    }
 
-    pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
-    iterator             __node_insert_unique(const_iterator __p,
-                                              __node_pointer __nd);
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> __node_assign_unique(const __container_value_type& __v, __node_pointer __dest);
 
+    _LIBCPP_INLINE_VISIBILITY
     iterator __node_insert_multi(__node_pointer __nd);
+    _LIBCPP_INLINE_VISIBILITY
     iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
 
+
+    _LIBCPP_INLINE_VISIBILITY iterator
+    __remove_node_pointer(__node_pointer) _NOEXCEPT;
+
+#if _LIBCPP_STD_VER > 14
+    template <class _NodeHandle, class _InsertReturnType>
+    _LIBCPP_INLINE_VISIBILITY
+    _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
+    template <class _NodeHandle>
+    _LIBCPP_INLINE_VISIBILITY
+    iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&);
+    template <class _Tree>
+    _LIBCPP_INLINE_VISIBILITY
+    void __node_handle_merge_unique(_Tree& __source);
+
+    template <class _NodeHandle>
+    _LIBCPP_INLINE_VISIBILITY
+    iterator __node_handle_insert_multi(_NodeHandle&&);
+    template <class _NodeHandle>
+    _LIBCPP_INLINE_VISIBILITY
+    iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&);
+    template <class _Tree>
+    _LIBCPP_INLINE_VISIBILITY
+    void __node_handle_merge_multi(_Tree& __source);
+
+
+    template <class _NodeHandle>
+    _LIBCPP_INLINE_VISIBILITY
+    _NodeHandle __node_handle_extract(key_type const&);
+    template <class _NodeHandle>
+    _LIBCPP_INLINE_VISIBILITY
+    _NodeHandle __node_handle_extract(const_iterator);
+#endif
+
     iterator erase(const_iterator __p);
     iterator erase(const_iterator __f, const_iterator __l);
     template <class _Key>
@@ -974,9 +1358,9 @@
     template <class _Key>
         size_type __erase_multi(const _Key& __k);
 
-    void __insert_node_at(__node_base_pointer __parent,
+    void __insert_node_at(__parent_pointer     __parent,
                           __node_base_pointer& __child,
-                          __node_base_pointer __new_node);
+                          __node_base_pointer __new_node) _NOEXCEPT;
 
     template <class _Key>
         iterator find(const _Key& __v);
@@ -995,15 +1379,15 @@
     template <class _Key>
         iterator __lower_bound(const _Key& __v,
                                __node_pointer __root,
-                               __node_pointer __result);
+                               __iter_pointer __result);
     template <class _Key>
         _LIBCPP_INLINE_VISIBILITY
         const_iterator lower_bound(const _Key& __v) const
             {return __lower_bound(__v, __root(), __end_node());}
     template <class _Key>
         const_iterator __lower_bound(const _Key& __v,
-                                     __node_const_pointer __root,
-                                     __node_const_pointer __result) const;
+                                     __node_pointer __root,
+                                     __iter_pointer __result) const;
     template <class _Key>
         _LIBCPP_INLINE_VISIBILITY
         iterator upper_bound(const _Key& __v)
@@ -1011,15 +1395,15 @@
     template <class _Key>
         iterator __upper_bound(const _Key& __v,
                                __node_pointer __root,
-                               __node_pointer __result);
+                               __iter_pointer __result);
     template <class _Key>
         _LIBCPP_INLINE_VISIBILITY
         const_iterator upper_bound(const _Key& __v) const
             {return __upper_bound(__v, __root(), __end_node());}
     template <class _Key>
         const_iterator __upper_bound(const _Key& __v,
-                                     __node_const_pointer __root,
-                                     __node_const_pointer __result) const;
+                                     __node_pointer __root,
+                                     __iter_pointer __result) const;
     template <class _Key>
         pair<iterator, iterator>
         __equal_range_unique(const _Key& __k);
@@ -1039,27 +1423,31 @@
 
     __node_holder remove(const_iterator __p) _NOEXCEPT;
 private:
-    typename __node_base::pointer&
-        __find_leaf_low(typename __node_base::pointer& __parent, const value_type& __v);
-    typename __node_base::pointer&
-        __find_leaf_high(typename __node_base::pointer& __parent, const value_type& __v);
-    typename __node_base::pointer&
+    __node_base_pointer&
+        __find_leaf_low(__parent_pointer& __parent, const key_type& __v);
+    __node_base_pointer&
+        __find_leaf_high(__parent_pointer& __parent, const key_type& __v);
+    __node_base_pointer&
         __find_leaf(const_iterator __hint,
-                    typename __node_base::pointer& __parent, const value_type& __v);
+                    __parent_pointer& __parent, const key_type& __v);
+    // FIXME: Make this function const qualified. Unfortunately doing so
+    // breaks existing code which uses non-const callable comparators.
     template <class _Key>
-        typename __node_base::pointer&
-        __find_equal(typename __node_base::pointer& __parent, const _Key& __v);
+    __node_base_pointer&
+        __find_equal(__parent_pointer& __parent, const _Key& __v);
     template <class _Key>
-        typename __node_base::pointer&
-        __find_equal(const_iterator __hint, typename __node_base::pointer& __parent,
+    _LIBCPP_INLINE_VISIBILITY __node_base_pointer&
+    __find_equal(__parent_pointer& __parent, const _Key& __v) const {
+      return const_cast<__tree*>(this)->__find_equal(__parent, __v);
+    }
+    template <class _Key>
+    __node_base_pointer&
+        __find_equal(const_iterator __hint, __parent_pointer& __parent,
+                     __node_base_pointer& __dummy,
                      const _Key& __v);
 
-#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
     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);
-#endif
+    __node_holder __construct_node(_Args&& ...__args);
 
     void destroy(__node_pointer __nd) _NOEXCEPT;
 
@@ -1070,9 +1458,13 @@
 
     _LIBCPP_INLINE_VISIBILITY
     void __copy_assign_alloc(const __tree& __t, true_type)
-        {__node_alloc() = __t.__node_alloc();}
+        {
+        if (__node_alloc() != __t.__node_alloc())
+            clear();
+        __node_alloc() = __t.__node_alloc();
+        }
     _LIBCPP_INLINE_VISIBILITY
-    void __copy_assign_alloc(const __tree& __t, false_type) {}
+    void __copy_assign_alloc(const __tree&, false_type) {}
 
     void __move_assign(__tree& __t, false_type);
     void __move_assign(__tree& __t, true_type)
@@ -1092,32 +1484,55 @@
         _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
         {__node_alloc() = _VSTD::move(__t.__node_alloc());}
     _LIBCPP_INLINE_VISIBILITY
-    void __move_assign_alloc(__tree& __t, false_type) _NOEXCEPT {}
+    void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
 
-    _LIBCPP_INLINE_VISIBILITY
-    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
-        _NOEXCEPT_(
-            !__node_traits::propagate_on_container_swap::value ||
-            __is_nothrow_swappable<__node_allocator>::value)
-        {__swap_alloc(__x, __y, integral_constant<bool,
-                      __node_traits::propagate_on_container_swap::value>());}
-    _LIBCPP_INLINE_VISIBILITY
-    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, true_type)
-        _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
-        {
-            using _VSTD::swap;
-            swap(__x, __y);
+    struct _DetachedTreeCache {
+      _LIBCPP_INLINE_VISIBILITY
+      explicit _DetachedTreeCache(__tree *__t) _NOEXCEPT : __t_(__t),
+        __cache_root_(__detach_from_tree(__t)) {
+          __advance();
         }
-    _LIBCPP_INLINE_VISIBILITY
-    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, false_type)
-        _NOEXCEPT
-        {}
 
-    __node_pointer __detach();
-    static __node_pointer __detach(__node_pointer);
+      _LIBCPP_INLINE_VISIBILITY
+      __node_pointer __get() const _NOEXCEPT {
+        return __cache_elem_;
+      }
 
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
+      _LIBCPP_INLINE_VISIBILITY
+      void __advance() _NOEXCEPT {
+        __cache_elem_ = __cache_root_;
+        if (__cache_root_) {
+          __cache_root_ = __detach_next(__cache_root_);
+        }
+      }
+
+      _LIBCPP_INLINE_VISIBILITY
+      ~_DetachedTreeCache() {
+        __t_->destroy(__cache_elem_);
+        if (__cache_root_) {
+          while (__cache_root_->__parent_ != nullptr)
+            __cache_root_ = static_cast<__node_pointer>(__cache_root_->__parent_);
+          __t_->destroy(__cache_root_);
+        }
+      }
+
+       _DetachedTreeCache(_DetachedTreeCache const&) = delete;
+       _DetachedTreeCache& operator=(_DetachedTreeCache const&) = delete;
+
+    private:
+      _LIBCPP_INLINE_VISIBILITY
+      static __node_pointer __detach_from_tree(__tree *__t) _NOEXCEPT;
+      _LIBCPP_INLINE_VISIBILITY
+      static __node_pointer __detach_next(__node_pointer) _NOEXCEPT;
+
+      __tree *__t_;
+      __node_pointer __cache_root_;
+      __node_pointer __cache_elem_;
+    };
+
+
+    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
+    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
 };
 
 template <class _Tp, class _Compare, class _Allocator>
@@ -1132,9 +1547,9 @@
 
 template <class _Tp, class _Compare, class _Allocator>
 __tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
-    : __pair1_(__node_allocator(__a)),
-      __begin_node_(__node_pointer()),
-      __pair3_(0)
+    : __begin_node_(__iter_pointer()),
+      __pair1_(__default_init_tag(), __node_allocator(__a)),
+      __pair3_(0, __default_init_tag())
 {
     __begin_node() = __end_node();
 }
@@ -1142,8 +1557,8 @@
 template <class _Tp, class _Compare, class _Allocator>
 __tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,
                                            const allocator_type& __a)
-    : __pair1_(__node_allocator(__a)),
-      __begin_node_(__node_pointer()),
+    : __begin_node_(__iter_pointer()),
+      __pair1_(__default_init_tag(), __node_allocator(__a)),
       __pair3_(0, __comp)
 {
     __begin_node() = __end_node();
@@ -1152,13 +1567,13 @@
 // Precondition:  size() != 0
 template <class _Tp, class _Compare, class _Allocator>
 typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
-__tree<_Tp, _Compare, _Allocator>::__detach()
+__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_from_tree(__tree *__t) _NOEXCEPT
 {
-    __node_pointer __cache = __begin_node();
-    __begin_node() = __end_node();
-    __end_node()->__left_->__parent_ = nullptr;
-    __end_node()->__left_ = nullptr;
-    size() = 0;
+    __node_pointer __cache = static_cast<__node_pointer>(__t->__begin_node());
+    __t->__begin_node() = __t->__end_node();
+    __t->__end_node()->__left_->__parent_ = nullptr;
+    __t->__end_node()->__left_ = nullptr;
+    __t->size() = 0;
     // __cache->__left_ == nullptr
     if (__cache->__right_ != nullptr)
         __cache = static_cast<__node_pointer>(__cache->__right_);
@@ -1173,24 +1588,24 @@
 //    This is no longer a red-black tree
 template <class _Tp, class _Compare, class _Allocator>
 typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
-__tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache)
+__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_next(__node_pointer __cache) _NOEXCEPT
 {
     if (__cache->__parent_ == nullptr)
         return nullptr;
-    if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))
+    if (_VSTD::__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))
     {
         __cache->__parent_->__left_ = nullptr;
         __cache = static_cast<__node_pointer>(__cache->__parent_);
         if (__cache->__right_ == nullptr)
             return __cache;
-        return static_cast<__node_pointer>(__tree_leaf(__cache->__right_));
+        return static_cast<__node_pointer>(_VSTD::__tree_leaf(__cache->__right_));
     }
     // __cache is right child
-    __cache->__parent_->__right_ = nullptr;
+    __cache->__parent_unsafe()->__right_ = nullptr;
     __cache = static_cast<__node_pointer>(__cache->__parent_);
     if (__cache->__left_ == nullptr)
         return __cache;
-    return static_cast<__node_pointer>(__tree_leaf(__cache->__left_));
+    return static_cast<__node_pointer>(_VSTD::__tree_leaf(__cache->__left_));
 }
 
 template <class _Tp, class _Compare, class _Allocator>
@@ -1207,40 +1622,23 @@
 }
 
 template <class _Tp, class _Compare, class _Allocator>
-template <class _InputIterator>
+template <class _ForwardIterator>
 void
-__tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last)
+__tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _ForwardIterator __last)
 {
+    typedef iterator_traits<_ForwardIterator> _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");
+    static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
+                  "__assign_unique requires a forward iterator");
     if (size() != 0)
     {
-        __node_pointer __cache = __detach();
-#ifndef _LIBCPP_NO_EXCEPTIONS
-        try
-        {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-            for (; __cache != nullptr && __first != __last; ++__first)
-            {
-                __cache->__value_ = *__first;
-                __node_pointer __next = __detach(__cache);
-                __node_insert_unique(__cache);
-                __cache = __next;
+        _DetachedTreeCache __cache(this);
+          for (; __cache.__get() != nullptr && __first != __last; ++__first) {
+              if (__node_assign_unique(*__first, __cache.__get()).second)
+                  __cache.__advance();
             }
-#ifndef _LIBCPP_NO_EXCEPTIONS
-        }
-        catch (...)
-        {
-            while (__cache->__parent_ != nullptr)
-                __cache = static_cast<__node_pointer>(__cache->__parent_);
-            destroy(__cache);
-            throw;
-        }
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        if (__cache != nullptr)
-        {
-            while (__cache->__parent_ != nullptr)
-                __cache = static_cast<__node_pointer>(__cache->__parent_);
-            destroy(__cache);
-        }
     }
     for (; __first != __last; ++__first)
         __insert_unique(*__first);
@@ -1251,52 +1649,34 @@
 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();
-#ifndef _LIBCPP_NO_EXCEPTIONS
-        try
-        {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-            for (; __cache != nullptr && __first != __last; ++__first)
-            {
-                __cache->__value_ = *__first;
-                __node_pointer __next = __detach(__cache);
-                __node_insert_multi(__cache);
-                __cache = __next;
-            }
-#ifndef _LIBCPP_NO_EXCEPTIONS
-        }
-        catch (...)
-        {
-            while (__cache->__parent_ != nullptr)
-                __cache = static_cast<__node_pointer>(__cache->__parent_);
-            destroy(__cache);
-            throw;
-        }
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        if (__cache != nullptr)
-        {
-            while (__cache->__parent_ != nullptr)
-                __cache = static_cast<__node_pointer>(__cache->__parent_);
-            destroy(__cache);
+        _DetachedTreeCache __cache(this);
+        for (; __cache.__get() && __first != __last; ++__first) {
+            __cache.__get()->__value_ = *__first;
+            __node_insert_multi(__cache.__get());
+            __cache.__advance();
         }
     }
     for (; __first != __last; ++__first)
-        __insert_multi(*__first);
+        __insert_multi(_NodeTypes::__get_value(*__first));
 }
 
 template <class _Tp, class _Compare, class _Allocator>
 __tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
-    : __begin_node_(__node_pointer()),
-      __pair1_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())),
+    : __begin_node_(__iter_pointer()),
+      __pair1_(__default_init_tag(), __node_traits::select_on_container_copy_construction(__t.__node_alloc())),
       __pair3_(0, __t.value_comp())
 {
     __begin_node() = __end_node();
 }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Tp, class _Compare, class _Allocator>
 __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
     _NOEXCEPT_(
@@ -1310,7 +1690,7 @@
         __begin_node() = __end_node();
     else
     {
-        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
+        __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
         __t.__begin_node() = __t.__end_node();
         __t.__end_node()->__left_ = nullptr;
         __t.size() = 0;
@@ -1319,7 +1699,7 @@
 
 template <class _Tp, class _Compare, class _Allocator>
 __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
-    : __pair1_(__node_allocator(__a)),
+    : __pair1_(__default_init_tag(), __node_allocator(__a)),
       __pair3_(0, _VSTD::move(__t.value_comp()))
 {
     if (__a == __t.__alloc())
@@ -1330,7 +1710,7 @@
         {
             __begin_node() = __t.__begin_node();
             __end_node()->__left_ = __t.__end_node()->__left_;
-            __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
+            __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
             size() = __t.size();
             __t.__begin_node() = __t.__end_node();
             __t.__end_node()->__left_ = nullptr;
@@ -1358,7 +1738,7 @@
         __begin_node() = __end_node();
     else
     {
-        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
+        __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
         __t.__begin_node() = __t.__end_node();
         __t.__end_node()->__left_ = nullptr;
         __t.size() = 0;
@@ -1377,37 +1757,15 @@
         const_iterator __e = end();
         if (size() != 0)
         {
-            __node_pointer __cache = __detach();
-#ifndef _LIBCPP_NO_EXCEPTIONS
-            try
-            {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-                while (__cache != nullptr && __t.size() != 0)
-                {
-                    __cache->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_);
-                    __node_pointer __next = __detach(__cache);
-                    __node_insert_multi(__cache);
-                    __cache = __next;
-                }
-#ifndef _LIBCPP_NO_EXCEPTIONS
-            }
-            catch (...)
-            {
-                while (__cache->__parent_ != nullptr)
-                    __cache = static_cast<__node_pointer>(__cache->__parent_);
-                destroy(__cache);
-                throw;
-            }
-#endif  // _LIBCPP_NO_EXCEPTIONS
-            if (__cache != nullptr)
-            {
-                while (__cache->__parent_ != nullptr)
-                    __cache = static_cast<__node_pointer>(__cache->__parent_);
-                destroy(__cache);
+            _DetachedTreeCache __cache(this);
+            while (__cache.__get() != nullptr && __t.size() != 0) {
+              __cache.__get()->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_);
+              __node_insert_multi(__cache.__get());
+              __cache.__advance();
             }
         }
         while (__t.size() != 0)
-            __insert_multi(__e, _VSTD::move(__t.remove(__t.begin())->__value_));
+            __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_));
     }
 }
 
@@ -1418,19 +1776,19 @@
         __node_traits::propagate_on_container_move_assignment::value &&
         is_nothrow_move_assignable<value_compare>::value &&
         is_nothrow_move_assignable<__node_allocator>::value)
-        
+
 {
     __move_assign(__t, integral_constant<bool,
                   __node_traits::propagate_on_container_move_assignment::value>());
     return *this;
 }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Tp, class _Compare, class _Allocator>
 __tree<_Tp, _Compare, _Allocator>::~__tree()
 {
-    destroy(__root());
+    static_assert((is_copy_constructible<value_compare>::value),
+                 "Comparator must be copy-constructible.");
+  destroy(__root());
 }
 
 template <class _Tp, class _Compare, class _Allocator>
@@ -1442,7 +1800,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);
     }
 }
@@ -1450,24 +1808,29 @@
 template <class _Tp, class _Compare, class _Allocator>
 void
 __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
-    _NOEXCEPT_(
-        __is_nothrow_swappable<value_compare>::value &&
-        (!__node_traits::propagate_on_container_swap::value ||
-         __is_nothrow_swappable<__node_allocator>::value))
+#if _LIBCPP_STD_VER <= 11
+        _NOEXCEPT_(
+            __is_nothrow_swappable<value_compare>::value
+            && (!__node_traits::propagate_on_container_swap::value ||
+                 __is_nothrow_swappable<__node_allocator>::value)
+            )
+#else
+        _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value)
+#endif
 {
     using _VSTD::swap;
     swap(__begin_node_, __t.__begin_node_);
     swap(__pair1_.first(), __t.__pair1_.first());
-    __swap_alloc(__node_alloc(), __t.__node_alloc());
+    _VSTD::__swap_allocator(__node_alloc(), __t.__node_alloc());
     __pair3_.swap(__t.__pair3_);
     if (size() == 0)
         __begin_node() = __end_node();
     else
-        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
+        __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node());
     if (__t.size() == 0)
         __t.__begin_node() = __t.__end_node();
     else
-        __t.__end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__t.__end_node());
+        __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node());
 }
 
 template <class _Tp, class _Compare, class _Allocator>
@@ -1484,9 +1847,9 @@
 // Set __parent to parent of null leaf
 // Return reference to null leaf
 template <class _Tp, class _Compare, class _Allocator>
-typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
-__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node_base::pointer& __parent,
-                                                   const value_type& __v)
+typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
+__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent,
+                                                   const key_type& __v)
 {
     __node_pointer __nd = __root();
     if (__nd != nullptr)
@@ -1499,8 +1862,8 @@
                     __nd = static_cast<__node_pointer>(__nd->__right_);
                 else
                 {
-                    __parent = static_cast<__node_base_pointer>(__nd);
-                    return __parent->__right_;
+                    __parent = static_cast<__parent_pointer>(__nd);
+                    return __nd->__right_;
                 }
             }
             else
@@ -1509,13 +1872,13 @@
                     __nd = static_cast<__node_pointer>(__nd->__left_);
                 else
                 {
-                    __parent = static_cast<__node_base_pointer>(__nd);
+                    __parent = static_cast<__parent_pointer>(__nd);
                     return __parent->__left_;
                 }
             }
         }
     }
-    __parent = static_cast<__node_base_pointer>(__end_node());
+    __parent = static_cast<__parent_pointer>(__end_node());
     return __parent->__left_;
 }
 
@@ -1523,9 +1886,9 @@
 // Set __parent to parent of null leaf
 // Return reference to null leaf
 template <class _Tp, class _Compare, class _Allocator>
-typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
-__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node_base::pointer& __parent,
-                                                    const value_type& __v)
+typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
+__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent,
+                                                    const key_type& __v)
 {
     __node_pointer __nd = __root();
     if (__nd != nullptr)
@@ -1538,7 +1901,7 @@
                     __nd = static_cast<__node_pointer>(__nd->__left_);
                 else
                 {
-                    __parent = static_cast<__node_base_pointer>(__nd);
+                    __parent = static_cast<__parent_pointer>(__nd);
                     return __parent->__left_;
                 }
             }
@@ -1548,13 +1911,13 @@
                     __nd = static_cast<__node_pointer>(__nd->__right_);
                 else
                 {
-                    __parent = static_cast<__node_base_pointer>(__nd);
-                    return __parent->__right_;
+                    __parent = static_cast<__parent_pointer>(__nd);
+                    return __nd->__right_;
                 }
             }
         }
     }
-    __parent = static_cast<__node_base_pointer>(__end_node());
+    __parent = static_cast<__parent_pointer>(__end_node());
     return __parent->__left_;
 }
 
@@ -1565,10 +1928,10 @@
 // Set __parent to parent of null leaf
 // Return reference to null leaf
 template <class _Tp, class _Compare, class _Allocator>
-typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
+typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
 __tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,
-                                               typename __node_base::pointer& __parent,
-                                               const value_type& __v)
+                                               __parent_pointer& __parent,
+                                               const key_type& __v)
 {
     if (__hint == end() || !value_comp()(*__hint, __v))  // check before
     {
@@ -1579,13 +1942,13 @@
             // *prev(__hint) <= __v <= *__hint
             if (__hint.__ptr_->__left_ == nullptr)
             {
-                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
+                __parent = static_cast<__parent_pointer>(__hint.__ptr_);
                 return __parent->__left_;
             }
             else
             {
-                __parent = static_cast<__node_base_pointer>(__prior.__ptr_);
-                return __parent->__right_;
+                __parent = static_cast<__parent_pointer>(__prior.__ptr_);
+                return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
             }
         }
         // __v < *prev(__hint)
@@ -1601,43 +1964,44 @@
 // If __v exists, set parent to node of __v and return reference to node of __v
 template <class _Tp, class _Compare, class _Allocator>
 template <class _Key>
-typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
-__tree<_Tp, _Compare, _Allocator>::__find_equal(typename __node_base::pointer& __parent,
+typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
+__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent,
                                                 const _Key& __v)
 {
     __node_pointer __nd = __root();
+    __node_base_pointer* __nd_ptr = __root_ptr();
     if (__nd != nullptr)
     {
         while (true)
         {
             if (value_comp()(__v, __nd->__value_))
             {
-                if (__nd->__left_ != nullptr)
+                if (__nd->__left_ != nullptr) {
+                    __nd_ptr = _VSTD::addressof(__nd->__left_);
                     __nd = static_cast<__node_pointer>(__nd->__left_);
-                else
-                {
-                    __parent = static_cast<__node_base_pointer>(__nd);
+                } else {
+                    __parent = static_cast<__parent_pointer>(__nd);
                     return __parent->__left_;
                 }
             }
             else if (value_comp()(__nd->__value_, __v))
             {
-                if (__nd->__right_ != nullptr)
+                if (__nd->__right_ != nullptr) {
+                    __nd_ptr = _VSTD::addressof(__nd->__right_);
                     __nd = static_cast<__node_pointer>(__nd->__right_);
-                else
-                {
-                    __parent = static_cast<__node_base_pointer>(__nd);
-                    return __parent->__right_;
+                } else {
+                    __parent = static_cast<__parent_pointer>(__nd);
+                    return __nd->__right_;
                 }
             }
             else
             {
-                __parent = static_cast<__node_base_pointer>(__nd);
-                return __parent;
+                __parent = static_cast<__parent_pointer>(__nd);
+                return *__nd_ptr;
             }
         }
     }
-    __parent = static_cast<__node_base_pointer>(__end_node());
+    __parent = static_cast<__parent_pointer>(__end_node());
     return __parent->__left_;
 }
 
@@ -1650,9 +2014,10 @@
 // If __v exists, set parent to node of __v and return reference to node of __v
 template <class _Tp, class _Compare, class _Allocator>
 template <class _Key>
-typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
+typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
 __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
-                                                typename __node_base::pointer& __parent,
+                                                __parent_pointer& __parent,
+                                                __node_base_pointer& __dummy,
                                                 const _Key& __v)
 {
     if (__hint == end() || value_comp()(__v, *__hint))  // check before
@@ -1664,13 +2029,13 @@
             // *prev(__hint) < __v < *__hint
             if (__hint.__ptr_->__left_ == nullptr)
             {
-                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
+                __parent = static_cast<__parent_pointer>(__hint.__ptr_);
                 return __parent->__left_;
             }
             else
             {
-                __parent = static_cast<__node_base_pointer>(__prior.__ptr_);
-                return __parent->__right_;
+                __parent = static_cast<__parent_pointer>(__prior.__ptr_);
+                return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
             }
         }
         // __v <= *prev(__hint)
@@ -1683,14 +2048,14 @@
         if (__next == end() || value_comp()(__v, *__next))
         {
             // *__hint < __v < *_VSTD::next(__hint)
-            if (__hint.__ptr_->__right_ == nullptr)
+            if (__hint.__get_np()->__right_ == nullptr)
             {
-                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
-                return __parent->__right_;
+                __parent = static_cast<__parent_pointer>(__hint.__ptr_);
+                return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_;
             }
             else
             {
-                __parent = static_cast<__node_base_pointer>(__next.__ptr_);
+                __parent = static_cast<__parent_pointer>(__next.__ptr_);
                 return __parent->__left_;
             }
         }
@@ -1698,48 +2063,89 @@
         return __find_equal(__parent, __v);
     }
     // else __v == *__hint
-    __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
-    return __parent;
+    __parent = static_cast<__parent_pointer>(__hint.__ptr_);
+    __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
+    return __dummy;
 }
 
 template <class _Tp, class _Compare, class _Allocator>
-void
-__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__node_base_pointer __parent,
-                                                    __node_base_pointer& __child,
-                                                    __node_base_pointer __new_node)
+void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
+    __parent_pointer __parent, __node_base_pointer& __child,
+    __node_base_pointer __new_node) _NOEXCEPT
 {
     __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_);
-    __tree_balance_after_insert(__end_node()->__left_, __child);
+        __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_);
+    _VSTD::__tree_balance_after_insert(__end_node()->__left_, __child);
     ++size();
 }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+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)
+{
+    __parent_pointer __parent;
+    __node_base_pointer& __child = __find_equal(__parent, __k);
+    __node_pointer __r = static_cast<__node_pointer>(__child);
+    bool __inserted = false;
+    if (__child == nullptr)
+    {
+        __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+        __r = __h.release();
+        __inserted = true;
+    }
+    return pair<iterator, bool>(iterator(__r), __inserted);
+}
+
+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_hint_unique_key_args(
+    const_iterator __p, _Key const& __k, _Args&&... __args)
+{
+    __parent_pointer __parent;
+    __node_base_pointer __dummy;
+    __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k);
+    __node_pointer __r = static_cast<__node_pointer>(__child);
+    bool __inserted = false;
+    if (__child == nullptr)
+    {
+        __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+        __r = __h.release();
+        __inserted = true;
+    }
+    return pair<iterator, bool>(iterator(__r), __inserted);
+}
 
 template <class _Tp, class _Compare, class _Allocator>
 template <class ..._Args>
 typename __tree<_Tp, _Compare, _Allocator>::__node_holder
 __tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)
 {
+    static_assert(!__is_tree_value_type<_Args...>::value,
+                  "Cannot construct from __value_type");
     __node_allocator& __na = __node_alloc();
     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...);
+    __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
     __h.get_deleter().__value_constructed = true;
     return __h;
 }
 
+
 template <class _Tp, class _Compare, class _Allocator>
 template <class... _Args>
 pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
-__tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args)
+__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args)
 {
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
-    __node_base_pointer __parent;
+    __parent_pointer __parent;
     __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
     __node_pointer __r = static_cast<__node_pointer>(__child);
     bool __inserted = false;
@@ -1755,11 +2161,12 @@
 template <class _Tp, class _Compare, class _Allocator>
 template <class... _Args>
 typename __tree<_Tp, _Compare, _Allocator>::iterator
-__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique(const_iterator __p, _Args&&... __args)
+__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args)
 {
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
-    __node_base_pointer __parent;
-    __node_base_pointer& __child = __find_equal(__p, __parent, __h->__value_);
+    __parent_pointer __parent;
+    __node_base_pointer __dummy;
+    __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
     __node_pointer __r = static_cast<__node_pointer>(__child);
     if (__child == nullptr)
     {
@@ -1775,8 +2182,8 @@
 __tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)
 {
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
-    __node_base_pointer __parent;
-    __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
+    __parent_pointer __parent;
+    __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_));
     __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
     return iterator(static_cast<__node_pointer>(__h.release()));
 }
@@ -1788,143 +2195,23 @@
                                                         _Args&&... __args)
 {
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
-    __node_base_pointer __parent;
-    __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
+    __parent_pointer __parent;
+    __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_));
     __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
     return iterator(static_cast<__node_pointer>(__h.release()));
 }
 
-#endif  // _LIBCPP_HAS_NO_VARIADICS
-
-template <class _Tp, class _Compare, class _Allocator>
-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
-
-template <class _Tp, class _Compare, class _Allocator>
-typename __tree<_Tp, _Compare, _Allocator>::__node_holder
-__tree<_Tp, _Compare, _Allocator>::__construct_node(const 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);
-    __h.get_deleter().__value_constructed = true;
-    return _VSTD::move(__h);  // explicitly moved for C++03
-}
-
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Tp, class _Compare, class _Allocator>
 pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
-__tree<_Tp, _Compare, _Allocator>::__insert_unique(const value_type& __v)
+__tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const __container_value_type& __v, __node_pointer __nd)
 {
-    __node_base_pointer __parent;
-    __node_base_pointer& __child = __find_equal(__parent, __v);
+    __parent_pointer __parent;
+    __node_base_pointer& __child = __find_equal(__parent, _NodeTypes::__get_key(__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);
-}
-
-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)
-{
-    __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_holder __h = __construct_node(__v);
-    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
-    return iterator(__h.release());
-}
-
-template <class _Tp, class _Compare, class _Allocator>
-typename __tree<_Tp, _Compare, _Allocator>::iterator
-__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const value_type& __v)
-{
-    __node_base_pointer __parent;
-    __node_base_pointer& __child = __find_leaf(__p, __parent, __v);
-    __node_holder __h = __construct_node(__v);
-    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
-    return iterator(__h.release());
-}
-
-template <class _Tp, class _Compare, class _Allocator>
-pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
-__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd)
-{
-    __node_base_pointer __parent;
-    __node_base_pointer& __child = __find_equal(__parent, __nd->__value_);
-    __node_pointer __r = static_cast<__node_pointer>(__child);
-    bool __inserted = false;
-    if (__child == nullptr)
-    {
+        __nd->__value_ = __v;
         __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
         __r = __nd;
         __inserted = true;
@@ -1932,28 +2219,13 @@
     return pair<iterator, bool>(iterator(__r), __inserted);
 }
 
-template <class _Tp, class _Compare, class _Allocator>
-typename __tree<_Tp, _Compare, _Allocator>::iterator
-__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p,
-                                                        __node_pointer __nd)
-{
-    __node_base_pointer __parent;
-    __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_);
-    __node_pointer __r = static_cast<__node_pointer>(__child);
-    if (__child == nullptr)
-    {
-        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
-        __r = __nd;
-    }
-    return iterator(__r);
-}
 
 template <class _Tp, class _Compare, class _Allocator>
 typename __tree<_Tp, _Compare, _Allocator>::iterator
 __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
 {
-    __node_base_pointer __parent;
-    __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_);
+    __parent_pointer __parent;
+    __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_));
     __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
     return iterator(__nd);
 }
@@ -1963,26 +2235,194 @@
 __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
                                                        __node_pointer __nd)
 {
-    __node_base_pointer __parent;
-    __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_);
+    __parent_pointer __parent;
+    __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_));
     __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
     return iterator(__nd);
 }
 
 template <class _Tp, class _Compare, class _Allocator>
 typename __tree<_Tp, _Compare, _Allocator>::iterator
-__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
+__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT
 {
-    __node_pointer __np = __p.__ptr_;
-    iterator __r(__np);
+    iterator __r(__ptr);
     ++__r;
-    if (__begin_node() == __np)
+    if (__begin_node() == __ptr)
         __begin_node() = __r.__ptr_;
     --size();
+    _VSTD::__tree_remove(__end_node()->__left_,
+                         static_cast<__node_base_pointer>(__ptr));
+    return __r;
+}
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, class _Compare, class _Allocator>
+template <class _NodeHandle, class _InsertReturnType>
+_LIBCPP_INLINE_VISIBILITY
+_InsertReturnType
+__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
+    _NodeHandle&& __nh)
+{
+    if (__nh.empty())
+        return _InsertReturnType{end(), false, _NodeHandle()};
+
+    __node_pointer __ptr = __nh.__ptr_;
+    __parent_pointer __parent;
+    __node_base_pointer& __child = __find_equal(__parent,
+                                                __ptr->__value_);
+    if (__child != nullptr)
+        return _InsertReturnType{
+            iterator(static_cast<__node_pointer>(__child)),
+            false, _VSTD::move(__nh)};
+
+    __insert_node_at(__parent, __child,
+                     static_cast<__node_base_pointer>(__ptr));
+    __nh.__release_ptr();
+    return _InsertReturnType{iterator(__ptr), true, _NodeHandle()};
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
+    const_iterator __hint, _NodeHandle&& __nh)
+{
+    if (__nh.empty())
+        return end();
+
+    __node_pointer __ptr = __nh.__ptr_;
+    __parent_pointer __parent;
+    __node_base_pointer __dummy;
+    __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy,
+                                                __ptr->__value_);
+    __node_pointer __r = static_cast<__node_pointer>(__child);
+    if (__child == nullptr)
+    {
+        __insert_node_at(__parent, __child,
+                         static_cast<__node_base_pointer>(__ptr));
+        __r = __ptr;
+        __nh.__release_ptr();
+    }
+    return iterator(__r);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+_NodeHandle
+__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key)
+{
+    iterator __it = find(__key);
+    if (__it == end())
+        return _NodeHandle();
+    return __node_handle_extract<_NodeHandle>(__it);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+_NodeHandle
+__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p)
+{
+    __node_pointer __np = __p.__get_np();
+    __remove_node_pointer(__np);
+    return _NodeHandle(__np, __alloc());
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Tree>
+_LIBCPP_INLINE_VISIBILITY
+void
+__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source)
+{
+    static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
+
+    for (typename _Tree::iterator __i = __source.begin();
+         __i != __source.end();)
+    {
+        __node_pointer __src_ptr = __i.__get_np();
+        __parent_pointer __parent;
+        __node_base_pointer& __child =
+            __find_equal(__parent, _NodeTypes::__get_key(__src_ptr->__value_));
+        ++__i;
+        if (__child != nullptr)
+            continue;
+        __source.__remove_node_pointer(__src_ptr);
+        __insert_node_at(__parent, __child,
+                         static_cast<__node_base_pointer>(__src_ptr));
+    }
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh)
+{
+    if (__nh.empty())
+        return end();
+    __node_pointer __ptr = __nh.__ptr_;
+    __parent_pointer __parent;
+    __node_base_pointer& __child = __find_leaf_high(
+        __parent, _NodeTypes::__get_key(__ptr->__value_));
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
+    __nh.__release_ptr();
+    return iterator(__ptr);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(
+    const_iterator __hint, _NodeHandle&& __nh)
+{
+    if (__nh.empty())
+        return end();
+
+    __node_pointer __ptr = __nh.__ptr_;
+    __parent_pointer __parent;
+    __node_base_pointer& __child = __find_leaf(__hint, __parent,
+                                               _NodeTypes::__get_key(__ptr->__value_));
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
+    __nh.__release_ptr();
+    return iterator(__ptr);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Tree>
+_LIBCPP_INLINE_VISIBILITY
+void
+__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source)
+{
+    static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
+
+    for (typename _Tree::iterator __i = __source.begin();
+         __i != __source.end();)
+    {
+        __node_pointer __src_ptr = __i.__get_np();
+        __parent_pointer __parent;
+        __node_base_pointer& __child = __find_leaf_high(
+            __parent, _NodeTypes::__get_key(__src_ptr->__value_));
+        ++__i;
+        __source.__remove_node_pointer(__src_ptr);
+        __insert_node_at(__parent, __child,
+                         static_cast<__node_base_pointer>(__src_ptr));
+    }
+}
+
+#endif // _LIBCPP_STD_VER > 14
+
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
+{
+    __node_pointer __np = __p.__get_np();
+    iterator __r = __remove_node_pointer(__np);
     __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;
 }
@@ -2047,17 +2487,15 @@
 typename __tree<_Tp, _Compare, _Allocator>::size_type
 __tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const
 {
-    __node_const_pointer __result = __end_node();
-    __node_const_pointer __rt = __root();
+    __node_pointer __rt = __root();
     while (__rt != nullptr)
     {
         if (value_comp()(__k, __rt->__value_))
         {
-            __result = __rt;
-            __rt = static_cast<__node_const_pointer>(__rt->__left_);
+            __rt = static_cast<__node_pointer>(__rt->__left_);
         }
         else if (value_comp()(__rt->__value_, __k))
-            __rt = static_cast<__node_const_pointer>(__rt->__right_);
+            __rt = static_cast<__node_pointer>(__rt->__right_);
         else
             return 1;
     }
@@ -2069,22 +2507,21 @@
 typename __tree<_Tp, _Compare, _Allocator>::size_type
 __tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
 {
-    typedef pair<const_iterator, const_iterator> _Pp;
-    __node_const_pointer __result = __end_node();
-    __node_const_pointer __rt = __root();
+    __iter_pointer __result = __end_node();
+    __node_pointer __rt = __root();
     while (__rt != nullptr)
     {
         if (value_comp()(__k, __rt->__value_))
         {
-            __result = __rt;
-            __rt = static_cast<__node_const_pointer>(__rt->__left_);
+            __result = static_cast<__iter_pointer>(__rt);
+            __rt = static_cast<__node_pointer>(__rt->__left_);
         }
         else if (value_comp()(__rt->__value_, __k))
-            __rt = static_cast<__node_const_pointer>(__rt->__right_);
+            __rt = static_cast<__node_pointer>(__rt->__right_);
         else
             return _VSTD::distance(
-                __lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt),
-                __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result)
+                __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
+                __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)
             );
     }
     return 0;
@@ -2095,13 +2532,13 @@
 typename __tree<_Tp, _Compare, _Allocator>::iterator
 __tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
                                                  __node_pointer __root,
-                                                 __node_pointer __result)
+                                                 __iter_pointer __result)
 {
     while (__root != nullptr)
     {
         if (!value_comp()(__root->__value_, __v))
         {
-            __result = __root;
+            __result = static_cast<__iter_pointer>(__root);
             __root = static_cast<__node_pointer>(__root->__left_);
         }
         else
@@ -2114,18 +2551,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,
+                                                 __iter_pointer __result) const
 {
     while (__root != nullptr)
     {
         if (!value_comp()(__root->__value_, __v))
         {
-            __result = __root;
-            __root = static_cast<__node_const_pointer>(__root->__left_);
+            __result = static_cast<__iter_pointer>(__root);
+            __root = static_cast<__node_pointer>(__root->__left_);
         }
         else
-            __root = static_cast<__node_const_pointer>(__root->__right_);
+            __root = static_cast<__node_pointer>(__root->__right_);
     }
     return const_iterator(__result);
 }
@@ -2135,13 +2572,13 @@
 typename __tree<_Tp, _Compare, _Allocator>::iterator
 __tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
                                                  __node_pointer __root,
-                                                 __node_pointer __result)
+                                                 __iter_pointer __result)
 {
     while (__root != nullptr)
     {
         if (value_comp()(__v, __root->__value_))
         {
-            __result = __root;
+            __result = static_cast<__iter_pointer>(__root);
             __root = static_cast<__node_pointer>(__root->__left_);
         }
         else
@@ -2154,18 +2591,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,
+                                                 __iter_pointer __result) const
 {
     while (__root != nullptr)
     {
         if (value_comp()(__v, __root->__value_))
         {
-            __result = __root;
-            __root = static_cast<__node_const_pointer>(__root->__left_);
+            __result = static_cast<__iter_pointer>(__root);
+            __root = static_cast<__node_pointer>(__root->__left_);
         }
         else
-            __root = static_cast<__node_const_pointer>(__root->__right_);
+            __root = static_cast<__node_pointer>(__root->__right_);
     }
     return const_iterator(__result);
 }
@@ -2177,13 +2614,13 @@
 __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)
 {
     typedef pair<iterator, iterator> _Pp;
-    __node_pointer __result = __end_node();
+    __iter_pointer __result = __end_node();
     __node_pointer __rt = __root();
     while (__rt != nullptr)
     {
         if (value_comp()(__k, __rt->__value_))
         {
-            __result = __rt;
+            __result = static_cast<__iter_pointer>(__rt);
             __rt = static_cast<__node_pointer>(__rt->__left_);
         }
         else if (value_comp()(__rt->__value_, __k))
@@ -2192,7 +2629,7 @@
             return _Pp(iterator(__rt),
                       iterator(
                           __rt->__right_ != nullptr ?
-                              static_cast<__node_pointer>(__tree_min(__rt->__right_))
+                              static_cast<__iter_pointer>(_VSTD::__tree_min(__rt->__right_))
                             : __result));
     }
     return _Pp(iterator(__result), iterator(__result));
@@ -2205,22 +2642,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();
+    __iter_pointer __result = __end_node();
+    __node_pointer __rt = __root();
     while (__rt != nullptr)
     {
         if (value_comp()(__k, __rt->__value_))
         {
-            __result = __rt;
-            __rt = static_cast<__node_const_pointer>(__rt->__left_);
+            __result = static_cast<__iter_pointer>(__rt);
+            __rt = static_cast<__node_pointer>(__rt->__left_);
         }
         else if (value_comp()(__rt->__value_, __k))
-            __rt = static_cast<__node_const_pointer>(__rt->__right_);
+            __rt = static_cast<__node_pointer>(__rt->__right_);
         else
             return _Pp(const_iterator(__rt),
                       const_iterator(
                           __rt->__right_ != nullptr ?
-                              static_cast<__node_const_pointer>(__tree_min(__rt->__right_))
+                              static_cast<__iter_pointer>(_VSTD::__tree_min(__rt->__right_))
                             : __result));
     }
     return _Pp(const_iterator(__result), const_iterator(__result));
@@ -2233,19 +2670,19 @@
 __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)
 {
     typedef pair<iterator, iterator> _Pp;
-    __node_pointer __result = __end_node();
+    __iter_pointer __result = __end_node();
     __node_pointer __rt = __root();
     while (__rt != nullptr)
     {
         if (value_comp()(__k, __rt->__value_))
         {
-            __result = __rt;
+            __result = static_cast<__iter_pointer>(__rt);
             __rt = static_cast<__node_pointer>(__rt->__left_);
         }
         else if (value_comp()(__rt->__value_, __k))
             __rt = static_cast<__node_pointer>(__rt->__right_);
         else
-            return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), __rt),
+            return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
                       __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
     }
     return _Pp(iterator(__result), iterator(__result));
@@ -2258,20 +2695,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();
+    __iter_pointer __result = __end_node();
+    __node_pointer __rt = __root();
     while (__rt != nullptr)
     {
         if (value_comp()(__k, __rt->__value_))
         {
-            __result = __rt;
-            __rt = static_cast<__node_const_pointer>(__rt->__left_);
+            __result = static_cast<__iter_pointer>(__rt);
+            __rt = static_cast<__node_pointer>(__rt->__left_);
         }
         else if (value_comp()(__rt->__value_, __k))
-            __rt = static_cast<__node_const_pointer>(__rt->__right_);
+            __rt = static_cast<__node_pointer>(__rt->__right_);
         else
-            return _Pp(__lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt),
-                      __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result));
+            return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)),
+                      __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
     }
     return _Pp(const_iterator(__result), const_iterator(__result));
 }
@@ -2280,18 +2717,18 @@
 typename __tree<_Tp, _Compare, _Allocator>::__node_holder
 __tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT
 {
-    __node_pointer __np = __p.__ptr_;
-    if (__begin_node() == __np)
+    __node_pointer __np = __p.__get_np();
+    if (__begin_node() == __p.__ptr_)
     {
         if (__np->__right_ != nullptr)
-            __begin_node() = static_cast<__node_pointer>(__np->__right_);
+            __begin_node() = static_cast<__iter_pointer>(__np->__right_);
         else
-            __begin_node() = static_cast<__node_pointer>(__np->__parent_);
+            __begin_node() = static_cast<__iter_pointer>(__np->__parent_);
     }
     --size();
-    __tree_remove(__end_node()->__left_,
-                  static_cast<__node_base_pointer>(__np));
-    return __node_holder(__np, _Dp(__node_alloc()));
+    _VSTD::__tree_remove(__end_node()->__left_,
+                         static_cast<__node_base_pointer>(__np));
+    return __node_holder(__np, _Dp(__node_alloc(), true));
 }
 
 template <class _Tp, class _Compare, class _Allocator>
@@ -2306,4 +2743,6 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif  // _LIBCPP___TREE
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___TREE
diff --git a/include/__tuple b/include/__tuple
index ee5b916..082ec86 100644
--- a/include/__tuple
+++ b/include/__tuple
@@ -1,10 +1,9 @@
 // -*- 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.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -19,90 +18,153 @@
 #pragma GCC system_header
 #endif
 
-#ifdef _LIBCPP_HAS_NO_VARIADICS
-
-#include <__tuple_03>
-
-#else  // _LIBCPP_HAS_NO_VARIADICS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-// __lazy_and
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size;
 
-template <bool _Last, class ..._Preds>
-struct __lazy_and_impl;
-
-template <class ..._Preds>
-struct __lazy_and_impl<false, _Preds...> : false_type {};
-
-template <>
-struct __lazy_and_impl<true> : true_type {};
-
-template <class _Pred>
-struct __lazy_and_impl<true, _Pred> : integral_constant<bool, _Pred::type::value> {};
-
-template <class _Hp, class ..._Tp>
-struct __lazy_and_impl<true, _Hp, _Tp...> : __lazy_and_impl<_Hp::type::value, _Tp...> {};
-
-template <class _P1, class ..._Pr>
-struct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {};
-
-// __lazy_not
-
-template <class _Pred>
-struct __lazy_not : integral_constant<bool, !_Pred::type::value> {};
-
-
-template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;
+#if !defined(_LIBCPP_CXX03_LANG)
+template <class _Tp, class...>
+using __enable_if_tuple_size_imp = _Tp;
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS_ONLY tuple_size<const _Tp>
-    : public tuple_size<_Tp> {};
+struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
+    const _Tp,
+    typename enable_if<!is_volatile<_Tp>::value>::type,
+    integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
+    : public integral_constant<size_t, tuple_size<_Tp>::value> {};
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS_ONLY tuple_size<volatile _Tp>
-    : public tuple_size<_Tp> {};
+struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
+    volatile _Tp,
+    typename enable_if<!is_const<_Tp>::value>::type,
+    integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
+    : public integral_constant<size_t, tuple_size<_Tp>::value> {};
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS_ONLY tuple_size<const volatile _Tp>
-    : public tuple_size<_Tp> {};
+struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
+    const volatile _Tp,
+    integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
+    : public integral_constant<size_t, tuple_size<_Tp>::value> {};
 
-template <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_element;
+#else
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {};
+#endif
+
+template <size_t _Ip, class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_element;
 
 template <size_t _Ip, class _Tp>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const _Tp>
+struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const _Tp>
 {
-public:
-    typedef typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type;
 };
 
 template <size_t _Ip, class _Tp>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, volatile _Tp>
+struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, volatile _Tp>
 {
-public:
-    typedef typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type;
 };
 
 template <size_t _Ip, class _Tp>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const volatile _Tp>
+struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp>
 {
-public:
-    typedef typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type;
 };
 
-template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple;
-template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair;
-template <class _Tp, size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY array;
-
 template <class _Tp> struct __tuple_like : false_type {};
 
 template <class _Tp> struct __tuple_like<const _Tp> : public __tuple_like<_Tp> {};
 template <class _Tp> struct __tuple_like<volatile _Tp> : public __tuple_like<_Tp> {};
 template <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_like<_Tp> {};
 
+// tuple specializations
+
+#ifndef _LIBCPP_CXX03_LANG
+
+template <size_t...> struct __tuple_indices {};
+
+template <class _IdxType, _IdxType... _Values>
+struct __integer_sequence {
+  template <template <class _OIdxType, _OIdxType...> class _ToIndexSeq, class _ToIndexType>
+  using __convert = _ToIndexSeq<_ToIndexType, _Values...>;
+
+  template <size_t _Sp>
+  using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>;
+};
+
+#if !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
+namespace __detail {
+
+template<typename _Tp, size_t ..._Extra> struct __repeat;
+template<typename _Tp, _Tp ..._Np, size_t ..._Extra> struct __repeat<__integer_sequence<_Tp, _Np...>, _Extra...> {
+  typedef _LIBCPP_NODEBUG_TYPE __integer_sequence<_Tp,
+                           _Np...,
+                           sizeof...(_Np) + _Np...,
+                           2 * sizeof...(_Np) + _Np...,
+                           3 * sizeof...(_Np) + _Np...,
+                           4 * sizeof...(_Np) + _Np...,
+                           5 * sizeof...(_Np) + _Np...,
+                           6 * sizeof...(_Np) + _Np...,
+                           7 * sizeof...(_Np) + _Np...,
+                           _Extra...> type;
+};
+
+template<size_t _Np> struct __parity;
+template<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {};
+
+template<> struct __make<0> { typedef __integer_sequence<size_t> type; };
+template<> struct __make<1> { typedef __integer_sequence<size_t, 0> type; };
+template<> struct __make<2> { typedef __integer_sequence<size_t, 0, 1> type; };
+template<> struct __make<3> { typedef __integer_sequence<size_t, 0, 1, 2> type; };
+template<> struct __make<4> { typedef __integer_sequence<size_t, 0, 1, 2, 3> type; };
+template<> struct __make<5> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4> type; };
+template<> struct __make<6> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; };
+template<> struct __make<7> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; };
+
+template<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; };
+template<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; };
+template<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<5> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<6> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
+
+} // namespace detail
+
+#endif // !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
+
+#if __has_builtin(__make_integer_seq)
+template <size_t _Ep, size_t _Sp>
+using __make_indices_imp =
+    typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template
+    __to_tuple_indices<_Sp>;
+#else
+template <size_t _Ep, size_t _Sp>
+using __make_indices_imp =
+    typename __detail::__make<_Ep - _Sp>::type::template __to_tuple_indices<_Sp>;
+
+#endif
+
+template <size_t _Ep, size_t _Sp = 0>
+struct __make_tuple_indices
+{
+    static_assert(_Sp <= _Ep, "__make_tuple_indices input error");
+    typedef __make_indices_imp<_Ep, _Sp> type;
+};
+
+
+template <class ..._Tp> class _LIBCPP_TEMPLATE_VIS tuple;
+
 template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {};
-template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {};
-template <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {};
+
+template <class ..._Tp>
+struct _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> >
+    : public integral_constant<size_t, sizeof...(_Tp)>
+{
+};
 
 template <size_t _Ip, class ..._Tp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
@@ -119,6 +181,17 @@
 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 // !defined(_LIBCPP_CXX03_LANG)
+
+// pair specializations
+
+template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {};
+
 template <size_t _Ip, class _T1, class _T2>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename tuple_element<_Ip, pair<_T1, _T2> >::type&
@@ -129,11 +202,24 @@
 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
 get(const pair<_T1, _T2>&) _NOEXCEPT;
 
+#ifndef _LIBCPP_CXX03_LANG
 template <size_t _Ip, class _T1, class _T2>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
 get(pair<_T1, _T2>&&) _NOEXCEPT;
 
+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
+
+template <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array;
+
+template <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {};
+
 template <size_t _Ip, class _Tp, size_t _Size>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp&
@@ -144,71 +230,109 @@
 const _Tp&
 get(const array<_Tp, _Size>&) _NOEXCEPT;
 
+#ifndef _LIBCPP_CXX03_LANG
 template <size_t _Ip, class _Tp, size_t _Size>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp&&
 get(array<_Tp, _Size>&&) _NOEXCEPT;
 
-// __make_tuple_indices
+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
 
-template <size_t...> struct __tuple_indices {};
-
-template <size_t _Sp, class _IntTuple, size_t _Ep>
-struct __make_indices_imp;
-
-template <size_t _Sp, size_t ..._Indices, size_t _Ep>
-struct __make_indices_imp<_Sp, __tuple_indices<_Indices...>, _Ep>
-{
-    typedef typename __make_indices_imp<_Sp+1, __tuple_indices<_Indices..., _Sp>, _Ep>::type type;
-};
-
-template <size_t _Ep, size_t ..._Indices>
-struct __make_indices_imp<_Ep, __tuple_indices<_Indices...>, _Ep>
-{
-    typedef __tuple_indices<_Indices...> type;
-};
-
-template <size_t _Ep, size_t _Sp = 0>
-struct __make_tuple_indices
-{
-    static_assert(_Sp <= _Ep, "__make_tuple_indices input error");
-    typedef typename __make_indices_imp<_Sp, __tuple_indices<>, _Ep>::type type;
-};
+#ifndef _LIBCPP_CXX03_LANG
 
 // __tuple_types
 
 template <class ..._Tp> struct __tuple_types {};
 
-template <size_t _Ip>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<> >
+#if !__has_builtin(__type_pack_element)
+
+namespace __indexer_detail {
+
+template <size_t _Idx, class _Tp>
+struct __indexed { using type _LIBCPP_NODEBUG_TYPE = _Tp; };
+
+template <class _Types, class _Indexes> struct __indexer;
+
+template <class ..._Types, size_t ..._Idx>
+struct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>>
+    : __indexed<_Idx, _Types>...
+{};
+
+template <size_t _Idx, class _Tp>
+__indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&);
+
+} // namespace __indexer_detail
+
+template <size_t _Idx, class ..._Types>
+using __type_pack_element _LIBCPP_NODEBUG_TYPE = typename decltype(
+    __indexer_detail::__at_index<_Idx>(
+        __indexer_detail::__indexer<
+            __tuple_types<_Types...>,
+            typename __make_tuple_indices<sizeof...(_Types)>::type
+        >{})
+  )::type;
+#endif
+
+template <size_t _Ip, class ..._Types>
+struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...>>
 {
-public:
-    static_assert(_Ip == 0, "tuple_element index out of range");
-    static_assert(_Ip != 0, "tuple_element index out of range");
+    static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range");
+    typedef _LIBCPP_NODEBUG_TYPE __type_pack_element<_Ip, _Types...> type;
 };
 
-template <class _Hp, class ..._Tp>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, __tuple_types<_Hp, _Tp...> >
-{
-public:
-    typedef _Hp type;
-};
-
-template <size_t _Ip, class _Hp, class ..._Tp>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Hp, _Tp...> >
-{
-public:
-    typedef typename tuple_element<_Ip-1, __tuple_types<_Tp...> >::type type;
-};
 
 template <class ..._Tp>
-class _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> >
+struct _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> >
     : public integral_constant<size_t, sizeof...(_Tp)>
 {
 };
 
 template <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type {};
 
+template <bool _ApplyLV, bool _ApplyConst, bool _ApplyVolatile>
+struct __apply_cv_mf;
+template <>
+struct __apply_cv_mf<false, false, false> {
+  template <class _Tp> using __apply = _Tp;
+};
+template <>
+struct __apply_cv_mf<false, true, false> {
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE  = const _Tp;
+};
+template <>
+struct __apply_cv_mf<false, false, true> {
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE  = volatile _Tp;
+};
+template <>
+struct __apply_cv_mf<false, true, true> {
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE  = const volatile _Tp;
+};
+template <>
+struct __apply_cv_mf<true, false, false> {
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE  = _Tp&;
+};
+template <>
+struct __apply_cv_mf<true, true, false> {
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE  = const _Tp&;
+};
+template <>
+struct __apply_cv_mf<true, false, true> {
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE  = volatile _Tp&;
+};
+template <>
+struct __apply_cv_mf<true, true, true> {
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE = const volatile _Tp&;
+};
+template <class _Tp, class _RawTp = typename remove_reference<_Tp>::type>
+using __apply_cv_t _LIBCPP_NODEBUG_TYPE  = __apply_cv_mf<
+    is_lvalue_reference<_Tp>::value,
+    is_const<_RawTp>::value,
+    is_volatile<_RawTp>::value>;
+
 // __make_tuple_types
 
 // __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a
@@ -216,48 +340,73 @@
 // _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>.  If _Tuple is a
 // lvalue_reference type, then __tuple_types<_Types&...> is the result.
 
-template <class _TupleTypes, class _Tp, size_t _Sp, size_t _Ep>
-struct __make_tuple_types_imp;
+template <class _TupleTypes, class _TupleIndices>
+struct __make_tuple_types_flat;
 
-template <class ..._Types, class _Tp, size_t _Sp, size_t _Ep>
-struct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Sp, _Ep>
-{
-    typedef typename remove_reference<_Tp>::type _Tpr;
-    typedef typename __make_tuple_types_imp<__tuple_types<_Types...,
-                                            typename conditional<is_lvalue_reference<_Tp>::value,
-                                                typename tuple_element<_Sp, _Tpr>::type&,
-                                                typename tuple_element<_Sp, _Tpr>::type>::type>,
-                                            _Tp, _Sp+1, _Ep>::type type;
+template <template <class...> class _Tuple, class ..._Types, size_t ..._Idx>
+struct __make_tuple_types_flat<_Tuple<_Types...>, __tuple_indices<_Idx...>> {
+  // Specialization for pair, tuple, and __tuple_types
+  template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>>
+  using __apply_quals _LIBCPP_NODEBUG_TYPE = __tuple_types<
+      typename _ApplyFn::template __apply<__type_pack_element<_Idx, _Types...>>...
+    >;
 };
 
-template <class ..._Types, class _Tp, size_t _Ep>
-struct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Ep, _Ep>
-{
-    typedef __tuple_types<_Types...> type;
+template <class _Vt, size_t _Np, size_t ..._Idx>
+struct __make_tuple_types_flat<array<_Vt, _Np>, __tuple_indices<_Idx...>> {
+  template <size_t>
+  using __value_type = _Vt;
+  template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>>
+  using __apply_quals = __tuple_types<
+      typename _ApplyFn::template __apply<__value_type<_Idx>>...
+    >;
 };
 
-template <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value, size_t _Sp = 0>
+template <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value,
+          size_t _Sp = 0,
+          bool _SameSize = (_Ep == tuple_size<typename remove_reference<_Tp>::type>::value)>
 struct __make_tuple_types
 {
     static_assert(_Sp <= _Ep, "__make_tuple_types input error");
-    typedef typename __make_tuple_types_imp<__tuple_types<>, _Tp, _Sp, _Ep>::type type;
+    using _RawTp = typename remove_cv<typename remove_reference<_Tp>::type>::type;
+    using _Maker = __make_tuple_types_flat<_RawTp, typename __make_tuple_indices<_Ep, _Sp>::type>;
+    using type = typename _Maker::template __apply_quals<_Tp>;
+};
+
+template <class ..._Types, size_t _Ep>
+struct __make_tuple_types<tuple<_Types...>, _Ep, 0, true> {
+  typedef _LIBCPP_NODEBUG_TYPE __tuple_types<_Types...> type;
+};
+
+template <class ..._Types, size_t _Ep>
+struct __make_tuple_types<__tuple_types<_Types...>, _Ep, 0, true> {
+  typedef _LIBCPP_NODEBUG_TYPE __tuple_types<_Types...> type;
+};
+
+template <bool ..._Preds>
+struct __all_dummy;
+
+template <bool ..._Pred>
+using __all = _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>>;
+
+struct __tuple_sfinae_base {
+  template <template <class, class...> class _Trait,
+            class ..._LArgs, class ..._RArgs>
+  static auto __do_test(__tuple_types<_LArgs...>, __tuple_types<_RArgs...>)
+    -> __all<typename enable_if<_Trait<_LArgs, _RArgs>::value, bool>::type{true}...>;
+  template <template <class...> class>
+  static auto __do_test(...) -> false_type;
+
+  template <class _FromArgs, class _ToArgs>
+  using __constructible = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{}));
+  template <class _FromArgs, class _ToArgs>
+  using __convertible = decltype(__do_test<is_convertible>(_FromArgs{}, _ToArgs{}));
+  template <class _FromArgs, class _ToArgs>
+  using __assignable = decltype(__do_test<is_assignable>(_ToArgs{}, _FromArgs{}));
 };
 
 // __tuple_convertible
 
-template <bool, class _Tp, class _Up>
-struct __tuple_convertible_imp : public false_type {};
-
-template <class _Tp0, class ..._Tp, class _Up0, class ..._Up>
-struct __tuple_convertible_imp<true, __tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> >
-    : public integral_constant<bool,
-                               is_convertible<_Tp0, _Up0>::value &&
-                               __tuple_convertible_imp<true, __tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};
-
-template <>
-struct __tuple_convertible_imp<true, __tuple_types<>, __tuple_types<> >
-    : public true_type {};
-
 template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,
                                 bool = __tuple_like<_Up>::value>
 struct __tuple_convertible
@@ -265,26 +414,14 @@
 
 template <class _Tp, class _Up>
 struct __tuple_convertible<_Tp, _Up, true, true>
-    : public __tuple_convertible_imp<tuple_size<typename remove_reference<_Tp>::type>::value ==
-                                     tuple_size<_Up>::value,
-             typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type>
+    : public __tuple_sfinae_base::__convertible<
+      typename __make_tuple_types<_Tp>::type
+    , typename __make_tuple_types<_Up>::type
+    >
 {};
 
 // __tuple_constructible
 
-template <bool, class _Tp, class _Up>
-struct __tuple_constructible_imp : public false_type {};
-
-template <class _Tp0, class ..._Tp, class _Up0, class ..._Up>
-struct __tuple_constructible_imp<true, __tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> >
-    : public integral_constant<bool,
-                               is_constructible<_Up0, _Tp0>::value &&
-                               __tuple_constructible_imp<true, __tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};
-
-template <>
-struct __tuple_constructible_imp<true, __tuple_types<>, __tuple_types<> >
-    : public true_type {};
-
 template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,
                                 bool = __tuple_like<_Up>::value>
 struct __tuple_constructible
@@ -292,26 +429,14 @@
 
 template <class _Tp, class _Up>
 struct __tuple_constructible<_Tp, _Up, true, true>
-    : public __tuple_constructible_imp<tuple_size<typename remove_reference<_Tp>::type>::value ==
-                                     tuple_size<_Up>::value,
-             typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type>
+    : public __tuple_sfinae_base::__constructible<
+      typename __make_tuple_types<_Tp>::type
+    , typename __make_tuple_types<_Up>::type
+    >
 {};
 
 // __tuple_assignable
 
-template <bool, class _Tp, class _Up>
-struct __tuple_assignable_imp : public false_type {};
-
-template <class _Tp0, class ..._Tp, class _Up0, class ..._Up>
-struct __tuple_assignable_imp<true, __tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> >
-    : public integral_constant<bool,
-                               is_assignable<_Up0&, _Tp0>::value &&
-                               __tuple_assignable_imp<true, __tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};
-
-template <>
-struct __tuple_assignable_imp<true, __tuple_types<>, __tuple_types<> >
-    : public true_type {};
-
 template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,
                                 bool = __tuple_like<_Up>::value>
 struct __tuple_assignable
@@ -319,13 +444,108 @@
 
 template <class _Tp, class _Up>
 struct __tuple_assignable<_Tp, _Up, true, true>
-    : public __tuple_assignable_imp<tuple_size<typename remove_reference<_Tp>::type>::value ==
-                                    tuple_size<_Up>::value,
-             typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type>
+    : public __tuple_sfinae_base::__assignable<
+      typename __make_tuple_types<_Tp>::type
+    , typename __make_tuple_types<_Up&>::type
+    >
 {};
 
+
+template <size_t _Ip, class ..._Tp>
+struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, tuple<_Tp...> >
+{
+    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <size_t _Ip, class ..._Tp>
+using tuple_element_t _LIBCPP_NODEBUG_TYPE  = typename tuple_element <_Ip, _Tp...>::type;
+#endif
+
+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 _LIBCPP_NODEBUG_TYPE = __tuple_like_with_size_imp<
+                                   __tuple_like<_RawTuple>::value,
+                                   tuple_size<_RawTuple>, _ExpectedSize
+                              >;
+
+struct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail {
+
+    static constexpr bool __enable_explicit_default() { return false; }
+    static constexpr bool __enable_implicit_default() { return false; }
+    template <class ...>
+    static constexpr bool __enable_explicit() { return false; }
+    template <class ...>
+    static constexpr bool __enable_implicit() { return false; }
+    template <class ...>
+    static constexpr bool __enable_assign() { return false; }
+};
+#endif // !defined(_LIBCPP_CXX03_LANG)
+
+#if _LIBCPP_STD_VER > 14
+
+template <bool _CanCopy, bool _CanMove>
+struct __sfinae_ctor_base {};
+template <>
+struct __sfinae_ctor_base<false, false> {
+  __sfinae_ctor_base() = default;
+  __sfinae_ctor_base(__sfinae_ctor_base const&) = delete;
+  __sfinae_ctor_base(__sfinae_ctor_base &&) = delete;
+  __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
+  __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
+};
+template <>
+struct __sfinae_ctor_base<true, false> {
+  __sfinae_ctor_base() = default;
+  __sfinae_ctor_base(__sfinae_ctor_base const&) = default;
+  __sfinae_ctor_base(__sfinae_ctor_base &&) = delete;
+  __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
+  __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
+};
+template <>
+struct __sfinae_ctor_base<false, true> {
+  __sfinae_ctor_base() = default;
+  __sfinae_ctor_base(__sfinae_ctor_base const&) = delete;
+  __sfinae_ctor_base(__sfinae_ctor_base &&) = default;
+  __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default;
+  __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default;
+};
+
+template <bool _CanCopy, bool _CanMove>
+struct __sfinae_assign_base {};
+template <>
+struct __sfinae_assign_base<false, false> {
+  __sfinae_assign_base() = default;
+  __sfinae_assign_base(__sfinae_assign_base const&) = default;
+  __sfinae_assign_base(__sfinae_assign_base &&) = default;
+  __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
+  __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete;
+};
+template <>
+struct __sfinae_assign_base<true, false> {
+  __sfinae_assign_base() = default;
+  __sfinae_assign_base(__sfinae_assign_base const&) = default;
+  __sfinae_assign_base(__sfinae_assign_base &&) = default;
+  __sfinae_assign_base& operator=(__sfinae_assign_base const&) = default;
+  __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete;
+};
+template <>
+struct __sfinae_assign_base<false, true> {
+  __sfinae_assign_base() = default;
+  __sfinae_assign_base(__sfinae_assign_base const&) = default;
+  __sfinae_assign_base(__sfinae_assign_base &&) = default;
+  __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete;
+  __sfinae_assign_base& operator=(__sfinae_assign_base&&) = default;
+};
+#endif // _LIBCPP_STD_VER > 14
+
 _LIBCPP_END_NAMESPACE_STD
 
-#endif  // _LIBCPP_HAS_NO_VARIADICS
-
-#endif  // _LIBCPP___TUPLE
+#endif // _LIBCPP___TUPLE
diff --git a/include/__tuple_03 b/include/__tuple_03
deleted file mode 100644
index b91c2cd..0000000
--- a/include/__tuple_03
+++ /dev/null
@@ -1,27 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___TUPLE_03
-#define _LIBCPP___TUPLE_03
-
-#include <__config>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;
-template <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_element;
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif  // _LIBCPP___TUPLE_03
diff --git a/include/__undef_macros b/include/__undef_macros
new file mode 100644
index 0000000..4923ee6
--- /dev/null
+++ b/include/__undef_macros
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//===------------------------ __undef_macros ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifdef min
+#if !defined(_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS)
+#if defined(_LIBCPP_WARNING)
+_LIBCPP_WARNING("macro min is incompatible with C++.  Try #define NOMINMAX "
+                "before any Windows header. #undefing min")
+#else
+#warning: macro min is incompatible with C++.  #undefing min
+#endif
+#endif
+#undef min
+#endif
+
+#ifdef max
+#if !defined(_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS)
+#if defined(_LIBCPP_WARNING)
+_LIBCPP_WARNING("macro max is incompatible with C++.  Try #define NOMINMAX "
+                "before any Windows header. #undefing max")
+#else
+#warning: macro max is incompatible with C++.  #undefing max
+#endif
+#endif
+#undef max
+#endif
diff --git a/include/__undef_min_max b/include/__undef_min_max
deleted file mode 100644
index 5df9412..0000000
--- a/include/__undef_min_max
+++ /dev/null
@@ -1,29 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifdef min
-#if defined(_MSC_VER) && ! defined(__clang__)
-_LIBCPP_WARNING("macro min is incompatible with C++.  Try #define NOMINMAX "
-                "before any Windows header. #undefing min")
-#else
-#warning: macro min is incompatible with C++.  #undefing min
-#endif
-#undef min
-#endif
-
-#ifdef max
-#if defined(_MSC_VER) && ! defined(__clang__)
-_LIBCPP_WARNING("macro max is incompatible with C++.  Try #define NOMINMAX "
-                "before any Windows header. #undefing max")
-#else
-#warning: macro max is incompatible with C++.  #undefing max
-#endif
-#undef max
-#endif
diff --git a/include/__utility/__decay_copy.h b/include/__utility/__decay_copy.h
new file mode 100644
index 0000000..eda8db6
--- /dev/null
+++ b/include/__utility/__decay_copy.h
@@ -0,0 +1,39 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_DECAY_COPY_H
+#define _LIBCPP___TYPE_TRAITS_DECAY_COPY_H
+
+#include <__config>
+#include <__utility/forward.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY typename decay<_Tp>::type __decay_copy(_Tp&& __t)
+#if _LIBCPP_STD_VER > 17
+    noexcept(is_nothrow_convertible_v<_Tp, remove_reference_t<_Tp> >)
+#endif
+{
+  return _VSTD::forward<_Tp>(__t);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___TYPE_TRAITS_DECAY_COPY_H
diff --git a/include/__utility/as_const.h b/include/__utility/as_const.h
new file mode 100644
index 0000000..2f23eb4
--- /dev/null
+++ b/include/__utility/as_const.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_AS_CONST_H
+#define _LIBCPP___UTILITY_AS_CONST_H
+
+#include <__config>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+_LIBCPP_NODISCARD_EXT constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; }
+
+template <class _Tp>
+void as_const(const _Tp&&) = delete;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___UTILITY_AS_CONST_H
diff --git a/include/__utility/cmp.h b/include/__utility/cmp.h
new file mode 100644
index 0000000..a14e373
--- /dev/null
+++ b/include/__utility/cmp.h
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_CMP_H
+#define _LIBCPP___UTILITY_CMP_H
+
+#include <__config>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <limits>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+template<class _Tp, class... _Up>
+struct _IsSameAsAny : _Or<_IsSame<_Tp, _Up>...> {};
+
+template<class _Tp>
+concept __is_safe_integral_cmp = is_integral_v<_Tp> &&
+                      !_IsSameAsAny<_Tp, bool, char,
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+                                    char8_t,
+#endif
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+                                    char16_t, char32_t,
+#endif
+                                    wchar_t>::value;
+
+template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
+_LIBCPP_INLINE_VISIBILITY constexpr
+bool cmp_equal(_Tp __t, _Up __u) noexcept
+{
+  if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
+    return __t == __u;
+  else if constexpr (is_signed_v<_Tp>)
+    return __t < 0 ? false : make_unsigned_t<_Tp>(__t) == __u;
+  else
+    return __u < 0 ? false : __t == make_unsigned_t<_Up>(__u);
+}
+
+template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
+_LIBCPP_INLINE_VISIBILITY constexpr
+bool cmp_not_equal(_Tp __t, _Up __u) noexcept
+{
+  return !_VSTD::cmp_equal(__t, __u);
+}
+
+template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
+_LIBCPP_INLINE_VISIBILITY constexpr
+bool cmp_less(_Tp __t, _Up __u) noexcept
+{
+  if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
+    return __t < __u;
+  else if constexpr (is_signed_v<_Tp>)
+    return __t < 0 ? true : make_unsigned_t<_Tp>(__t) < __u;
+  else
+    return __u < 0 ? false : __t < make_unsigned_t<_Up>(__u);
+}
+
+template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
+_LIBCPP_INLINE_VISIBILITY constexpr
+bool cmp_greater(_Tp __t, _Up __u) noexcept
+{
+  return _VSTD::cmp_less(__u, __t);
+}
+
+template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
+_LIBCPP_INLINE_VISIBILITY constexpr
+bool cmp_less_equal(_Tp __t, _Up __u) noexcept
+{
+  return !_VSTD::cmp_greater(__t, __u);
+}
+
+template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
+_LIBCPP_INLINE_VISIBILITY constexpr
+bool cmp_greater_equal(_Tp __t, _Up __u) noexcept
+{
+  return !_VSTD::cmp_less(__t, __u);
+}
+
+template<__is_safe_integral_cmp _Tp, __is_safe_integral_cmp _Up>
+_LIBCPP_INLINE_VISIBILITY constexpr
+bool in_range(_Up __u) noexcept
+{
+  return _VSTD::cmp_less_equal(__u, numeric_limits<_Tp>::max()) &&
+         _VSTD::cmp_greater_equal(__u, numeric_limits<_Tp>::min());
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___UTILITY_CMP_H
diff --git a/include/__utility/declval.h b/include/__utility/declval.h
new file mode 100644
index 0000000..185527c
--- /dev/null
+++ b/include/__utility/declval.h
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_DECLVAL_H
+#define _LIBCPP___UTILITY_DECLVAL_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Suppress deprecation notice for volatile-qualified return type resulting
+// from volatile-qualified types _Tp.
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
+template <class _Tp>
+_Tp&& __declval(int);
+template <class _Tp>
+_Tp __declval(long);
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+
+template <class _Tp>
+decltype(__declval<_Tp>(0)) declval() _NOEXCEPT;
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___UTILITY_DECLVAL_H
diff --git a/include/__utility/exchange.h b/include/__utility/exchange.h
new file mode 100644
index 0000000..4d5211d
--- /dev/null
+++ b/include/__utility/exchange.h
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_EXCHANGE_H
+#define _LIBCPP___UTILITY_EXCHANGE_H
+
+#include <__config>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 11
+template<class _T1, class _T2 = _T1>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_T1 exchange(_T1& __obj, _T2 && __new_value)
+{
+    _T1 __old_value = _VSTD::move(__obj);
+    __obj = _VSTD::forward<_T2>(__new_value);
+    return __old_value;
+}
+#endif // _LIBCPP_STD_VER > 11
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___UTILITY_EXCHANGE_H
diff --git a/include/__utility/forward.h b/include/__utility/forward.h
new file mode 100644
index 0000000..c994f12
--- /dev/null
+++ b/include/__utility/forward.h
@@ -0,0 +1,42 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_FORWARD_H
+#define _LIBCPP___UTILITY_FORWARD_H
+
+#include <__config>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Tp&&
+forward(typename remove_reference<_Tp>::type& __t) _NOEXCEPT {
+  return static_cast<_Tp&&>(__t);
+}
+
+template <class _Tp>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Tp&&
+forward(typename remove_reference<_Tp>::type&& __t) _NOEXCEPT {
+  static_assert(!is_lvalue_reference<_Tp>::value, "cannot forward an rvalue as an lvalue");
+  return static_cast<_Tp&&>(__t);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___UTILITY_FORWARD_H
diff --git a/include/__utility/in_place.h b/include/__utility/in_place.h
new file mode 100644
index 0000000..964d083
--- /dev/null
+++ b/include/__utility/in_place.h
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_IN_PLACE_H
+#define _LIBCPP___UTILITY_IN_PLACE_H
+
+#include <__config>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+struct _LIBCPP_TYPE_VIS in_place_t {
+    explicit in_place_t() = default;
+};
+_LIBCPP_INLINE_VAR constexpr in_place_t in_place{};
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS in_place_type_t {
+    explicit in_place_type_t() = default;
+};
+template <class _Tp>
+_LIBCPP_INLINE_VAR constexpr in_place_type_t<_Tp> in_place_type{};
+
+template <size_t _Idx>
+struct _LIBCPP_TEMPLATE_VIS in_place_index_t {
+    explicit in_place_index_t() = default;
+};
+template <size_t _Idx>
+_LIBCPP_INLINE_VAR constexpr in_place_index_t<_Idx> in_place_index{};
+
+template <class _Tp> struct __is_inplace_type_imp : false_type {};
+template <class _Tp> struct __is_inplace_type_imp<in_place_type_t<_Tp>> : true_type {};
+
+template <class _Tp>
+using __is_inplace_type = __is_inplace_type_imp<__uncvref_t<_Tp>>;
+
+template <class _Tp> struct __is_inplace_index_imp : false_type {};
+template <size_t _Idx> struct __is_inplace_index_imp<in_place_index_t<_Idx>> : true_type {};
+
+template <class _Tp>
+using __is_inplace_index = __is_inplace_index_imp<__uncvref_t<_Tp>>;
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___UTILITY_IN_PLACE_H
diff --git a/include/__utility/integer_sequence.h b/include/__utility/integer_sequence.h
new file mode 100644
index 0000000..963c4a9
--- /dev/null
+++ b/include/__utility/integer_sequence.h
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_INTEGER_SEQUENCE_H
+#define _LIBCPP___UTILITY_INTEGER_SEQUENCE_H
+
+#include <__config>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 11
+
+template<class _Tp, _Tp... _Ip>
+struct _LIBCPP_TEMPLATE_VIS integer_sequence
+{
+    typedef _Tp value_type;
+    static_assert( is_integral<_Tp>::value,
+                  "std::integer_sequence can only be instantiated with an integral type" );
+    static
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    size_t
+    size() noexcept { return sizeof...(_Ip); }
+};
+
+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>
+using __make_integer_sequence _LIBCPP_NODEBUG_TYPE = __make_integer_seq<integer_sequence, _Tp, _Ep>;
+
+#else
+
+template<typename _Tp, _Tp _Np> using __make_integer_sequence_unchecked _LIBCPP_NODEBUG_TYPE  =
+  typename __detail::__make<_Np>::type::template __convert<integer_sequence, _Tp>;
+
+template <class _Tp, _Tp _Ep>
+struct __make_integer_sequence_checked
+{
+    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 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 _LIBCPP_NODEBUG_TYPE  __make_integer_sequence_unchecked<_Tp, 0 <= _Ep ? _Ep : 0> type;
+};
+
+template <class _Tp, _Tp _Ep>
+using __make_integer_sequence _LIBCPP_NODEBUG_TYPE = typename __make_integer_sequence_checked<_Tp, _Ep>::type;
+
+#endif
+
+template<class _Tp, _Tp _Np>
+    using make_integer_sequence = __make_integer_sequence<_Tp, _Np>;
+
+template<size_t _Np>
+    using make_index_sequence = make_integer_sequence<size_t, _Np>;
+
+template<class... _Tp>
+    using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
+
+#endif // _LIBCPP_STD_VER > 11
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___UTILITY_INTEGER_SEQUENCE_H
diff --git a/include/__utility/move.h b/include/__utility/move.h
new file mode 100644
index 0000000..d3c56f9
--- /dev/null
+++ b/include/__utility/move.h
@@ -0,0 +1,52 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_MOVE_H
+#define _LIBCPP___UTILITY_MOVE_H
+
+#include <__config>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename remove_reference<_Tp>::type&&
+move(_Tp&& __t) _NOEXCEPT {
+  typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tp>::type _Up;
+  return static_cast<_Up&&>(__t);
+}
+
+#ifndef _LIBCPP_CXX03_LANG
+template <class _Tp>
+using __move_if_noexcept_result_t =
+    typename conditional<!is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value, const _Tp&,
+                         _Tp&&>::type;
+#else // _LIBCPP_CXX03_LANG
+template <class _Tp>
+using __move_if_noexcept_result_t = const _Tp&;
+#endif
+
+template <class _Tp>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 __move_if_noexcept_result_t<_Tp>
+move_if_noexcept(_Tp& __x) _NOEXCEPT {
+  return _VSTD::move(__x);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___UTILITY_MOVE_H
diff --git a/include/__utility/pair.h b/include/__utility/pair.h
new file mode 100644
index 0000000..e0216f3
--- /dev/null
+++ b/include/__utility/pair.h
@@ -0,0 +1,585 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_PAIR_H
+#define _LIBCPP___UTILITY_PAIR_H
+
+#include <__config>
+#include <__functional/unwrap_ref.h>
+#include <__tuple>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <__utility/piecewise_construct.h>
+#include <cstddef>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+
+#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
+template <class, class>
+struct __non_trivially_copyable_base {
+  _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+  __non_trivially_copyable_base() _NOEXCEPT {}
+  _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+  __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
+};
+#endif
+
+template <class _T1, class _T2>
+struct _LIBCPP_TEMPLATE_VIS pair
+#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
+: private __non_trivially_copyable_base<_T1, _T2>
+#endif
+{
+    typedef _T1 first_type;
+    typedef _T2 second_type;
+
+    _T1 first;
+    _T2 second;
+
+#if !defined(_LIBCPP_CXX03_LANG)
+    pair(pair const&) = default;
+    pair(pair&&) = default;
+#else
+  // Use the implicitly declared copy constructor in C++03
+#endif
+
+#ifdef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    pair() : first(), second() {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
+
+    template <class _U1, class _U2>
+    _LIBCPP_INLINE_VISIBILITY
+    pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    pair& operator=(pair const& __p) {
+        first = __p.first;
+        second = __p.second;
+        return *this;
+    }
+#else
+    template <bool _Val>
+    using _EnableB _LIBCPP_NODEBUG_TYPE = typename enable_if<_Val, bool>::type;
+
+    struct _CheckArgs {
+      template <int&...>
+      static constexpr bool __enable_explicit_default() {
+          return is_default_constructible<_T1>::value
+              && is_default_constructible<_T2>::value
+              && !__enable_implicit_default<>();
+      }
+
+      template <int&...>
+      static constexpr bool __enable_implicit_default() {
+          return __is_implicitly_default_constructible<_T1>::value
+              && __is_implicitly_default_constructible<_T2>::value;
+      }
+
+      template <class _U1, class _U2>
+      static constexpr bool __enable_explicit() {
+          return is_constructible<first_type, _U1>::value
+              && is_constructible<second_type, _U2>::value
+              && (!is_convertible<_U1, first_type>::value
+                  || !is_convertible<_U2, second_type>::value);
+      }
+
+      template <class _U1, class _U2>
+      static constexpr bool __enable_implicit() {
+          return is_constructible<first_type, _U1>::value
+              && is_constructible<second_type, _U2>::value
+              && is_convertible<_U1, first_type>::value
+              && is_convertible<_U2, second_type>::value;
+      }
+    };
+
+    template <bool _MaybeEnable>
+    using _CheckArgsDep _LIBCPP_NODEBUG_TYPE = typename conditional<
+      _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type;
+
+    struct _CheckTupleLikeConstructor {
+        template <class _Tuple>
+        static constexpr bool __enable_implicit() {
+            return __tuple_convertible<_Tuple, pair>::value;
+        }
+
+        template <class _Tuple>
+        static constexpr bool __enable_explicit() {
+            return __tuple_constructible<_Tuple, pair>::value
+               && !__tuple_convertible<_Tuple, pair>::value;
+        }
+
+        template <class _Tuple>
+        static constexpr bool __enable_assign() {
+            return __tuple_assignable<_Tuple, pair>::value;
+        }
+    };
+
+    template <class _Tuple>
+    using _CheckTLC _LIBCPP_NODEBUG_TYPE = typename conditional<
+        __tuple_like_with_size<_Tuple, 2>::value
+            && !is_same<typename decay<_Tuple>::type, pair>::value,
+        _CheckTupleLikeConstructor,
+        __check_tuple_constructor_fail
+    >::type;
+
+    template<bool _Dummy = true, _EnableB<
+            _CheckArgsDep<_Dummy>::__enable_explicit_default()
+    > = false>
+    explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
+                      is_nothrow_default_constructible<second_type>::value)
+        : first(), second() {}
+
+    template<bool _Dummy = true, _EnableB<
+            _CheckArgsDep<_Dummy>::__enable_implicit_default()
+    > = false>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
+                      is_nothrow_default_constructible<second_type>::value)
+        : first(), second() {}
+
+    template <bool _Dummy = true, _EnableB<
+             _CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>()
+    > = false>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    explicit pair(_T1 const& __t1, _T2 const& __t2)
+        _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
+                   is_nothrow_copy_constructible<second_type>::value)
+        : first(__t1), second(__t2) {}
+
+    template<bool _Dummy = true, _EnableB<
+            _CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>()
+    > = false>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    pair(_T1 const& __t1, _T2 const& __t2)
+        _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
+                   is_nothrow_copy_constructible<second_type>::value)
+        : first(__t1), second(__t2) {}
+
+    template<class _U1, class _U2, _EnableB<
+             _CheckArgs::template __enable_explicit<_U1, _U2>()
+    > = false>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    explicit pair(_U1&& __u1, _U2&& __u2)
+        _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
+                    is_nothrow_constructible<second_type, _U2>::value))
+        : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
+
+    template<class _U1, class _U2, _EnableB<
+            _CheckArgs::template __enable_implicit<_U1, _U2>()
+    > = false>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    pair(_U1&& __u1, _U2&& __u2)
+        _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
+                    is_nothrow_constructible<second_type, _U2>::value))
+        : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
+
+    template<class _U1, class _U2, _EnableB<
+            _CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>()
+    > = false>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    explicit pair(pair<_U1, _U2> const& __p)
+        _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
+                    is_nothrow_constructible<second_type, _U2 const&>::value))
+        : first(__p.first), second(__p.second) {}
+
+    template<class _U1, class _U2, _EnableB<
+            _CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>()
+    > = false>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    pair(pair<_U1, _U2> const& __p)
+        _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
+                    is_nothrow_constructible<second_type, _U2 const&>::value))
+        : first(__p.first), second(__p.second) {}
+
+    template<class _U1, class _U2, _EnableB<
+            _CheckArgs::template __enable_explicit<_U1, _U2>()
+    > = false>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    explicit pair(pair<_U1, _U2>&&__p)
+        _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
+                    is_nothrow_constructible<second_type, _U2&&>::value))
+        : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
+
+    template<class _U1, class _U2, _EnableB<
+            _CheckArgs::template __enable_implicit<_U1, _U2>()
+    > = false>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    pair(pair<_U1, _U2>&& __p)
+        _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
+                    is_nothrow_constructible<second_type, _U2&&>::value))
+        : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
+
+    template<class _Tuple, _EnableB<
+            _CheckTLC<_Tuple>::template __enable_explicit<_Tuple>()
+    > = false>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    explicit pair(_Tuple&& __p)
+        : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
+          second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
+
+    template<class _Tuple, _EnableB<
+            _CheckTLC<_Tuple>::template __enable_implicit<_Tuple>()
+    > = false>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    pair(_Tuple&& __p)
+        : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
+          second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
+
+    template <class... _Args1, class... _Args2>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    pair(piecewise_construct_t __pc,
+         tuple<_Args1...> __first_args, tuple<_Args2...> __second_args)
+        _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value &&
+                    is_nothrow_constructible<second_type, _Args2...>::value))
+        : pair(__pc, __first_args, __second_args,
+                typename __make_tuple_indices<sizeof...(_Args1)>::type(),
+                typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    pair& operator=(typename conditional<
+                        is_copy_assignable<first_type>::value &&
+                        is_copy_assignable<second_type>::value,
+                    pair, __nat>::type const& __p)
+        _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&
+                   is_nothrow_copy_assignable<second_type>::value)
+    {
+        first = __p.first;
+        second = __p.second;
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    pair& operator=(typename conditional<
+                        is_move_assignable<first_type>::value &&
+                        is_move_assignable<second_type>::value,
+                    pair, __nat>::type&& __p)
+        _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&
+                   is_nothrow_move_assignable<second_type>::value)
+    {
+        first = _VSTD::forward<first_type>(__p.first);
+        second = _VSTD::forward<second_type>(__p.second);
+        return *this;
+    }
+
+    template <class _Tuple, _EnableB<
+            _CheckTLC<_Tuple>::template __enable_assign<_Tuple>()
+     > = false>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    pair& operator=(_Tuple&& __p) {
+        first = _VSTD::get<0>(_VSTD::forward<_Tuple>(__p));
+        second = _VSTD::get<1>(_VSTD::forward<_Tuple>(__p));
+        return *this;
+    }
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    void
+    swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&
+                               __is_nothrow_swappable<second_type>::value)
+    {
+        using _VSTD::swap;
+        swap(first,  __p.first);
+        swap(second, __p.second);
+    }
+private:
+
+#ifndef _LIBCPP_CXX03_LANG
+    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    pair(piecewise_construct_t,
+         tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
+         __tuple_indices<_I1...>, __tuple_indices<_I2...>);
+#endif
+};
+
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+template<class _T1, class _T2>
+pair(_T1, _T2) -> pair<_T1, _T2>;
+#endif // _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+{
+    return __x.first == __y.first && __x.second == __y.second;
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator!=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+{
+    return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator> (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+{
+    return __y < __x;
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator>=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+typename enable_if
+<
+    __is_swappable<_T1>::value &&
+    __is_swappable<_T2>::value,
+    void
+>::type
+swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
+                     _NOEXCEPT_((__is_nothrow_swappable<_T1>::value &&
+                                 __is_nothrow_swappable<_T2>::value))
+{
+    __x.swap(__y);
+}
+
+#ifndef _LIBCPP_CXX03_LANG
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
+make_pair(_T1&& __t1, _T2&& __t2)
+{
+    return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
+               (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
+}
+
+#else  // _LIBCPP_CXX03_LANG
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+pair<_T1,_T2>
+make_pair(_T1 __x, _T2 __y)
+{
+    return pair<_T1, _T2>(__x, __y);
+}
+
+#endif // _LIBCPP_CXX03_LANG
+
+template <class _T1, class _T2>
+  struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> >
+    : public integral_constant<size_t, 2> {};
+
+template <size_t _Ip, class _T1, class _T2>
+struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> >
+{
+    static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
+};
+
+template <class _T1, class _T2>
+struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> >
+{
+    typedef _LIBCPP_NODEBUG_TYPE _T1 type;
+};
+
+template <class _T1, class _T2>
+struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> >
+{
+    typedef _LIBCPP_NODEBUG_TYPE _T2 type;
+};
+
+template <size_t _Ip> struct __get_pair;
+
+template <>
+struct __get_pair<0>
+{
+    template <class _T1, class _T2>
+    static
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    _T1&
+    get(pair<_T1, _T2>& __p) _NOEXCEPT {return __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 __p.first;}
+
+#ifndef _LIBCPP_CXX03_LANG
+    template <class _T1, class _T2>
+    static
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    _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_CXX03_LANG
+};
+
+template <>
+struct __get_pair<1>
+{
+    template <class _T1, class _T2>
+    static
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    _T2&
+    get(pair<_T1, _T2>& __p) _NOEXCEPT {return __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 __p.second;}
+
+#ifndef _LIBCPP_CXX03_LANG
+    template <class _T1, class _T2>
+    static
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    _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_CXX03_LANG
+};
+
+template <size_t _Ip, class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename tuple_element<_Ip, pair<_T1, _T2> >::type&
+get(pair<_T1, _T2>& __p) _NOEXCEPT
+{
+    return __get_pair<_Ip>::get(__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(__p);
+}
+
+#ifndef _LIBCPP_CXX03_LANG
+template <size_t _Ip, class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
+get(pair<_T1, _T2>&& __p) _NOEXCEPT
+{
+    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_CXX03_LANG
+
+#if _LIBCPP_STD_VER > 11
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT
+{
+    return __get_pair<0>::get(__p);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT
+{
+    return __get_pair<0>::get(__p);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT
+{
+    return __get_pair<0>::get(_VSTD::move(__p));
+}
+
+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);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT
+{
+    return __get_pair<1>::get(__p);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT
+{
+    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
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___UTILITY_PAIR_H
diff --git a/include/__utility/piecewise_construct.h b/include/__utility/piecewise_construct.h
new file mode 100644
index 0000000..8bef01c
--- /dev/null
+++ b/include/__utility/piecewise_construct.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_PIECEWISE_CONSTRUCT_H
+#define _LIBCPP___UTILITY_PIECEWISE_CONSTRUCT_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { explicit piecewise_construct_t() = default; };
+#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
+extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
+#else
+/* _LIBCPP_INLINE_VAR */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___UTILITY_PIECEWISE_CONSTRUCT_H
diff --git a/include/__utility/rel_ops.h b/include/__utility/rel_ops.h
new file mode 100644
index 0000000..b900da8
--- /dev/null
+++ b/include/__utility/rel_ops.h
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_REL_OPS_H
+#define _LIBCPP___UTILITY_REL_OPS_H
+
+#include <__config>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace rel_ops
+{
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const _Tp& __x, const _Tp& __y)
+{
+    return !(__x == __y);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const _Tp& __x, const _Tp& __y)
+{
+    return __y < __x;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const _Tp& __x, const _Tp& __y)
+{
+    return !(__y < __x);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const _Tp& __x, const _Tp& __y)
+{
+    return !(__x < __y);
+}
+
+}  // rel_ops
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___UTILITY_REL_OPS_H
diff --git a/include/__utility/swap.h b/include/__utility/swap.h
new file mode 100644
index 0000000..8af83a9
--- /dev/null
+++ b/include/__utility/swap.h
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_SWAP_H
+#define _LIBCPP___UTILITY_SWAP_H
+
+#include <__config>
+#include <__utility/declval.h>
+#include <__utility/move.h>
+#include <type_traits>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_CXX03_LANG
+template <class _Tp>
+using __swap_result_t = typename enable_if<is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value>::type;
+#else
+template <class>
+using __swap_result_t = void;
+#endif
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY __swap_result_t<_Tp> _LIBCPP_CONSTEXPR_AFTER_CXX17 swap(_Tp& __x, _Tp& __y)
+    _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value&& is_nothrow_move_assignable<_Tp>::value) {
+  _Tp __t(_VSTD::move(__x));
+  __x = _VSTD::move(__y);
+  __y = _VSTD::move(__t);
+}
+
+template <class _Tp, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename enable_if<__is_swappable<_Tp>::value>::type
+swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) {
+  for (size_t __i = 0; __i != _Np; ++__i) {
+    swap(__a[__i], __b[__i]);
+  }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___UTILITY_SWAP_H
diff --git a/include/__utility/to_underlying.h b/include/__utility/to_underlying.h
new file mode 100644
index 0000000..fd22f89
--- /dev/null
+++ b/include/__utility/to_underlying.h
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+//===----------------- __utility/to_underlying.h --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_TO_UNDERLYING_H
+#define _LIBCPP___UTILITY_TO_UNDERLYING_H
+
+#include <__config>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_CXX03_LANG
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY constexpr typename underlying_type<_Tp>::type
+__to_underlying(_Tp __val) noexcept {
+  return static_cast<typename underlying_type<_Tp>::type>(__val);
+}
+#endif // !_LIBCPP_CXX03_LANG
+
+#if _LIBCPP_STD_VER > 20
+template <class _Tp>
+_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY constexpr underlying_type_t<_Tp>
+to_underlying(_Tp __val) noexcept {
+  return _VSTD::__to_underlying(__val);
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___UTILITY_TO_UNDERLYING_H
diff --git a/include/__variant/monostate.h b/include/__variant/monostate.h
new file mode 100644
index 0000000..36e3eea
--- /dev/null
+++ b/include/__variant/monostate.h
@@ -0,0 +1,65 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___VARIANT_MONOSTATE_H
+#define _LIBCPP___VARIANT_MONOSTATE_H
+
+#include <__config>
+#include <__functional/hash.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+struct _LIBCPP_TEMPLATE_VIS monostate {};
+
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr bool operator<(monostate, monostate) noexcept { return false; }
+
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr bool operator>(monostate, monostate) noexcept { return false; }
+
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr bool operator<=(monostate, monostate) noexcept { return true; }
+
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr bool operator>=(monostate, monostate) noexcept { return true; }
+
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr bool operator==(monostate, monostate) noexcept { return true; }
+
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr bool operator!=(monostate, monostate) noexcept { return false; }
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
+  using argument_type = monostate;
+  using result_type = size_t;
+
+  inline _LIBCPP_INLINE_VISIBILITY
+  result_type operator()(const argument_type&) const _NOEXCEPT {
+    return 66740831; // return a fundamentally attractive random value.
+  }
+};
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___VARIANT_MONOSTATE_H
diff --git a/include/algorithm b/include/algorithm
index 3ba104b..849302a 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -1,10 +1,9 @@
 // -*- C++ -*-
 //===-------------------------- algorithm ---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -20,289 +19,309 @@
 {
 
 template <class InputIterator, class Predicate>
-    bool
+    constexpr bool     // constexpr in C++20
     all_of(InputIterator first, InputIterator last, Predicate pred);
 
 template <class InputIterator, class Predicate>
-    bool
+    constexpr bool     // constexpr in C++20
     any_of(InputIterator first, InputIterator last, Predicate pred);
 
 template <class InputIterator, class Predicate>
-    bool
+    constexpr bool     // constexpr in C++20
     none_of(InputIterator first, InputIterator last, Predicate pred);
 
 template <class InputIterator, class Function>
-    Function
+    constexpr Function          // constexpr in C++20
     for_each(InputIterator first, InputIterator last, Function f);
 
+template<class InputIterator, class Size, class Function>
+    constexpr InputIterator     // constexpr in C++20
+    for_each_n(InputIterator first, Size n, Function f); // C++17
+
 template <class InputIterator, class T>
-    InputIterator
+    constexpr InputIterator     // constexpr in C++20
     find(InputIterator first, InputIterator last, const T& value);
 
 template <class InputIterator, class Predicate>
-    InputIterator
+    constexpr InputIterator     // constexpr in C++20
     find_if(InputIterator first, InputIterator last, Predicate pred);
 
 template<class InputIterator, class Predicate>
-    InputIterator
+    constexpr InputIterator     // constexpr in C++20
     find_if_not(InputIterator first, InputIterator last, Predicate pred);
 
 template <class ForwardIterator1, class ForwardIterator2>
-    ForwardIterator1
+    constexpr ForwardIterator1  // constexpr in C++20
     find_end(ForwardIterator1 first1, ForwardIterator1 last1,
              ForwardIterator2 first2, ForwardIterator2 last2);
 
 template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
-    ForwardIterator1
+    constexpr ForwardIterator1  // constexpr in C++20
     find_end(ForwardIterator1 first1, ForwardIterator1 last1,
              ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);
 
 template <class ForwardIterator1, class ForwardIterator2>
-    ForwardIterator1
+    constexpr ForwardIterator1  // constexpr in C++20
     find_first_of(ForwardIterator1 first1, ForwardIterator1 last1,
                   ForwardIterator2 first2, ForwardIterator2 last2);
 
 template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
-    ForwardIterator1
+    constexpr ForwardIterator1  // constexpr in C++20
     find_first_of(ForwardIterator1 first1, ForwardIterator1 last1,
                   ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);
 
 template <class ForwardIterator>
-    ForwardIterator
+    constexpr ForwardIterator   // constexpr in C++20
     adjacent_find(ForwardIterator first, ForwardIterator last);
 
 template <class ForwardIterator, class BinaryPredicate>
-    ForwardIterator
+    constexpr ForwardIterator   // constexpr in C++20
     adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate pred);
 
 template <class InputIterator, class T>
-    typename iterator_traits<InputIterator>::difference_type
+    constexpr typename iterator_traits<InputIterator>::difference_type  // constexpr in C++20
     count(InputIterator first, InputIterator last, const T& value);
 
 template <class InputIterator, class Predicate>
-    typename iterator_traits<InputIterator>::difference_type
+    constexpr typename iterator_traits<InputIterator>::difference_type // constexpr in C++20
     count_if(InputIterator first, InputIterator last, Predicate pred);
 
 template <class InputIterator1, class InputIterator2>
-    pair<InputIterator1, InputIterator2>
+    constexpr pair<InputIterator1, InputIterator2>   // constexpr in C++20
     mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);
 
 template <class InputIterator1, class InputIterator2>
-    pair<InputIterator1, InputIterator2>
-    mismatch(InputIterator1 first1, InputIterator1 last1, 
+    constexpr pair<InputIterator1, InputIterator2>   // constexpr in C++20
+    mismatch(InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2, InputIterator2 last2); // **C++14**
 
 template <class InputIterator1, class InputIterator2, class BinaryPredicate>
-    pair<InputIterator1, InputIterator2>
+    constexpr pair<InputIterator1, InputIterator2>   // constexpr in C++20
     mismatch(InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2, BinaryPredicate pred);
 
 template <class InputIterator1, class InputIterator2, class BinaryPredicate>
-    pair<InputIterator1, InputIterator2>
+    constexpr pair<InputIterator1, InputIterator2>   // constexpr in C++20
     mismatch(InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2, InputIterator2 last2,
              BinaryPredicate pred); // **C++14**
 
 template <class InputIterator1, class InputIterator2>
-    bool
+    constexpr bool      // constexpr in C++20
     equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);
 
 template <class InputIterator1, class InputIterator2>
-    bool
-    equal(InputIterator1 first1, InputIterator1 last1, 
+    constexpr bool      // constexpr in C++20
+    equal(InputIterator1 first1, InputIterator1 last1,
           InputIterator2 first2, InputIterator2 last2); // **C++14**
 
 template <class InputIterator1, class InputIterator2, class BinaryPredicate>
-    bool
+    constexpr bool      // constexpr in C++20
     equal(InputIterator1 first1, InputIterator1 last1,
           InputIterator2 first2, BinaryPredicate pred);
 
 template <class InputIterator1, class InputIterator2, class BinaryPredicate>
-    bool
+    constexpr bool      // constexpr in C++20
     equal(InputIterator1 first1, InputIterator1 last1,
           InputIterator2 first2, InputIterator2 last2,
           BinaryPredicate pred); // **C++14**
 
 template<class ForwardIterator1, class ForwardIterator2>
-    bool
+    constexpr bool      // constexpr in C++20
     is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                    ForwardIterator2 first2);
 
 template<class ForwardIterator1, class ForwardIterator2>
-    bool
+    constexpr bool      // constexpr in C++20
     is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                    ForwardIterator2 first2, ForwardIterator2 last2); // **C++14**
 
 template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
-    bool
+    constexpr bool      // constexpr in C++20
     is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                    ForwardIterator2 first2, BinaryPredicate pred);
 
 template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
-    bool
+    constexpr bool      // constexpr in C++20
     is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                    ForwardIterator2 first2, ForwardIterator2 last2,
                    BinaryPredicate pred);  // **C++14**
 
 template <class ForwardIterator1, class ForwardIterator2>
-    ForwardIterator1
+    constexpr ForwardIterator1      // constexpr in C++20
     search(ForwardIterator1 first1, ForwardIterator1 last1,
            ForwardIterator2 first2, ForwardIterator2 last2);
 
 template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
-    ForwardIterator1
+    constexpr ForwardIterator1      // constexpr in C++20
     search(ForwardIterator1 first1, ForwardIterator1 last1,
            ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);
 
 template <class ForwardIterator, class Size, class T>
-    ForwardIterator
+    constexpr ForwardIterator       // constexpr in C++20
     search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value);
 
 template <class ForwardIterator, class Size, class T, class BinaryPredicate>
-    ForwardIterator
+    constexpr ForwardIterator       // constexpr in C++20
     search_n(ForwardIterator first, ForwardIterator last,
              Size count, const T& value, BinaryPredicate pred);
 
 template <class InputIterator, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator      // constexpr in C++20
     copy(InputIterator first, InputIterator last, OutputIterator result);
 
 template<class InputIterator, class OutputIterator, class Predicate>
-    OutputIterator
+    constexpr OutputIterator      // constexpr in C++20
     copy_if(InputIterator first, InputIterator last,
             OutputIterator result, Predicate pred);
 
 template<class InputIterator, class Size, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator      // constexpr in C++20
     copy_n(InputIterator first, Size n, OutputIterator result);
 
 template <class BidirectionalIterator1, class BidirectionalIterator2>
-    BidirectionalIterator2
+    constexpr BidirectionalIterator2      // constexpr in C++20
     copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last,
                   BidirectionalIterator2 result);
 
 template <class ForwardIterator1, class ForwardIterator2>
-    ForwardIterator2
+    constexpr ForwardIterator2    // constexpr in C++20
     swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2);
 
 template <class ForwardIterator1, class ForwardIterator2>
-    void
+    constexpr void                // constexpr in C++20
     iter_swap(ForwardIterator1 a, ForwardIterator2 b);
 
 template <class InputIterator, class OutputIterator, class UnaryOperation>
-    OutputIterator
+    constexpr OutputIterator      // constexpr in C++20
     transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op);
 
 template <class InputIterator1, class InputIterator2, class OutputIterator, class BinaryOperation>
-    OutputIterator
+    constexpr OutputIterator      // constexpr in C++20
     transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,
               OutputIterator result, BinaryOperation binary_op);
 
 template <class ForwardIterator, class T>
-    void
+    constexpr void      // constexpr in C++20
     replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value);
 
 template <class ForwardIterator, class Predicate, class T>
-    void
+    constexpr void      // constexpr in C++20
     replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value);
 
 template <class InputIterator, class OutputIterator, class T>
-    OutputIterator
+    constexpr OutputIterator      // constexpr in C++20
     replace_copy(InputIterator first, InputIterator last, OutputIterator result,
                  const T& old_value, const T& new_value);
 
 template <class InputIterator, class OutputIterator, class Predicate, class T>
-    OutputIterator
+    constexpr OutputIterator      // constexpr in C++20
     replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value);
 
 template <class ForwardIterator, class T>
-    void
+    constexpr void      // constexpr in C++20
     fill(ForwardIterator first, ForwardIterator last, const T& value);
 
 template <class OutputIterator, class Size, class T>
-    OutputIterator
+    constexpr OutputIterator      // constexpr in C++20
     fill_n(OutputIterator first, Size n, const T& value);
 
 template <class ForwardIterator, class Generator>
-    void
+    constexpr void      // constexpr in C++20
     generate(ForwardIterator first, ForwardIterator last, Generator gen);
 
 template <class OutputIterator, class Size, class Generator>
-    OutputIterator
+    constexpr OutputIterator      // constexpr in C++20
     generate_n(OutputIterator first, Size n, Generator gen);
 
 template <class ForwardIterator, class T>
-    ForwardIterator
+    constexpr ForwardIterator     // constexpr in C++20
     remove(ForwardIterator first, ForwardIterator last, const T& value);
 
 template <class ForwardIterator, class Predicate>
-    ForwardIterator
+    constexpr ForwardIterator     // constexpr in C++20
     remove_if(ForwardIterator first, ForwardIterator last, Predicate pred);
 
 template <class InputIterator, class OutputIterator, class T>
-    OutputIterator
+    constexpr OutputIterator     // constexpr in C++20
     remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value);
 
 template <class InputIterator, class OutputIterator, class Predicate>
-    OutputIterator
+    constexpr OutputIterator     // constexpr in C++20
     remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred);
 
 template <class ForwardIterator>
-    ForwardIterator
+    constexpr ForwardIterator    // constexpr in C++20
     unique(ForwardIterator first, ForwardIterator last);
 
 template <class ForwardIterator, class BinaryPredicate>
-    ForwardIterator
+    constexpr ForwardIterator    // constexpr in C++20
     unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred);
 
 template <class InputIterator, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator     // constexpr in C++20
     unique_copy(InputIterator first, InputIterator last, OutputIterator result);
 
 template <class InputIterator, class OutputIterator, class BinaryPredicate>
-    OutputIterator
+    constexpr OutputIterator     // constexpr in C++20
     unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred);
 
 template <class BidirectionalIterator>
-    void
+    constexpr void               // constexpr in C++20
     reverse(BidirectionalIterator first, BidirectionalIterator last);
 
 template <class BidirectionalIterator, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator       // constexpr in C++20
     reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result);
 
 template <class ForwardIterator>
-    ForwardIterator
+    constexpr ForwardIterator      // constexpr in C++20
     rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last);
 
 template <class ForwardIterator, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator       // constexpr in C++20
     rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result);
 
 template <class RandomAccessIterator>
     void
-    random_shuffle(RandomAccessIterator first, RandomAccessIterator last); // deprecated in C++14
+    random_shuffle(RandomAccessIterator first, RandomAccessIterator last); // deprecated in C++14, removed in C++17
 
 template <class RandomAccessIterator, class RandomNumberGenerator>
     void
     random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
-                   RandomNumberGenerator& rand);  // deprecated in C++14
+                   RandomNumberGenerator& rand);  // deprecated in C++14, removed in C++17
+
+template<class PopulationIterator, class SampleIterator,
+         class Distance, class UniformRandomBitGenerator>
+    SampleIterator sample(PopulationIterator first, PopulationIterator last,
+                          SampleIterator out, Distance n,
+                          UniformRandomBitGenerator&& g); // C++17
 
 template<class RandomAccessIterator, class UniformRandomNumberGenerator>
     void shuffle(RandomAccessIterator first, RandomAccessIterator last,
                  UniformRandomNumberGenerator&& g);
 
+template<class ForwardIterator>
+  constexpr ForwardIterator
+    shift_left(ForwardIterator first, ForwardIterator last,
+               typename iterator_traits<ForwardIterator>::difference_type n); // C++20
+
+template<class ForwardIterator>
+  constexpr ForwardIterator
+    shift_right(ForwardIterator first, ForwardIterator last,
+                typename iterator_traits<ForwardIterator>::difference_type n); // C++20
+
 template <class InputIterator, class Predicate>
-    bool
+    constexpr bool  // constexpr in C++20
     is_partitioned(InputIterator first, InputIterator last, Predicate pred);
 
 template <class ForwardIterator, class Predicate>
-    ForwardIterator
+    constexpr ForwardIterator  // constexpr in C++20
     partition(ForwardIterator first, ForwardIterator last, Predicate pred);
 
 template <class InputIterator, class OutputIterator1,
           class OutputIterator2, class Predicate>
-    pair<OutputIterator1, OutputIterator2>
+    constexpr pair<OutputIterator1, OutputIterator2>   // constexpr in C++20
     partition_copy(InputIterator first, InputIterator last,
                    OutputIterator1 out_true, OutputIterator2 out_false,
                    Predicate pred);
@@ -312,31 +331,31 @@
     stable_partition(ForwardIterator first, ForwardIterator last, Predicate pred);
 
 template<class ForwardIterator, class Predicate>
-    ForwardIterator
+    constexpr ForwardIterator  // constexpr in C++20
     partition_point(ForwardIterator first, ForwardIterator last, Predicate pred);
 
 template <class ForwardIterator>
-    bool
+    constexpr bool  // constexpr in C++20
     is_sorted(ForwardIterator first, ForwardIterator last);
 
 template <class ForwardIterator, class Compare>
-    bool
+    constexpr bool  // constexpr in C++20
     is_sorted(ForwardIterator first, ForwardIterator last, Compare comp);
 
 template<class ForwardIterator>
-    ForwardIterator
+    constexpr ForwardIterator    // constexpr in C++20
     is_sorted_until(ForwardIterator first, ForwardIterator last);
 
 template <class ForwardIterator, class Compare>
-    ForwardIterator
+    constexpr ForwardIterator    // constexpr in C++20
     is_sorted_until(ForwardIterator first, ForwardIterator last, Compare comp);
 
 template <class RandomAccessIterator>
-    void
+    constexpr void               // constexpr in C++20
     sort(RandomAccessIterator first, RandomAccessIterator last);
 
 template <class RandomAccessIterator, class Compare>
-    void
+    constexpr void               // constexpr in C++20
     sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
 
 template <class RandomAccessIterator>
@@ -348,70 +367,70 @@
     stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
 
 template <class RandomAccessIterator>
-    void
+    constexpr void                    // constexpr in C++20
     partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last);
 
 template <class RandomAccessIterator, class Compare>
-    void
+    constexpr void                    // constexpr in C++20
     partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp);
 
 template <class InputIterator, class RandomAccessIterator>
-    RandomAccessIterator
+    constexpr RandomAccessIterator    // constexpr in C++20
     partial_sort_copy(InputIterator first, InputIterator last,
                       RandomAccessIterator result_first, RandomAccessIterator result_last);
 
 template <class InputIterator, class RandomAccessIterator, class Compare>
-    RandomAccessIterator
+    constexpr RandomAccessIterator    // constexpr in C++20
     partial_sort_copy(InputIterator first, InputIterator last,
                       RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp);
 
 template <class RandomAccessIterator>
-    void
+    constexpr void                    // constexpr in C++20
     nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last);
 
 template <class RandomAccessIterator, class Compare>
-    void
+    constexpr void                    // constexpr in C++20
     nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp);
 
 template <class ForwardIterator, class T>
-    ForwardIterator
+    constexpr ForwardIterator                         // constexpr in C++20
     lower_bound(ForwardIterator first, ForwardIterator last, const T& value);
 
 template <class ForwardIterator, class T, class Compare>
-    ForwardIterator
+    constexpr ForwardIterator                         // constexpr in C++20
     lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);
 
 template <class ForwardIterator, class T>
-    ForwardIterator
+    constexpr ForwardIterator                         // constexpr in C++20
     upper_bound(ForwardIterator first, ForwardIterator last, const T& value);
 
 template <class ForwardIterator, class T, class Compare>
-    ForwardIterator
+    constexpr ForwardIterator                         // constexpr in C++20
     upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);
 
 template <class ForwardIterator, class T>
-    pair<ForwardIterator, ForwardIterator>
+    constexpr pair<ForwardIterator, ForwardIterator>  // constexpr in C++20
     equal_range(ForwardIterator first, ForwardIterator last, const T& value);
 
 template <class ForwardIterator, class T, class Compare>
-    pair<ForwardIterator, ForwardIterator>
+    constexpr pair<ForwardIterator, ForwardIterator>  // constexpr in C++20
     equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);
 
 template <class ForwardIterator, class T>
-    bool
+    constexpr bool                                    // constexpr in C++20
     binary_search(ForwardIterator first, ForwardIterator last, const T& value);
 
 template <class ForwardIterator, class T, class Compare>
-    bool
+    constexpr bool                                    // constexpr in C++20
     binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);
 
 template <class InputIterator1, class InputIterator2, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator                          // constexpr in C++20
     merge(InputIterator1 first1, InputIterator1 last1,
           InputIterator2 first2, InputIterator2 last2, OutputIterator result);
 
 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
-    OutputIterator
+    constexpr OutputIterator                          // constexpr in C++20
     merge(InputIterator1 first1, InputIterator1 last1,
           InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);
 
@@ -424,196 +443,202 @@
     inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp);
 
 template <class InputIterator1, class InputIterator2>
-    bool
+    constexpr bool                                    // constexpr in C++20
     includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2);
 
 template <class InputIterator1, class InputIterator2, class Compare>
-    bool
+    constexpr bool                                    // constexpr in C++20
     includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp);
 
 template <class InputIterator1, class InputIterator2, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator                          // constexpr in C++20
     set_union(InputIterator1 first1, InputIterator1 last1,
               InputIterator2 first2, InputIterator2 last2, OutputIterator result);
 
 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
-    OutputIterator
+    constexpr OutputIterator                          // constexpr in C++20
     set_union(InputIterator1 first1, InputIterator1 last1,
               InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);
 
 template <class InputIterator1, class InputIterator2, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator                         // constexpr in C++20
     set_intersection(InputIterator1 first1, InputIterator1 last1,
                      InputIterator2 first2, InputIterator2 last2, OutputIterator result);
 
 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
-    OutputIterator
+    constexpr OutputIterator                         // constexpr in C++20
     set_intersection(InputIterator1 first1, InputIterator1 last1,
                      InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);
 
 template <class InputIterator1, class InputIterator2, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator                         // constexpr in C++20
     set_difference(InputIterator1 first1, InputIterator1 last1,
                    InputIterator2 first2, InputIterator2 last2, OutputIterator result);
 
 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
-    OutputIterator
+    constexpr OutputIterator                         // constexpr in C++20
     set_difference(InputIterator1 first1, InputIterator1 last1,
                    InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);
 
 template <class InputIterator1, class InputIterator2, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator                         // constexpr in C++20
     set_symmetric_difference(InputIterator1 first1, InputIterator1 last1,
                              InputIterator2 first2, InputIterator2 last2, OutputIterator result);
 
 template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
-    OutputIterator
+    constexpr OutputIterator                         // constexpr in C++20
     set_symmetric_difference(InputIterator1 first1, InputIterator1 last1,
                              InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);
 
 template <class RandomAccessIterator>
-    void
+    constexpr void                                   // constexpr in C++20
     push_heap(RandomAccessIterator first, RandomAccessIterator last);
 
 template <class RandomAccessIterator, class Compare>
-    void
+    constexpr void                                   // constexpr in C++20
     push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
 
 template <class RandomAccessIterator>
-    void
+    constexpr void                                   // constexpr in C++20
     pop_heap(RandomAccessIterator first, RandomAccessIterator last);
 
 template <class RandomAccessIterator, class Compare>
-    void
+    constexpr void                                   // constexpr in C++20
     pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
 
 template <class RandomAccessIterator>
-    void
+    constexpr void                                   // constexpr in C++20
     make_heap(RandomAccessIterator first, RandomAccessIterator last);
 
 template <class RandomAccessIterator, class Compare>
-    void
+    constexpr void                                   // constexpr in C++20
     make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
 
 template <class RandomAccessIterator>
-    void
+    constexpr void                                   // constexpr in C++20
     sort_heap(RandomAccessIterator first, RandomAccessIterator last);
 
 template <class RandomAccessIterator, class Compare>
-    void
+    constexpr void                                   // constexpr in C++20
     sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
 
 template <class RandomAccessIterator>
-    bool
+    constexpr bool   // constexpr in C++20
     is_heap(RandomAccessIterator first, RandomAccessiterator last);
 
 template <class RandomAccessIterator, class Compare>
-    bool
+    constexpr bool   // constexpr in C++20
     is_heap(RandomAccessIterator first, RandomAccessiterator last, Compare comp);
 
 template <class RandomAccessIterator>
-    RandomAccessIterator
+    constexpr RandomAccessIterator   // constexpr in C++20
     is_heap_until(RandomAccessIterator first, RandomAccessiterator last);
 
 template <class RandomAccessIterator, class Compare>
-    RandomAccessIterator
+    constexpr RandomAccessIterator   // constexpr in C++20
     is_heap_until(RandomAccessIterator first, RandomAccessiterator last, Compare comp);
 
 template <class ForwardIterator>
-    ForwardIterator
+    constexpr ForwardIterator        // constexpr in C++14
     min_element(ForwardIterator first, ForwardIterator last);
 
 template <class ForwardIterator, class Compare>
-    ForwardIterator
+    constexpr ForwardIterator        // constexpr in C++14
     min_element(ForwardIterator first, ForwardIterator last, Compare comp);
 
 template <class T>
-    const T&
-    min(const T& a, const T& b);  // constexpr in C++14
+    constexpr const T&               // constexpr in C++14
+    min(const T& a, const T& b);
 
 template <class T, class Compare>
-    const T&
-    min(const T& a, const T& b, Compare comp);  // constexpr in C++14
+    constexpr const T&               // constexpr in C++14
+    min(const T& a, const T& b, Compare comp);
 
 template<class T>
-    T
-    min(initializer_list<T> t);  // constexpr in C++14
+    constexpr T                      // constexpr in C++14
+    min(initializer_list<T> t);
 
 template<class T, class Compare>
-    T
-    min(initializer_list<T> t, Compare comp);  // constexpr in C++14
+    constexpr T                      // constexpr in C++14
+    min(initializer_list<T> t, Compare comp);
+
+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
+    constexpr ForwardIterator        // constexpr in C++14
     max_element(ForwardIterator first, ForwardIterator last);
 
 template <class ForwardIterator, class Compare>
-    ForwardIterator
+    constexpr ForwardIterator        // constexpr in C++14
     max_element(ForwardIterator first, ForwardIterator last, Compare comp);
 
 template <class T>
-    const T&
-    max(const T& a, const T& b); // constexpr in C++14
+    constexpr const T&               // constexpr in C++14
+    max(const T& a, const T& b);
 
 template <class T, class Compare>
-    const T&
-    max(const T& a, const T& b, Compare comp);  // constexpr in C++14
+    constexpr const T&               // constexpr in C++14
+    max(const T& a, const T& b, Compare comp);
 
 template<class T>
-    T
-    max(initializer_list<T> t);  // constexpr in C++14
+    constexpr T                      // constexpr in C++14
+    max(initializer_list<T> t);
 
 template<class T, class Compare>
-    T
-    max(initializer_list<T> t, Compare comp);  // constexpr in C++14
+    constexpr T                      // constexpr in C++14
+    max(initializer_list<T> t, Compare comp);
 
 template<class ForwardIterator>
-    pair<ForwardIterator, ForwardIterator>
+    constexpr pair<ForwardIterator, ForwardIterator>  // constexpr in C++14
     minmax_element(ForwardIterator first, ForwardIterator last);
 
 template<class ForwardIterator, class Compare>
-    pair<ForwardIterator, ForwardIterator>
+    constexpr pair<ForwardIterator, ForwardIterator>  // constexpr in C++14
     minmax_element(ForwardIterator first, ForwardIterator last, Compare comp);
 
 template<class T>
-    pair<const T&, const T&>
-    minmax(const T& a, const T& b);  // constexpr in C++14
+    constexpr pair<const T&, const T&>  // constexpr in C++14
+    minmax(const T& a, const T& b);
 
 template<class T, class Compare>
-    pair<const T&, const T&>
-    minmax(const T& a, const T& b, Compare comp);  // constexpr in C++14
+    constexpr pair<const T&, const T&>  // constexpr in C++14
+    minmax(const T& a, const T& b, Compare comp);
 
 template<class T>
-    pair<T, T>
-    minmax(initializer_list<T> t);  // constexpr in C++14
+    constexpr pair<T, T>                // constexpr in C++14
+    minmax(initializer_list<T> t);
 
 template<class T, class Compare>
-    pair<T, T>
-    minmax(initializer_list<T> t, Compare comp);  // constexpr in C++14
+    constexpr pair<T, T>                // constexpr in C++14
+    minmax(initializer_list<T> t, Compare comp);
 
 template <class InputIterator1, class InputIterator2>
-    bool
+    constexpr bool     // constexpr in C++20
     lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2);
 
 template <class InputIterator1, class InputIterator2, class Compare>
-    bool
+    constexpr bool     // constexpr in C++20
     lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, InputIterator2 last2, Compare comp);
 
 template <class BidirectionalIterator>
-    bool
+    constexpr bool     // constexpr in C++20
     next_permutation(BidirectionalIterator first, BidirectionalIterator last);
 
 template <class BidirectionalIterator, class Compare>
-    bool
+    constexpr bool     // constexpr in C++20
     next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp);
 
 template <class BidirectionalIterator>
-    bool
+    constexpr bool     // constexpr in C++20
     prev_permutation(BidirectionalIterator first, BidirectionalIterator last);
 
 template <class BidirectionalIterator, class Compare>
-    bool
+    constexpr bool     // constexpr in C++20
     prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp);
 
 }  // std
@@ -621,5145 +646,125 @@
 */
 
 #include <__config>
-#include <initializer_list>
-#include <type_traits>
+#include <__debug>
+#include <__bits> // __libcpp_clz
+#include <cstddef>
 #include <cstring>
-#include <utility>
+#include <functional>
+#include <initializer_list>
+#include <utility> // needed to provide swap_ranges.
 #include <memory>
 #include <iterator>
-#include <cstddef>
+#include <memory>
+#include <type_traits>
+#include <utility> // swap_ranges
+#include <version>
 
-#if defined(__IBMCPP__)
-#include "support/ibm/support.h"
-#endif
-#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
-#include "support/win32/support.h"
-#endif
-
-#include <__undef_min_max>
-
-#include <__debug>
+#include <__algorithm/adjacent_find.h>
+#include <__algorithm/all_of.h>
+#include <__algorithm/any_of.h>
+#include <__algorithm/binary_search.h>
+#include <__algorithm/clamp.h>
+#include <__algorithm/comp.h>
+#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/copy.h>
+#include <__algorithm/copy_backward.h>
+#include <__algorithm/copy_if.h>
+#include <__algorithm/copy_n.h>
+#include <__algorithm/count.h>
+#include <__algorithm/count_if.h>
+#include <__algorithm/equal.h>
+#include <__algorithm/equal_range.h>
+#include <__algorithm/fill_n.h>
+#include <__algorithm/fill.h>
+#include <__algorithm/find.h>
+#include <__algorithm/find_end.h>
+#include <__algorithm/find_first_of.h>
+#include <__algorithm/find_if.h>
+#include <__algorithm/find_if_not.h>
+#include <__algorithm/for_each.h>
+#include <__algorithm/for_each_n.h>
+#include <__algorithm/generate_n.h>
+#include <__algorithm/generate.h>
+#include <__algorithm/half_positive.h>
+#include <__algorithm/includes.h>
+#include <__algorithm/inplace_merge.h>
+#include <__algorithm/is_heap.h>
+#include <__algorithm/is_heap_until.h>
+#include <__algorithm/is_partitioned.h>
+#include <__algorithm/is_permutation.h>
+#include <__algorithm/is_sorted.h>
+#include <__algorithm/is_sorted_until.h>
+#include <__algorithm/iter_swap.h>
+#include <__algorithm/lexicographical_compare.h>
+#include <__algorithm/lower_bound.h>
+#include <__algorithm/make_heap.h>
+#include <__algorithm/max.h>
+#include <__algorithm/max_element.h>
+#include <__algorithm/merge.h>
+#include <__algorithm/min.h>
+#include <__algorithm/min_element.h>
+#include <__algorithm/minmax.h>
+#include <__algorithm/minmax_element.h>
+#include <__algorithm/mismatch.h>
+#include <__algorithm/move.h>
+#include <__algorithm/move_backward.h>
+#include <__algorithm/next_permutation.h>
+#include <__algorithm/none_of.h>
+#include <__algorithm/nth_element.h>
+#include <__algorithm/partial_sort.h>
+#include <__algorithm/partial_sort_copy.h>
+#include <__algorithm/partition.h>
+#include <__algorithm/partition_copy.h>
+#include <__algorithm/partition_point.h>
+#include <__algorithm/pop_heap.h>
+#include <__algorithm/prev_permutation.h>
+#include <__algorithm/push_heap.h>
+#include <__algorithm/remove.h>
+#include <__algorithm/remove_copy.h>
+#include <__algorithm/remove_copy_if.h>
+#include <__algorithm/remove_if.h>
+#include <__algorithm/replace.h>
+#include <__algorithm/replace_copy.h>
+#include <__algorithm/replace_copy_if.h>
+#include <__algorithm/replace_if.h>
+#include <__algorithm/reverse.h>
+#include <__algorithm/reverse_copy.h>
+#include <__algorithm/rotate.h>
+#include <__algorithm/rotate_copy.h>
+#include <__algorithm/sample.h>
+#include <__algorithm/search.h>
+#include <__algorithm/search_n.h>
+#include <__algorithm/set_difference.h>
+#include <__algorithm/set_intersection.h>
+#include <__algorithm/set_symmetric_difference.h>
+#include <__algorithm/set_union.h>
+#include <__algorithm/shift_left.h>
+#include <__algorithm/shift_right.h>
+#include <__algorithm/shuffle.h>
+#include <__algorithm/sift_down.h>
+#include <__algorithm/sort.h>
+#include <__algorithm/sort_heap.h>
+#include <__algorithm/stable_partition.h>
+#include <__algorithm/stable_sort.h>
+#include <__algorithm/swap_ranges.h>
+#include <__algorithm/transform.h>
+#include <__algorithm/unique_copy.h>
+#include <__algorithm/unique.h>
+#include <__algorithm/unwrap_iter.h>
+#include <__algorithm/upper_bound.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
 
-_LIBCPP_BEGIN_NAMESPACE_STD
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
 
-// I'd like to replace these with _VSTD::equal_to<void>, but can't because:
-//   * That only works with C++14 and later, and
-//   * We haven't included <functional> here.
-template <class _T1, class _T2 = _T1>
-struct __equal_to
-{
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;}
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;}
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;}
-};
+_LIBCPP_POP_MACROS
 
-template <class _T1>
-struct __equal_to<_T1, _T1>
-{
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
-};
-
-template <class _T1>
-struct __equal_to<const _T1, _T1>
-{
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
-};
-
-template <class _T1>
-struct __equal_to<_T1, const _T1>
-{
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
-};
-
-template <class _T1, class _T2 = _T1>
-struct __less
-{
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 
-    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
-
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-    bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;}
-
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-    bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;}
-
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-    bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;}
-};
-
-template <class _T1>
-struct __less<_T1, _T1>
-{
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
-};
-
-template <class _T1>
-struct __less<const _T1, _T1>
-{
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
-};
-
-template <class _T1>
-struct __less<_T1, const _T1>
-{
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
-};
-
-template <class _Predicate>
-class __negate
-{
-private:
-    _Predicate __p_;
-public:
-    _LIBCPP_INLINE_VISIBILITY __negate() {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    explicit __negate(_Predicate __p) : __p_(__p) {}
-
-    template <class _T1>
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _T1& __x) {return !__p_(__x);}
-
-    template <class _T1, class _T2>
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _T1& __x, const _T2& __y) {return !__p_(__x, __y);}
-};
-
-#ifdef _LIBCPP_DEBUG
-
-template <class _Compare>
-struct __debug_less
-{
-    _Compare __comp_;
-    __debug_less(_Compare& __c) : __comp_(__c) {}
-    template <class _Tp, class _Up>
-    bool operator()(const _Tp& __x, const _Up& __y)
-    {
-        bool __r = __comp_(__x, __y);
-        if (__r)
-            _LIBCPP_ASSERT(!__comp_(__y, __x), "Comparator does not induce a strict weak ordering");
-        return __r;
-    }
-};
-
-#endif  // _LIBCPP_DEBUG
-
-// Precondition:  __x != 0
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned
-__ctz(unsigned __x)
-{
-    return static_cast<unsigned>(__builtin_ctz(__x));
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned long
-__ctz(unsigned long __x)
-{
-    return static_cast<unsigned long>(__builtin_ctzl(__x));
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned long long
-__ctz(unsigned long long __x)
-{
-    return static_cast<unsigned long long>(__builtin_ctzll(__x));
-}
-
-// Precondition:  __x != 0
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned
-__clz(unsigned __x)
-{
-    return static_cast<unsigned>(__builtin_clz(__x));
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned long
-__clz(unsigned long __x)
-{
-    return static_cast<unsigned long>(__builtin_clzl (__x));
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned long long
-__clz(unsigned long long __x)
-{
-    return static_cast<unsigned long long>(__builtin_clzll(__x));
-}
-
-inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned           __x) {return __builtin_popcount  (__x);}
-inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned      long __x) {return __builtin_popcountl (__x);}
-inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned long long __x) {return __builtin_popcountll(__x);}
-
-// all_of
-
-template <class _InputIterator, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
-{
-    for (; __first != __last; ++__first)
-        if (!__pred(*__first))
-            return false;
-    return true;
-}
-
-// any_of
-
-template <class _InputIterator, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
-{
-    for (; __first != __last; ++__first)
-        if (__pred(*__first))
-            return true;
-    return false;
-}
-
-// none_of
-
-template <class _InputIterator, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
-{
-    for (; __first != __last; ++__first)
-        if (__pred(*__first))
-            return false;
-    return true;
-}
-
-// for_each
-
-template <class _InputIterator, class _Function>
-inline _LIBCPP_INLINE_VISIBILITY
-_Function
-for_each(_InputIterator __first, _InputIterator __last, _Function __f)
-{
-    for (; __first != __last; ++__first)
-        __f(*__first);
-    return _VSTD::move(__f);  // explicitly moved for (emulated) C++03
-}
-
-// find
-
-template <class _InputIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-_InputIterator
-find(_InputIterator __first, _InputIterator __last, const _Tp& __value_)
-{
-    for (; __first != __last; ++__first)
-        if (*__first == __value_)
-            break;
-    return __first;
-}
-
-// find_if
-
-template <class _InputIterator, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
-_InputIterator
-find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
-{
-    for (; __first != __last; ++__first)
-        if (__pred(*__first))
-            break;
-    return __first;
-}
-
-// find_if_not
-
-template<class _InputIterator, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
-_InputIterator
-find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred)
-{
-    for (; __first != __last; ++__first)
-        if (!__pred(*__first))
-            break;
-    return __first;
-}
-
-// find_end
-
-template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
-_ForwardIterator1
-__find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-           _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred,
-           forward_iterator_tag, forward_iterator_tag)
-{
-    // modeled after search algorithm
-    _ForwardIterator1 __r = __last1;  // __last1 is the "default" answer
-    if (__first2 == __last2)
-        return __r;
-    while (true)
-    {
-        while (true)
-        {
-            if (__first1 == __last1)         // if source exhausted return last correct answer
-                return __r;                  //    (or __last1 if never found)
-            if (__pred(*__first1, *__first2))
-                break;
-            ++__first1;
-        }
-        // *__first1 matches *__first2, now match elements after here
-        _ForwardIterator1 __m1 = __first1;
-        _ForwardIterator2 __m2 = __first2;
-        while (true)
-        {
-            if (++__m2 == __last2)
-            {                         // Pattern exhaused, record answer and search for another one
-                __r = __first1;
-                ++__first1;
-                break;
-            }
-            if (++__m1 == __last1)     // Source exhausted, return last answer
-                return __r;
-            if (!__pred(*__m1, *__m2))  // mismatch, restart with a new __first
-            {
-                ++__first1;
-                break;
-            }  // else there is a match, check next elements
-        }
-    }
-}
-
-template <class _BinaryPredicate, class _BidirectionalIterator1, class _BidirectionalIterator2>
-_BidirectionalIterator1
-__find_end(_BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1,
-           _BidirectionalIterator2 __first2, _BidirectionalIterator2 __last2, _BinaryPredicate __pred,
-           bidirectional_iterator_tag, bidirectional_iterator_tag)
-{
-    // modeled after search algorithm (in reverse)
-    if (__first2 == __last2)
-        return __last1;  // Everything matches an empty sequence
-    _BidirectionalIterator1 __l1 = __last1;
-    _BidirectionalIterator2 __l2 = __last2;
-    --__l2;
-    while (true)
-    {
-        // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks
-        while (true)
-        {
-            if (__first1 == __l1)  // return __last1 if no element matches *__first2
-                return __last1;
-            if (__pred(*--__l1, *__l2))
-                break;
-        }
-        // *__l1 matches *__l2, now match elements before here
-        _BidirectionalIterator1 __m1 = __l1;
-        _BidirectionalIterator2 __m2 = __l2;
-        while (true)
-        {
-            if (__m2 == __first2)  // If pattern exhausted, __m1 is the answer (works for 1 element pattern)
-                return __m1;
-            if (__m1 == __first1)  // Otherwise if source exhaused, pattern not found
-                return __last1;
-            if (!__pred(*--__m1, *--__m2))  // if there is a mismatch, restart with a new __l1
-            {
-                break;
-            }  // else there is a match, check next elements
-        }
-    }
-}
-
-template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1
-__find_end(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
-           _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred,
-           random_access_iterator_tag, random_access_iterator_tag)
-{
-    // Take advantage of knowing source and pattern lengths.  Stop short when source is smaller than pattern
-    typename iterator_traits<_RandomAccessIterator2>::difference_type __len2 = __last2 - __first2;
-    if (__len2 == 0)
-        return __last1;
-    typename iterator_traits<_RandomAccessIterator1>::difference_type __len1 = __last1 - __first1;
-    if (__len1 < __len2)
-        return __last1;
-    const _RandomAccessIterator1 __s = __first1 + (__len2 - 1);  // End of pattern match can't go before here
-    _RandomAccessIterator1 __l1 = __last1;
-    _RandomAccessIterator2 __l2 = __last2;
-    --__l2;
-    while (true)
-    {
-        while (true)
-        {
-            if (__s == __l1)
-                return __last1;
-            if (__pred(*--__l1, *__l2))
-                break;
-        }
-        _RandomAccessIterator1 __m1 = __l1;
-        _RandomAccessIterator2 __m2 = __l2;
-        while (true)
-        {
-            if (__m2 == __first2)
-                return __m1;
-                                 // no need to check range on __m1 because __s guarantees we have enough source
-            if (!__pred(*--__m1, *--__m2))
-            {
-                break;
-            }
-        }
-    }
-}
-
-template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator1
-find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-         _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
-{
-    return _VSTD::__find_end<typename add_lvalue_reference<_BinaryPredicate>::type>
-                         (__first1, __last1, __first2, __last2, __pred,
-                          typename iterator_traits<_ForwardIterator1>::iterator_category(),
-                          typename iterator_traits<_ForwardIterator2>::iterator_category());
-}
-
-template <class _ForwardIterator1, class _ForwardIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator1
-find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-         _ForwardIterator2 __first2, _ForwardIterator2 __last2)
-{
-    typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
-    typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
-    return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
-}
-
-// find_first_of
-
-template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1
-__find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-              _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
-{
-    for (; __first1 != __last1; ++__first1)
-        for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
-            if (__pred(*__first1, *__j))
-                return __first1;
-    return __last1;
-}
-
-
-template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator1
-find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-              _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
-{
-    return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred);
-}
-
-template <class _ForwardIterator1, class _ForwardIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator1
-find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-              _ForwardIterator2 __first2, _ForwardIterator2 __last2)
-{
-    typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
-    typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
-    return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
-}
-
-// adjacent_find
-
-template <class _ForwardIterator, class _BinaryPredicate>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
-{
-    if (__first != __last)
-    {
-        _ForwardIterator __i = __first;
-        while (++__i != __last)
-        {
-            if (__pred(*__first, *__i))
-                return __first;
-            __first = __i;
-        }
-    }
-    return __last;
-}
-
-template <class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-adjacent_find(_ForwardIterator __first, _ForwardIterator __last)
-{
-    typedef typename iterator_traits<_ForwardIterator>::value_type __v;
-    return _VSTD::adjacent_find(__first, __last, __equal_to<__v>());
-}
-
-// count
-
-template <class _InputIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-typename iterator_traits<_InputIterator>::difference_type
-count(_InputIterator __first, _InputIterator __last, const _Tp& __value_)
-{
-    typename iterator_traits<_InputIterator>::difference_type __r(0);
-    for (; __first != __last; ++__first)
-        if (*__first == __value_)
-            ++__r;
-    return __r;
-}
-
-// count_if
-
-template <class _InputIterator, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
-typename iterator_traits<_InputIterator>::difference_type
-count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
-{
-    typename iterator_traits<_InputIterator>::difference_type __r(0);
-    for (; __first != __last; ++__first)
-        if (__pred(*__first))
-            ++__r;
-    return __r;
-}
-
-// mismatch
-
-template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
-inline _LIBCPP_INLINE_VISIBILITY
-pair<_InputIterator1, _InputIterator2>
-mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
-         _InputIterator2 __first2, _BinaryPredicate __pred)
-{
-    for (; __first1 != __last1; ++__first1, ++__first2)
-        if (!__pred(*__first1, *__first2))
-            break;
-    return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
-}
-
-template <class _InputIterator1, class _InputIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-pair<_InputIterator1, _InputIterator2>
-mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2)
-{
-    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
-    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
-    return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>());
-}
-
-#if _LIBCPP_STD_VER > 11
-template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
-inline _LIBCPP_INLINE_VISIBILITY
-pair<_InputIterator1, _InputIterator2>
-mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
-         _InputIterator2 __first2, _InputIterator2 __last2,
-         _BinaryPredicate __pred)
-{
-    for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
-        if (!__pred(*__first1, *__first2))
-            break;
-    return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
-}
-
-template <class _InputIterator1, class _InputIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-pair<_InputIterator1, _InputIterator2>
-mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
-         _InputIterator2 __first2, _InputIterator2 __last2)
-{
-    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
-    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
-    return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
-}
+#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
+#   include <__pstl_algorithm>
 #endif
 
-// equal
-
-template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred)
-{
-    for (; __first1 != __last1; ++__first1, ++__first2)
-        if (!__pred(*__first1, *__first2))
-            return false;
-    return true;
-}
-
-template <class _InputIterator1, class _InputIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2)
-{
-    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
-    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
-    return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>());
-}
-
-#if _LIBCPP_STD_VER > 11
-template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-__equal(_InputIterator1 __first1, _InputIterator1 __last1, 
-        _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred,
-        input_iterator_tag, input_iterator_tag )
-{
-    for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
-        if (!__pred(*__first1, *__first2))
-            return false;
-    return __first1 == __last1 && __first2 == __last2;
-}
-
-template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, 
-        _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, 
-      random_access_iterator_tag, random_access_iterator_tag )
-{
-    if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
-        return false;
-    return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2,
-                        typename add_lvalue_reference<_BinaryPredicate>::type>
-                       (__first1, __last1, __first2, __pred );
-}
-
-template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-equal(_InputIterator1 __first1, _InputIterator1 __last1, 
-      _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred )
-{
-    return _VSTD::__equal<typename add_lvalue_reference<_BinaryPredicate>::type>
-       (__first1, __last1, __first2, __last2, __pred, 
-        typename iterator_traits<_InputIterator1>::iterator_category(),
-        typename iterator_traits<_InputIterator2>::iterator_category());
-}
-
-template <class _InputIterator1, class _InputIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-equal(_InputIterator1 __first1, _InputIterator1 __last1, 
-      _InputIterator2 __first2, _InputIterator2 __last2)
-{
-    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
-    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
-    return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(),
-        typename iterator_traits<_InputIterator1>::iterator_category(),
-        typename iterator_traits<_InputIterator2>::iterator_category());
-}
-#endif
-
-// is_permutation
-
-template<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
-bool
-is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-               _ForwardIterator2 __first2, _BinaryPredicate __pred)
-{
-    // shorten sequences as much as possible by lopping of any equal parts
-    for (; __first1 != __last1; ++__first1, ++__first2)
-        if (!__pred(*__first1, *__first2))
-            goto __not_done;
-    return true;
-__not_done:
-    // __first1 != __last1 && *__first1 != *__first2
-    typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
-    _D1 __l1 = _VSTD::distance(__first1, __last1);
-    if (__l1 == _D1(1))
-        return false;
-    _ForwardIterator2 __last2 = _VSTD::next(__first2, __l1);
-    // For each element in [f1, l1) see if there are the same number of
-    //    equal elements in [f2, l2)
-    for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i)
-    {
-        // Have we already counted the number of *__i in [f1, l1)?
-        for (_ForwardIterator1 __j = __first1; __j != __i; ++__j)
-            if (__pred(*__j, *__i))
-                goto __next_iter;
-        {
-            // Count number of *__i in [f2, l2)
-            _D1 __c2 = 0;
-            for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
-                if (__pred(*__i, *__j))
-                    ++__c2;
-            if (__c2 == 0)
-                return false;
-            // Count number of *__i in [__i, l1) (we can start with 1)
-            _D1 __c1 = 1;
-            for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)
-                if (__pred(*__i, *__j))
-                    ++__c1;
-            if (__c1 != __c2)
-                return false;
-        }
-__next_iter:;
-    }
-    return true;
-}
-
-template<class _ForwardIterator1, class _ForwardIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-               _ForwardIterator2 __first2)
-{
-    typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
-    typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
-    return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>());
-}
-
-#if _LIBCPP_STD_VER > 11
-template<class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
-bool
-__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-                 _ForwardIterator2 __first2, _ForwardIterator2 __last2, 
-                 _BinaryPredicate __pred,
-                 forward_iterator_tag, forward_iterator_tag )
-{
-    // shorten sequences as much as possible by lopping of any equal parts
-    for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
-        if (!__pred(*__first1, *__first2))
-            goto __not_done;
-    return __first1 == __last1 && __first2 == __last2;
-__not_done:
-    // __first1 != __last1 && __first2 != __last2 && *__first1 != *__first2
-    typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
-    _D1 __l1 = _VSTD::distance(__first1, __last1);
-
-    typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2;
-    _D2 __l2 = _VSTD::distance(__first2, __last2);
-    if (__l1 != __l2)
-        return false;
-
-    // For each element in [f1, l1) see if there are the same number of
-    //    equal elements in [f2, l2)
-    for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i)
-    {
-        // Have we already counted the number of *__i in [f1, l1)?
-        for (_ForwardIterator1 __j = __first1; __j != __i; ++__j)
-            if (__pred(*__j, *__i))
-                goto __next_iter;
-        {
-            // Count number of *__i in [f2, l2)
-            _D1 __c2 = 0;
-            for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
-                if (__pred(*__i, *__j))
-                    ++__c2;
-            if (__c2 == 0)
-                return false;
-            // Count number of *__i in [__i, l1) (we can start with 1)
-            _D1 __c1 = 1;
-            for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)
-                if (__pred(*__i, *__j))
-                    ++__c1;
-            if (__c1 != __c2)
-                return false;
-        }
-__next_iter:;
-    }
-    return true;
-}
-
-template<class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
-bool
-__is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1,
-               _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2, 
-               _BinaryPredicate __pred,
-               random_access_iterator_tag, random_access_iterator_tag )
-{
-    if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
-        return false;
-    return _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2,
-                                 typename add_lvalue_reference<_BinaryPredicate>::type>
-                                (__first1, __last1, __first2, __pred );
-}
-
-template<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-               _ForwardIterator2 __first2, _ForwardIterator2 __last2,
-               _BinaryPredicate __pred )
-{
-    return _VSTD::__is_permutation<typename add_lvalue_reference<_BinaryPredicate>::type>
-       (__first1, __last1, __first2, __last2, __pred,
-        typename iterator_traits<_ForwardIterator1>::iterator_category(),
-        typename iterator_traits<_ForwardIterator2>::iterator_category());
-}
-
-template<class _ForwardIterator1, class _ForwardIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-               _ForwardIterator2 __first2, _ForwardIterator2 __last2)
-{
-    typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
-    typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
-    return _VSTD::__is_permutation(__first1, __last1, __first2, __last2,
-        __equal_to<__v1, __v2>(),
-        typename iterator_traits<_ForwardIterator1>::iterator_category(),
-        typename iterator_traits<_ForwardIterator2>::iterator_category());
-}
-#endif
-
-// search
-
-template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
-_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
-    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;
-            if (__pred(*__first1, *__first2))
-                break;
-            ++__first1;
-        }
-        // *__first1 matches *__first2, now match elements after here
-        _ForwardIterator1 __m1 = __first1;
-        _ForwardIterator2 __m2 = __first2;
-        while (true)
-        {
-            if (++__m2 == __last2)  // If pattern exhausted, __first1 is the answer (works for 1 element pattern)
-                return __first1;
-            if (++__m1 == __last1)  // Otherwise if source exhaused, pattern not found
-                return __last1;
-            if (!__pred(*__m1, *__m2))  // if there is a mismatch, restart with a new __first1
-            {
-                ++__first1;
-                break;
-            }  // else there is a match, check next elements
-        }
-    }
-}
-
-template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1
-__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
-           _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;
-    // Take advantage of knowing source and pattern lengths.  Stop short when source is smaller than pattern
-    _D2 __len2 = __last2 - __first2;
-    if (__len2 == 0)
-        return __first1;
-    _D1 __len1 = __last1 - __first1;
-    if (__len1 < __len2)
-        return __last1;
-    const _RandomAccessIterator1 __s = __last1 - (__len2 - 1);  // Start of pattern match can't go beyond here
-    while (true)
-    {
-#if !_LIBCPP_UNROLL_LOOPS
-        while (true)
-        {
-            if (__first1 == __s)
-                return __last1;
-            if (__pred(*__first1, *__first2))
-                break;
-            ++__first1;
-        }
-#else  // !_LIBCPP_UNROLL_LOOPS
-        for (_D1 __loop_unroll = (__s - __first1) / 4; __loop_unroll > 0; --__loop_unroll)
-        {
-            if (__pred(*__first1, *__first2))
-                goto __phase2;
-            if (__pred(*++__first1, *__first2))
-                goto __phase2;
-            if (__pred(*++__first1, *__first2))
-                goto __phase2;
-            if (__pred(*++__first1, *__first2))
-                goto __phase2;
-            ++__first1;
-        }
-        switch (__s - __first1)
-        {
-        case 3:
-            if (__pred(*__first1, *__first2))
-                break;
-            ++__first1;
-        case 2:
-            if (__pred(*__first1, *__first2))
-                break;
-            ++__first1;
-        case 1:
-            if (__pred(*__first1, *__first2))
-                break;
-        case 0:
-            return __last1;
-        }
-    __phase2:
-#endif  // !_LIBCPP_UNROLL_LOOPS
-        _RandomAccessIterator1 __m1 = __first1;
-        _RandomAccessIterator2 __m2 = __first2;
-#if !_LIBCPP_UNROLL_LOOPS
-         while (true)
-         {
-             if (++__m2 == __last2)
-                 return __first1;
-             ++__m1;          // no need to check range on __m1 because __s guarantees we have enough source
-             if (!__pred(*__m1, *__m2))
-             {
-                 ++__first1;
-                 break;
-             }
-         }
-#else  // !_LIBCPP_UNROLL_LOOPS
-        ++__m2;
-        ++__m1;
-        for (_D2 __loop_unroll = (__last2 - __m2) / 4; __loop_unroll > 0; --__loop_unroll)
-        {
-            if (!__pred(*__m1, *__m2))
-                goto __continue;
-            if (!__pred(*++__m1, *++__m2))
-                goto __continue;
-            if (!__pred(*++__m1, *++__m2))
-                goto __continue;
-            if (!__pred(*++__m1, *++__m2))
-                goto __continue;
-            ++__m1;
-            ++__m2;
-        }
-        switch (__last2 - __m2)
-        {
-        case 3:
-            if (!__pred(*__m1, *__m2))
-                break;
-            ++__m1;
-            ++__m2;
-        case 2:
-            if (!__pred(*__m1, *__m2))
-                break;
-            ++__m1;
-            ++__m2;
-        case 1:
-            if (!__pred(*__m1, *__m2))
-                break;
-        case 0:
-            return __first1;
-        }
-    __continue:
-        ++__first1;
-#endif  // !_LIBCPP_UNROLL_LOOPS
-    }
-}
-
-template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator1
-search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-       _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
-{
-    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());
-}
-
-template <class _ForwardIterator1, class _ForwardIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator1
-search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-       _ForwardIterator2 __first2, _ForwardIterator2 __last2)
-{
-    typedef typename std::iterator_traits<_ForwardIterator1>::value_type __v1;
-    typedef typename std::iterator_traits<_ForwardIterator2>::value_type __v2;
-    return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
-}
-
-// search_n
-
-template <class _BinaryPredicate, class _ForwardIterator, class _Size, class _Tp>
-_ForwardIterator
-__search_n(_ForwardIterator __first, _ForwardIterator __last,
-           _Size __count, const _Tp& __value_, _BinaryPredicate __pred, forward_iterator_tag)
-{
-    if (__count <= 0)
-        return __first;
-    while (true)
-    {
-        // Find first element in sequence that matchs __value_, with a mininum of loop checks
-        while (true)
-        {
-            if (__first == __last)  // return __last if no element matches __value_
-                return __last;
-            if (__pred(*__first, __value_))
-                break;
-            ++__first;
-        }
-        // *__first matches __value_, now match elements after here
-        _ForwardIterator __m = __first;
-        _Size __c(0);
-        while (true)
-        {
-            if (++__c == __count)  // If pattern exhausted, __first is the answer (works for 1 element pattern)
-                return __first;
-            if (++__m == __last)  // Otherwise if source exhaused, pattern not found
-                return __last;
-            if (!__pred(*__m, __value_))  // if there is a mismatch, restart with a new __first
-            {
-                __first = __m;
-                ++__first;
-                break;
-            }  // else there is a match, check next elements
-        }
-    }
-}
-
-template <class _BinaryPredicate, class _RandomAccessIterator, class _Size, class _Tp>
-_RandomAccessIterator
-__search_n(_RandomAccessIterator __first, _RandomAccessIterator __last,
-           _Size __count, const _Tp& __value_, _BinaryPredicate __pred, random_access_iterator_tag)
-{
-    if (__count <= 0)
-        return __first;
-    _Size __len = static_cast<_Size>(__last - __first);
-    if (__len < __count)
-        return __last;
-    const _RandomAccessIterator __s = __last - (__count - 1);  // Start of pattern match can't go beyond here
-    while (true)
-    {
-        // Find first element in sequence that matchs __value_, with a mininum of loop checks
-        while (true)
-        {
-            if (__first >= __s)  // return __last if no element matches __value_
-                return __last;
-            if (__pred(*__first, __value_))
-                break;
-            ++__first;
-        }
-        // *__first matches __value_, now match elements after here
-        _RandomAccessIterator __m = __first;
-        _Size __c(0);
-        while (true)
-        {
-            if (++__c == __count)  // If pattern exhausted, __first is the answer (works for 1 element pattern)
-                return __first;
-             ++__m;          // no need to check range on __m because __s guarantees we have enough source
-            if (!__pred(*__m, __value_))  // if there is a mismatch, restart with a new __first
-            {
-                __first = __m;
-                ++__first;
-                break;
-            }  // else there is a match, check next elements
-        }
-    }
-}
-
-template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-search_n(_ForwardIterator __first, _ForwardIterator __last,
-         _Size __count, const _Tp& __value_, _BinaryPredicate __pred)
-{
-    return _VSTD::__search_n<typename add_lvalue_reference<_BinaryPredicate>::type>
-           (__first, __last, __count, __value_, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());
-}
-
-template <class _ForwardIterator, class _Size, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_)
-{
-    typedef typename iterator_traits<_ForwardIterator>::value_type __v;
-    return _VSTD::search_n(__first, __last, __count, __value_, __equal_to<__v, _Tp>());
-}
-
-// 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
-__unwrap_iter(_Iter __i)
-{
-    return __i;
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_trivially_copy_assignable<_Tp>::value,
-    _Tp*
->::type
-__unwrap_iter(move_iterator<_Tp*> __i)
-{
-    return __i.base();
-}
-
-#if _LIBCPP_DEBUG_LEVEL < 2
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_trivially_copy_assignable<_Tp>::value,
-    _Tp*
->::type
-__unwrap_iter(__wrap_iter<_Tp*> __i)
-{
-    return __i.base();
-}
-
-#endif  // _LIBCPP_DEBUG_LEVEL < 2
-
-template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
-    for (; __first != __last; ++__first, ++__result)
-        *__result = *__first;
-    return __result;
-}
-
-template <class _Tp, class _Up>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_same<typename remove_const<_Tp>::type, _Up>::value &&
-    is_trivially_copy_assignable<_Up>::value,
-    _Up*
->::type
-__copy(_Tp* __first, _Tp* __last, _Up* __result)
-{
-    const size_t __n = static_cast<size_t>(__last - __first);
-    _VSTD::memmove(__result, __first, __n * sizeof(_Up));
-    return __result + __n;
-}
-
-template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
-    return _VSTD::__copy(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));
-}
-
-// copy_backward
-
-template <class _BidirectionalIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
-{
-    while (__first != __last)
-        *--__result = *--__last;
-    return __result;
-}
-
-template <class _Tp, class _Up>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_same<typename remove_const<_Tp>::type, _Up>::value &&
-    is_trivially_copy_assignable<_Up>::value,
-    _Up*
->::type
-__copy_backward(_Tp* __first, _Tp* __last, _Up* __result)
-{
-    const size_t __n = static_cast<size_t>(__last - __first);
-    __result -= __n;
-    _VSTD::memmove(__result, __first, __n * sizeof(_Up));
-    return __result;
-}
-
-template <class _BidirectionalIterator1, class _BidirectionalIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-_BidirectionalIterator2
-copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
-              _BidirectionalIterator2 __result)
-{
-    return _VSTD::__copy_backward(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));
-}
-
-// copy_if
-
-template<class _InputIterator, class _OutputIterator, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-copy_if(_InputIterator __first, _InputIterator __last,
-        _OutputIterator __result, _Predicate __pred)
-{
-    for (; __first != __last; ++__first)
-    {
-        if (__pred(*__first))
-        {
-            *__result = *__first;
-            ++__result;
-        }
-    }
-    return __result;
-}
-
-// copy_n
-
-template<class _InputIterator, class _Size, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_input_iterator<_InputIterator>::value &&
-   !__is_random_access_iterator<_InputIterator>::value,
-    _OutputIterator
->::type
-copy_n(_InputIterator __first, _Size __n, _OutputIterator __result)
-{
-    if (__n > 0)
-    {
-        *__result = *__first;
-        ++__result;
-        for (--__n; __n > 0; --__n)
-        {
-            ++__first;
-            *__result = *__first;
-            ++__result;
-        }
-    }
-    return __result;
-}
-
-template<class _InputIterator, class _Size, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    __is_random_access_iterator<_InputIterator>::value,
-    _OutputIterator
->::type
-copy_n(_InputIterator __first, _Size __n, _OutputIterator __result)
-{
-    return _VSTD::copy(__first, __first + __n, __result);
-}
-
-// move
-
-template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
-    for (; __first != __last; ++__first, ++__result)
-        *__result = _VSTD::move(*__first);
-    return __result;
-}
-
-template <class _Tp, class _Up>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_same<typename remove_const<_Tp>::type, _Up>::value &&
-    is_trivially_copy_assignable<_Up>::value,
-    _Up*
->::type
-__move(_Tp* __first, _Tp* __last, _Up* __result)
-{
-    const size_t __n = static_cast<size_t>(__last - __first);
-    _VSTD::memmove(__result, __first, __n * sizeof(_Up));
-    return __result + __n;
-}
-
-template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
-    return _VSTD::__move(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));
-}
-
-// move_backward
-
-template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
-    while (__first != __last)
-        *--__result = _VSTD::move(*--__last);
-    return __result;
-}
-
-template <class _Tp, class _Up>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_same<typename remove_const<_Tp>::type, _Up>::value &&
-    is_trivially_copy_assignable<_Up>::value,
-    _Up*
->::type
-__move_backward(_Tp* __first, _Tp* __last, _Up* __result)
-{
-    const size_t __n = static_cast<size_t>(__last - __first);
-    __result -= __n;
-    _VSTD::memmove(__result, __first, __n * sizeof(_Up));
-    return __result;
-}
-
-template <class _BidirectionalIterator1, class _BidirectionalIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-_BidirectionalIterator2
-move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
-              _BidirectionalIterator2 __result)
-{
-    return _VSTD::__move_backward(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));
-}
-
-// iter_swap
-
-// moved to <type_traits> for better swap / noexcept support
-
-// transform
-
-template <class _InputIterator, class _OutputIterator, class _UnaryOperation>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op)
-{
-    for (; __first != __last; ++__first, ++__result)
-        *__result = __op(*__first);
-    return __result;
-}
-
-template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _BinaryOperation>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
-          _OutputIterator __result, _BinaryOperation __binary_op)
-{
-    for (; __first1 != __last1; ++__first1, ++__first2, ++__result)
-        *__result = __binary_op(*__first1, *__first2);
-    return __result;
-}
-
-// replace
-
-template <class _ForwardIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value)
-{
-    for (; __first != __last; ++__first)
-        if (*__first == __old_value)
-            *__first = __new_value;
-}
-
-// replace_if
-
-template <class _ForwardIterator, class _Predicate, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value)
-{
-    for (; __first != __last; ++__first)
-        if (__pred(*__first))
-            *__first = __new_value;
-}
-
-// replace_copy
-
-template <class _InputIterator, class _OutputIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
-             const _Tp& __old_value, const _Tp& __new_value)
-{
-    for (; __first != __last; ++__first, ++__result)
-        if (*__first == __old_value)
-            *__result = __new_value;
-        else
-            *__result = *__first;
-    return __result;
-}
-
-// replace_copy_if
-
-template <class _InputIterator, class _OutputIterator, class _Predicate, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
-                _Predicate __pred, const _Tp& __new_value)
-{
-    for (; __first != __last; ++__first, ++__result)
-        if (__pred(*__first))
-            *__result = __new_value;
-        else
-            *__result = *__first;
-    return __result;
-}
-
-// fill_n
-
-template <class _OutputIterator, class _Size, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
-{
-    for (; __n > 0; ++__first, --__n)
-        *__first = __value_;
-    return __first;
-}
-
-template <class _Tp, class _Size, class _Up>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value && sizeof(_Tp) == 1 &&
-    !is_same<_Tp, bool>::value &&
-    is_integral<_Up>::value && sizeof(_Up) == 1,
-    _Tp*
->::type
-__fill_n(_Tp* __first, _Size __n,_Up __value_)
-{
-    if (__n > 0)
-        _VSTD::memset(__first, (unsigned char)__value_, (size_t)(__n));
-    return __first + __n;
-}
-
-template <class _OutputIterator, class _Size, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
-{
-   return _VSTD::__fill_n(__first, __n, __value_);
-}
-
-// fill
-
-template <class _ForwardIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag)
-{
-    for (; __first != __last; ++__first)
-        *__first = __value_;
-}
-
-template <class _RandomAccessIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag)
-{
-    _VSTD::fill_n(__first, __last - __first, __value_);
-}
-
-template <class _ForwardIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
-{
-    _VSTD::__fill(__first, __last, __value_, typename iterator_traits<_ForwardIterator>::iterator_category());
-}
-
-// generate
-
-template <class _ForwardIterator, class _Generator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen)
-{
-    for (; __first != __last; ++__first)
-        *__first = __gen();
-}
-
-// generate_n
-
-template <class _OutputIterator, class _Size, class _Generator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-generate_n(_OutputIterator __first, _Size __n, _Generator __gen)
-{
-    for (; __n > 0; ++__first, --__n)
-        *__first = __gen();
-    return __first;
-}
-
-// remove
-
-template <class _ForwardIterator, class _Tp>
-_ForwardIterator
-remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
-{
-    __first = _VSTD::find(__first, __last, __value_);
-    if (__first != __last)
-    {
-        _ForwardIterator __i = __first;
-        while (++__i != __last)
-        {
-            if (!(*__i == __value_))
-            {
-                *__first = _VSTD::move(*__i);
-                ++__first;
-            }
-        }
-    }
-    return __first;
-}
-
-// remove_if
-
-template <class _ForwardIterator, class _Predicate>
-_ForwardIterator
-remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
-{
-    __first = _VSTD::find_if<_ForwardIterator, typename add_lvalue_reference<_Predicate>::type>
-                           (__first, __last, __pred);
-    if (__first != __last)
-    {
-        _ForwardIterator __i = __first;
-        while (++__i != __last)
-        {
-            if (!__pred(*__i))
-            {
-                *__first = _VSTD::move(*__i);
-                ++__first;
-            }
-        }
-    }
-    return __first;
-}
-
-// remove_copy
-
-template <class _InputIterator, class _OutputIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_)
-{
-    for (; __first != __last; ++__first)
-    {
-        if (!(*__first == __value_))
-        {
-            *__result = *__first;
-            ++__result;
-        }
-    }
-    return __result;
-}
-
-// remove_copy_if
-
-template <class _InputIterator, class _OutputIterator, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred)
-{
-    for (; __first != __last; ++__first)
-    {
-        if (!__pred(*__first))
-        {
-            *__result = *__first;
-            ++__result;
-        }
-    }
-    return __result;
-}
-
-// unique
-
-template <class _ForwardIterator, class _BinaryPredicate>
-_ForwardIterator
-unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
-{
-    __first = _VSTD::adjacent_find<_ForwardIterator, typename add_lvalue_reference<_BinaryPredicate>::type>
-                                 (__first, __last, __pred);
-    if (__first != __last)
-    {
-        // ...  a  a  ?  ...
-        //      f     i
-        _ForwardIterator __i = __first;
-        for (++__i; ++__i != __last;)
-            if (!__pred(*__first, *__i))
-                *++__first = _VSTD::move(*__i);
-        ++__first;
-    }
-    return __first;
-}
-
-template <class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-unique(_ForwardIterator __first, _ForwardIterator __last)
-{
-    typedef typename iterator_traits<_ForwardIterator>::value_type __v;
-    return _VSTD::unique(__first, __last, __equal_to<__v>());
-}
-
-// unique_copy
-
-template <class _BinaryPredicate, class _InputIterator, class _OutputIterator>
-_OutputIterator
-__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred,
-              input_iterator_tag, output_iterator_tag)
-{
-    if (__first != __last)
-    {
-        typename iterator_traits<_InputIterator>::value_type __t(*__first);
-        *__result = __t;
-        ++__result;
-        while (++__first != __last)
-        {
-            if (!__pred(__t, *__first))
-            {
-                __t = *__first;
-                *__result = __t;
-                ++__result;
-            }
-        }
-    }
-    return __result;
-}
-
-template <class _BinaryPredicate, class _ForwardIterator, class _OutputIterator>
-_OutputIterator
-__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred,
-              forward_iterator_tag, output_iterator_tag)
-{
-    if (__first != __last)
-    {
-        _ForwardIterator __i = __first;
-        *__result = *__i;
-        ++__result;
-        while (++__first != __last)
-        {
-            if (!__pred(*__i, *__first))
-            {
-                *__result = *__first;
-                ++__result;
-                __i = __first;
-            }
-        }
-    }
-    return __result;
-}
-
-template <class _BinaryPredicate, class _InputIterator, class _ForwardIterator>
-_ForwardIterator
-__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred,
-              input_iterator_tag, forward_iterator_tag)
-{
-    if (__first != __last)
-    {
-        *__result = *__first;
-        while (++__first != __last)
-            if (!__pred(*__result, *__first))
-                *++__result = *__first;
-        ++__result;
-    }
-    return __result;
-}
-
-template <class _InputIterator, class _OutputIterator, class _BinaryPredicate>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred)
-{
-    return _VSTD::__unique_copy<typename add_lvalue_reference<_BinaryPredicate>::type>
-                              (__first, __last, __result, __pred,
-                               typename iterator_traits<_InputIterator>::iterator_category(),
-                               typename iterator_traits<_OutputIterator>::iterator_category());
-}
-
-template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
-    typedef typename iterator_traits<_InputIterator>::value_type __v;
-    return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>());
-}
-
-// reverse
-
-template <class _BidirectionalIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag)
-{
-    while (__first != __last)
-    {
-        if (__first == --__last)
-            break;
-        swap(*__first, *__last);
-        ++__first;
-    }
-}
-
-template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag)
-{
-    if (__first != __last)
-        for (; __first < --__last; ++__first)
-            swap(*__first, *__last);
-}
-
-template <class _BidirectionalIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
-{
-    _VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category());
-}
-
-// reverse_copy
-
-template <class _BidirectionalIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
-{
-    for (; __first != __last; ++__result)
-        *__result = *--__last;
-    return __result;
-}
-
-// rotate
-
-template <class _ForwardIterator>
-_ForwardIterator
-__rotate_left(_ForwardIterator __first, _ForwardIterator __last)
-{
-    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
-    value_type __tmp = _VSTD::move(*__first);
-    _ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first);
-    *__lm1 = _VSTD::move(__tmp);
-    return __lm1;
-}
-
-template <class _BidirectionalIterator>
-_BidirectionalIterator
-__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last)
-{
-    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
-    _BidirectionalIterator __lm1 = _VSTD::prev(__last);
-    value_type __tmp = _VSTD::move(*__lm1);
-    _BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last);
-    *__first = _VSTD::move(__tmp);
-    return __fp1;
-}
-
-template <class _ForwardIterator>
-_ForwardIterator
-__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
-{
-    _ForwardIterator __i = __middle;
-    while (true)
-    {
-        swap(*__first, *__i);
-        ++__first;
-        if (++__i == __last)
-            break;
-        if (__first == __middle)
-            __middle = __i;
-    }
-    _ForwardIterator __r = __first;
-    if (__first != __middle)
-    {
-        __i = __middle;
-        while (true)
-        {
-            swap(*__first, *__i);
-            ++__first;
-            if (++__i == __last)
-            {
-                if (__first == __middle)
-                    break;
-                __i = __middle;
-            }
-            else if (__first == __middle)
-                __middle = __i;
-        }
-    }
-    return __r;
-}
-
-template<typename _Integral>
-inline _LIBCPP_INLINE_VISIBILITY
-_Integral
-__gcd(_Integral __x, _Integral __y)
-{
-    do
-    {
-        _Integral __t = __x % __y;
-        __x = __y;
-        __y = __t;
-    } while (__y);
-    return __x;
-}
-
-template<typename _RandomAccessIterator>
-_RandomAccessIterator
-__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
-{
-    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
-
-    const difference_type __m1 = __middle - __first;
-    const difference_type __m2 = __last - __middle;
-    if (__m1 == __m2)
-    {
-        _VSTD::swap_ranges(__first, __middle, __middle);
-        return __middle;
-    }
-    const difference_type __g = _VSTD::__gcd(__m1, __m2);
-    for (_RandomAccessIterator __p = __first + __g; __p != __first;)
-    {
-        value_type __t(_VSTD::move(*--__p));
-        _RandomAccessIterator __p1 = __p;
-        _RandomAccessIterator __p2 = __p1 + __m1;
-        do
-        {
-            *__p1 = _VSTD::move(*__p2);
-            __p1 = __p2;
-            const difference_type __d = __last - __p2;
-            if (__m1 < __d)
-                __p2 += __m1;
-            else
-                __p2 = __first + (__m1 - __d);
-        } while (__p2 != __p);
-        *__p1 = _VSTD::move(__t);
-    }
-    return __first + __m2;
-}
-
-template <class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-__rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
-         _VSTD::forward_iterator_tag)
-{
-    typedef typename _VSTD::iterator_traits<_ForwardIterator>::value_type value_type;
-    if (_VSTD::is_trivially_move_assignable<value_type>::value)
-    {
-        if (_VSTD::next(__first) == __middle)
-            return _VSTD::__rotate_left(__first, __last);
-    }
-    return _VSTD::__rotate_forward(__first, __middle, __last);
-}
-
-template <class _BidirectionalIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_BidirectionalIterator
-__rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
-         _VSTD::bidirectional_iterator_tag)
-{
-    typedef typename _VSTD::iterator_traits<_BidirectionalIterator>::value_type value_type;
-    if (_VSTD::is_trivially_move_assignable<value_type>::value)
-    {
-        if (_VSTD::next(__first) == __middle)
-            return _VSTD::__rotate_left(__first, __last);
-        if (_VSTD::next(__middle) == __last)
-            return _VSTD::__rotate_right(__first, __last);
-    }
-    return _VSTD::__rotate_forward(__first, __middle, __last);
-}
-
-template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_RandomAccessIterator
-__rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
-         _VSTD::random_access_iterator_tag)
-{
-    typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::value_type value_type;
-    if (_VSTD::is_trivially_move_assignable<value_type>::value)
-    {
-        if (_VSTD::next(__first) == __middle)
-            return _VSTD::__rotate_left(__first, __last);
-        if (_VSTD::next(__middle) == __last)
-            return _VSTD::__rotate_right(__first, __last);
-        return _VSTD::__rotate_gcd(__first, __middle, __last);
-    }
-    return _VSTD::__rotate_forward(__first, __middle, __last);
-}
-
-template <class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
-{
-    if (__first == __middle)
-        return __last;
-    if (__middle == __last)
-        return __first;
-    return _VSTD::__rotate(__first, __middle, __last,
-                           typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category());
-}
-
-// rotate_copy
-
-template <class _ForwardIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result)
-{
-    return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result));
-}
-
-// min_element
-
-template <class _ForwardIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-_ForwardIterator
-__min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
-{
-    if (__first != __last)
-    {
-        _ForwardIterator __i = __first;
-        while (++__i != __last)
-            if (__comp(*__i, *__first))
-                __first = __i;
-    }
-    return __first;
-}
-
-template <class _ForwardIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
-{
-    return __min_element(__first, __last, __comp);
-}
-
-template <class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-min_element(_ForwardIterator __first, _ForwardIterator __last)
-{
-    return __min_element(__first, __last,
-              __less<typename iterator_traits<_ForwardIterator>::value_type>());
-}
-
-// min
-
-template <class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-const _Tp&
-min(const _Tp& __a, const _Tp& __b, _Compare __comp)
-{
-    return __comp(__b, __a) ? __b : __a;
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-const _Tp&
-min(const _Tp& __a, const _Tp& __b)
-{
-    return _VSTD::min(__a, __b, __less<_Tp>());
-}
-
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-
-template<class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-_Tp
-min(initializer_list<_Tp> __t, _Compare __comp)
-{
-    return *__min_element(__t.begin(), __t.end(), __comp);
-}
-
-template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-_Tp
-min(initializer_list<_Tp> __t)
-{
-    return *__min_element(__t.begin(), __t.end(), __less<_Tp>());
-}
-
-#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-
-// max_element
-
-template <class _ForwardIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-_ForwardIterator
-__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
-{
-    if (__first != __last)
-    {
-        _ForwardIterator __i = __first;
-        while (++__i != __last)
-            if (__comp(*__first, *__i))
-                __first = __i;
-    }
-    return __first;
-}
-
-
-template <class _ForwardIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
-{
-    return __max_element(__first, __last, __comp);
-}
-
-template <class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-max_element(_ForwardIterator __first, _ForwardIterator __last)
-{
-    return __max_element(__first, __last,
-              __less<typename iterator_traits<_ForwardIterator>::value_type>());
-}
-
-// max
-
-template <class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-const _Tp&
-max(const _Tp& __a, const _Tp& __b, _Compare __comp)
-{
-    return __comp(__a, __b) ? __b : __a;
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-const _Tp&
-max(const _Tp& __a, const _Tp& __b)
-{
-    return _VSTD::max(__a, __b, __less<_Tp>());
-}
-
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-
-template<class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-_Tp
-max(initializer_list<_Tp> __t, _Compare __comp)
-{
-    return *__max_element(__t.begin(), __t.end(), __comp);
-}
-
-template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-_Tp
-max(initializer_list<_Tp> __t)
-{
-    return *__max_element(__t.begin(), __t.end(), __less<_Tp>());
-}
-
-#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-
-// minmax_element
-
-template <class _ForwardIterator, class _Compare>
-std::pair<_ForwardIterator, _ForwardIterator>
-minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
-{
-  std::pair<_ForwardIterator, _ForwardIterator> __result(__first, __first);
-  if (__first != __last)
-  {
-      if (++__first != __last)
-      {
-          if (__comp(*__first, *__result.first))
-              __result.first = __first;
-          else
-              __result.second = __first;
-          while (++__first != __last)
-          {
-              _ForwardIterator __i = __first;
-              if (++__first == __last)
-              {
-                  if (__comp(*__i, *__result.first))
-                      __result.first = __i;
-                  else if (!__comp(*__i, *__result.second))
-                      __result.second = __i;
-                  break;
-              }
-              else
-              {
-                  if (__comp(*__first, *__i))
-                  {
-                      if (__comp(*__first, *__result.first))
-                          __result.first = __first;
-                      if (!__comp(*__i, *__result.second))
-                          __result.second = __i;
-                  }
-                  else
-                  {
-                      if (__comp(*__i, *__result.first))
-                          __result.first = __i;
-                      if (!__comp(*__first, *__result.second))
-                          __result.second = __first;
-                  }
-              }
-          }
-      }
-  }
-  return __result;
-}
-
-template <class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-std::pair<_ForwardIterator, _ForwardIterator>
-minmax_element(_ForwardIterator __first, _ForwardIterator __last)
-{
-    return _VSTD::minmax_element(__first, __last,
-              __less<typename iterator_traits<_ForwardIterator>::value_type>());
-}
-
-// minmax
-
-template<class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-pair<const _Tp&, const _Tp&>
-minmax(const _Tp& __a, const _Tp& __b, _Compare __comp)
-{
-    return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) :
-                              pair<const _Tp&, const _Tp&>(__a, __b);
-}
-
-template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-pair<const _Tp&, const _Tp&>
-minmax(const _Tp& __a, const _Tp& __b)
-{
-    return _VSTD::minmax(__a, __b, __less<_Tp>());
-}
-
-#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-
-template<class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-pair<_Tp, _Tp>
-minmax(initializer_list<_Tp> __t, _Compare __comp)
-{
-    typedef typename initializer_list<_Tp>::const_iterator _Iter;
-    _Iter __first = __t.begin();
-    _Iter __last  = __t.end();
-    std::pair<_Tp, _Tp> __result ( *__first, *__first );
-
-    ++__first;
-    if (__t.size() % 2 == 0)
-    {
-        if (__comp(*__first,  __result.first))
-            __result.first  = *__first;
-        else
-            __result.second = *__first;
-        ++__first;
-    }
-    
-    while (__first != __last)
-    {
-        _Tp __prev = *__first++;
-        if (__comp(__prev, *__first)) {
-            if (__comp(__prev, __result.first))    __result.first  = __prev;
-            if (__comp(__result.second, *__first)) __result.second = *__first;
-            }
-        else {
-            if (__comp(*__first, __result.first)) __result.first  = *__first;
-            if (__comp(__result.second, __prev))  __result.second = __prev;
-            }
-                
-        __first++;
-    }
-    return __result;
-}
-
-template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-pair<_Tp, _Tp>
-minmax(initializer_list<_Tp> __t)
-{
-    return _VSTD::minmax(__t, __less<_Tp>());
-}
-
-#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-
-// random_shuffle
-
-// __independent_bits_engine
-
-template <unsigned long long _Xp, size_t _Rp>
-struct __log2_imp
-{
-    static const size_t value = _Xp & ((unsigned long long)(1) << _Rp) ? _Rp
-                                           : __log2_imp<_Xp, _Rp - 1>::value;
-};
-
-template <unsigned long long _Xp>
-struct __log2_imp<_Xp, 0>
-{
-    static const size_t value = 0;
-};
-
-template <size_t _Rp>
-struct __log2_imp<0, _Rp>
-{
-    static const size_t value = _Rp + 1;
-};
-
-template <class _UI, _UI _Xp>
-struct __log2
-{
-    static const size_t value = __log2_imp<_Xp,
-                                         sizeof(_UI) * __CHAR_BIT__ - 1>::value;
-};
-
-template<class _Engine, class _UIntType>
-class __independent_bits_engine
-{
-public:
-    // types
-    typedef _UIntType result_type;
-
-private:
-    typedef typename _Engine::result_type _Engine_result_type;
-    typedef typename conditional
-        <
-            sizeof(_Engine_result_type) <= sizeof(result_type),
-                result_type,
-                _Engine_result_type
-        >::type _Working_result_type;
-
-    _Engine& __e_;
-    size_t __w_;
-    size_t __w0_;
-    size_t __n_;
-    size_t __n0_;
-    _Working_result_type __y0_;
-    _Working_result_type __y1_;
-    _Engine_result_type __mask0_;
-    _Engine_result_type __mask1_;
-
-#ifdef _LIBCPP_HAS_NO_CONSTEXPR
-    static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min
-                                          + _Working_result_type(1);
-#else
-    static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()
-                                                      + _Working_result_type(1);
-#endif
-    static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value;
-    static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits;
-    static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits;
-
-public:
-    // constructors and seeding functions
-    __independent_bits_engine(_Engine& __e, size_t __w);
-
-    // generating functions
-    result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
-
-private:
-    result_type __eval(false_type);
-    result_type __eval(true_type);
-};
-
-template<class _Engine, class _UIntType>
-__independent_bits_engine<_Engine, _UIntType>
-    ::__independent_bits_engine(_Engine& __e, size_t __w)
-        : __e_(__e),
-          __w_(__w)
-{
-    __n_ = __w_ / __m + (__w_ % __m != 0);
-    __w0_ = __w_ / __n_;
-    if (_Rp == 0)
-        __y0_ = _Rp;
-    else if (__w0_ < _WDt)
-        __y0_ = (_Rp >> __w0_) << __w0_;
-    else
-        __y0_ = 0;
-    if (_Rp - __y0_ > __y0_ / __n_)
-    {
-        ++__n_;
-        __w0_ = __w_ / __n_;
-        if (__w0_ < _WDt)
-            __y0_ = (_Rp >> __w0_) << __w0_;
-        else
-            __y0_ = 0;
-    }
-    __n0_ = __n_ - __w_ % __n_;
-    if (__w0_ < _WDt - 1)
-        __y1_ = (_Rp >> (__w0_ + 1)) << (__w0_ + 1);
-    else
-        __y1_ = 0;
-    __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) :
-                          _Engine_result_type(0);
-    __mask1_ = __w0_ < _EDt - 1 ?
-                               _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) :
-                               _Engine_result_type(~0);
-}
-
-template<class _Engine, class _UIntType>
-inline
-_UIntType
-__independent_bits_engine<_Engine, _UIntType>::__eval(false_type)
-{
-    return static_cast<result_type>(__e_() & __mask0_);
-}
-
-template<class _Engine, class _UIntType>
-_UIntType
-__independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
-{
-    result_type _Sp = 0;
-    for (size_t __k = 0; __k < __n0_; ++__k)
-    {
-        _Engine_result_type __u;
-        do
-        {
-            __u = __e_() - _Engine::min();
-        } while (__u >= __y0_);
-        if (__w0_ < _WDt)
-            _Sp <<= __w0_;
-        else
-            _Sp = 0;
-        _Sp += __u & __mask0_;
-    }
-    for (size_t __k = __n0_; __k < __n_; ++__k)
-    {
-        _Engine_result_type __u;
-        do
-        {
-            __u = __e_() - _Engine::min();
-        } while (__u >= __y1_);
-        if (__w0_ < _WDt - 1)
-            _Sp <<= __w0_ + 1;
-        else
-            _Sp = 0;
-        _Sp += __u & __mask1_;
-    }
-    return _Sp;
-}
-
-// uniform_int_distribution
-
-template<class _IntType = int>
-class uniform_int_distribution
-{
-public:
-    // types
-    typedef _IntType result_type;
-
-    class param_type
-    {
-        result_type __a_;
-        result_type __b_;
-    public:
-        typedef uniform_int_distribution distribution_type;
-
-        explicit param_type(result_type __a = 0,
-                            result_type __b = numeric_limits<result_type>::max())
-            : __a_(__a), __b_(__b) {}
-
-        result_type a() const {return __a_;}
-        result_type b() const {return __b_;}
-
-        friend bool operator==(const param_type& __x, const param_type& __y)
-            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
-        friend bool operator!=(const param_type& __x, const param_type& __y)
-            {return !(__x == __y);}
-    };
-
-private:
-    param_type __p_;
-
-public:
-    // constructors and reset functions
-    explicit uniform_int_distribution(result_type __a = 0,
-                                      result_type __b = numeric_limits<result_type>::max())
-        : __p_(param_type(__a, __b)) {}
-    explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}
-    void reset() {}
-
-    // generating functions
-    template<class _URNG> result_type operator()(_URNG& __g)
-        {return (*this)(__g, __p_);}
-    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
-
-    // property functions
-    result_type a() const {return __p_.a();}
-    result_type b() const {return __p_.b();}
-
-    param_type param() const {return __p_;}
-    void param(const param_type& __p) {__p_ = __p;}
-
-    result_type min() const {return a();}
-    result_type max() const {return b();}
-
-    friend bool operator==(const uniform_int_distribution& __x,
-                           const uniform_int_distribution& __y)
-        {return __x.__p_ == __y.__p_;}
-    friend bool operator!=(const uniform_int_distribution& __x,
-                           const uniform_int_distribution& __y)
-            {return !(__x == __y);}
-};
-
-template<class _IntType>
-template<class _URNG>
-typename uniform_int_distribution<_IntType>::result_type
-uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
-{
-    typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t),
-                                            uint32_t, uint64_t>::type _UIntType;
-    const _UIntType _Rp = __p.b() - __p.a() + _UIntType(1);
-    if (_Rp == 1)
-        return __p.a();
-    const size_t _Dt = numeric_limits<_UIntType>::digits;
-    typedef __independent_bits_engine<_URNG, _UIntType> _Eng;
-    if (_Rp == 0)
-        return static_cast<result_type>(_Eng(__g, _Dt)());
-    size_t __w = _Dt - __clz(_Rp) - 1;
-    if ((_Rp & (_UIntType(~0) >> (_Dt - __w))) != 0)
-        ++__w;
-    _Eng __e(__g, __w);
-    _UIntType __u;
-    do
-    {
-        __u = __e();
-    } while (__u >= _Rp);
-    return static_cast<result_type>(__u + __p.a());
-}
-
-class _LIBCPP_TYPE_VIS __rs_default;
-
-_LIBCPP_FUNC_VIS __rs_default __rs_get();
-
-class _LIBCPP_TYPE_VIS __rs_default
-{
-    static unsigned __c_;
-
-    __rs_default();
-public:
-    typedef uint_fast32_t result_type;
-
-    static const result_type _Min = 0;
-    static const result_type _Max = 0xFFFFFFFF;
-
-    __rs_default(const __rs_default&);
-    ~__rs_default();
-
-    result_type operator()();
-
-    static _LIBCPP_CONSTEXPR result_type min() {return _Min;}
-    static _LIBCPP_CONSTEXPR result_type max() {return _Max;}
-
-    friend _LIBCPP_FUNC_VIS __rs_default __rs_get();
-};
-
-_LIBCPP_FUNC_VIS __rs_default __rs_get();
-
-template <class _RandomAccessIterator>
-void
-random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
-    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    typedef uniform_int_distribution<ptrdiff_t> _Dp;
-    typedef typename _Dp::param_type _Pp;
-    difference_type __d = __last - __first;
-    if (__d > 1)
-    {
-        _Dp __uid;
-        __rs_default __g = __rs_get();
-        for (--__last, --__d; __first < __last; ++__first, --__d)
-        {
-            difference_type __i = __uid(__g, _Pp(0, __d));
-            if (__i != difference_type(0))
-                swap(*__first, *(__first + __i));
-        }
-    }
-}
-
-template <class _RandomAccessIterator, class _RandomNumberGenerator>
-void
-random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-               _RandomNumberGenerator&& __rand)
-#else
-               _RandomNumberGenerator& __rand)
-#endif
-{
-    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    difference_type __d = __last - __first;
-    if (__d > 1)
-    {
-        for (--__last; __first < __last; ++__first, --__d)
-        {
-            difference_type __i = __rand(__d);
-            swap(*__first, *(__first + __i));
-        }
-    }
-}
-
-template<class _RandomAccessIterator, class _UniformRandomNumberGenerator>
-    void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-                 _UniformRandomNumberGenerator&& __g)
-#else
-                 _UniformRandomNumberGenerator& __g)
-#endif
-{
-    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    typedef uniform_int_distribution<ptrdiff_t> _Dp;
-    typedef typename _Dp::param_type _Pp;
-    difference_type __d = __last - __first;
-    if (__d > 1)
-    {
-        _Dp __uid;
-        for (--__last, --__d; __first < __last; ++__first, --__d)
-        {
-            difference_type __i = __uid(__g, _Pp(0, __d));
-            if (__i != difference_type(0))
-                swap(*__first, *(__first + __i));
-        }
-    }
-}
-
-template <class _InputIterator, class _Predicate>
-bool
-is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred)
-{
-    for (; __first != __last; ++__first)
-        if (!__pred(*__first))
-            break;
-    for (; __first != __last; ++__first)
-        if (__pred(*__first))
-            return false;
-    return true;
-}
-
-// partition
-
-template <class _Predicate, class _ForwardIterator>
-_ForwardIterator
-__partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag)
-{
-    while (true)
-    {
-        if (__first == __last)
-            return __first;
-        if (!__pred(*__first))
-            break;
-        ++__first;
-    }
-    for (_ForwardIterator __p = __first; ++__p != __last;)
-    {
-        if (__pred(*__p))
-        {
-            swap(*__first, *__p);
-            ++__first;
-        }
-    }
-    return __first;
-}
-
-template <class _Predicate, class _BidirectionalIterator>
-_BidirectionalIterator
-__partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
-            bidirectional_iterator_tag)
-{
-    while (true)
-    {
-        while (true)
-        {
-            if (__first == __last)
-                return __first;
-            if (!__pred(*__first))
-                break;
-            ++__first;
-        }
-        do
-        {
-            if (__first == --__last)
-                return __first;
-        } while (!__pred(*__last));
-        swap(*__first, *__last);
-        ++__first;
-    }
-}
-
-template <class _ForwardIterator, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
-{
-    return _VSTD::__partition<typename add_lvalue_reference<_Predicate>::type>
-                            (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());
-}
-
-// partition_copy
-
-template <class _InputIterator, class _OutputIterator1,
-          class _OutputIterator2, class _Predicate>
-pair<_OutputIterator1, _OutputIterator2>
-partition_copy(_InputIterator __first, _InputIterator __last,
-               _OutputIterator1 __out_true, _OutputIterator2 __out_false,
-               _Predicate __pred)
-{
-    for (; __first != __last; ++__first)
-    {
-        if (__pred(*__first))
-        {
-            *__out_true = *__first;
-            ++__out_true;
-        }
-        else
-        {
-            *__out_false = *__first;
-            ++__out_false;
-        }
-    }
-    return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false);
-}
-
-// partition_point
-
-template<class _ForwardIterator, class _Predicate>
-_ForwardIterator
-partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
-{
-    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
-    difference_type __len = _VSTD::distance(__first, __last);
-    while (__len != 0)
-    {
-        difference_type __l2 = __len / 2;
-        _ForwardIterator __m = __first;
-        _VSTD::advance(__m, __l2);
-        if (__pred(*__m))
-        {
-            __first = ++__m;
-            __len -= __l2 + 1;
-        }
-        else
-            __len = __l2;
-    }
-    return __first;
-}
-
-// stable_partition
-
-template <class _Predicate, class _ForwardIterator, class _Distance, class _Pair>
-_ForwardIterator
-__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
-                   _Distance __len, _Pair __p, forward_iterator_tag __fit)
-{
-    // *__first is known to be false
-    // __len >= 1
-    if (__len == 1)
-        return __first;
-    if (__len == 2)
-    {
-        _ForwardIterator __m = __first;
-        if (__pred(*++__m))
-        {
-            swap(*__first, *__m);
-            return __m;
-        }
-        return __first;
-    }
-    if (__len <= __p.second)
-    {   // The buffer is big enough to use
-        typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
-        __destruct_n __d(0);
-        unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);
-        // Move the falses into the temporary buffer, and the trues to the front of the line
-        // Update __first to always point to the end of the trues
-        value_type* __t = __p.first;
-        ::new(__t) value_type(_VSTD::move(*__first));
-        __d.__incr((value_type*)0);
-        ++__t;
-        _ForwardIterator __i = __first;
-        while (++__i != __last)
-        {
-            if (__pred(*__i))
-            {
-                *__first = _VSTD::move(*__i);
-                ++__first;
-            }
-            else
-            {
-                ::new(__t) value_type(_VSTD::move(*__i));
-                __d.__incr((value_type*)0);
-                ++__t;
-            }
-        }
-        // All trues now at start of range, all falses in buffer
-        // Move falses back into range, but don't mess up __first which points to first false
-        __i = __first;
-        for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, ++__i)
-            *__i = _VSTD::move(*__t2);
-        // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
-        return __first;
-    }
-    // Else not enough buffer, do in place
-    // __len >= 3
-    _ForwardIterator __m = __first;
-    _Distance __len2 = __len / 2;  // __len2 >= 2
-    _VSTD::advance(__m, __len2);
-    // recurse on [__first, __m), *__first know to be false
-    // F?????????????????
-    // f       m         l
-    typedef typename add_lvalue_reference<_Predicate>::type _PredRef;
-    _ForwardIterator __first_false = __stable_partition<_PredRef>(__first, __m, __pred, __len2, __p, __fit);
-    // TTTFFFFF??????????
-    // f  ff   m         l
-    // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true
-    _ForwardIterator __m1 = __m;
-    _ForwardIterator __second_false = __last;
-    _Distance __len_half = __len - __len2;
-    while (__pred(*__m1))
-    {
-        if (++__m1 == __last)
-            goto __second_half_done;
-        --__len_half;
-    }
-    // TTTFFFFFTTTF??????
-    // f  ff   m  m1     l
-    __second_false = __stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __fit);
-__second_half_done:
-    // TTTFFFFFTTTTTFFFFF
-    // f  ff   m    sf   l
-    return _VSTD::rotate(__first_false, __m, __second_false);
-    // TTTTTTTTFFFFFFFFFF
-    //         |
-}
-
-struct __return_temporary_buffer
-{
-    template <class _Tp>
-    _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) const {_VSTD::return_temporary_buffer(__p);}
-};
-
-template <class _Predicate, class _ForwardIterator>
-_ForwardIterator
-__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
-                   forward_iterator_tag)
-{
-    const unsigned __alloc_limit = 3;  // might want to make this a function of trivial assignment
-    // Either prove all true and return __first or point to first false
-    while (true)
-    {
-        if (__first == __last)
-            return __first;
-        if (!__pred(*__first))
-            break;
-        ++__first;
-    }
-    // We now have a reduced range [__first, __last)
-    // *__first is known to be false
-    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
-    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
-    difference_type __len = _VSTD::distance(__first, __last);
-    pair<value_type*, ptrdiff_t> __p(0, 0);
-    unique_ptr<value_type, __return_temporary_buffer> __h;
-    if (__len >= __alloc_limit)
-    {
-        __p = _VSTD::get_temporary_buffer<value_type>(__len);
-        __h.reset(__p.first);
-    }
-    return __stable_partition<typename add_lvalue_reference<_Predicate>::type>
-                             (__first, __last, __pred, __len, __p, forward_iterator_tag());
-}
-
-template <class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair>
-_BidirectionalIterator
-__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
-                   _Distance __len, _Pair __p, bidirectional_iterator_tag __bit)
-{
-    // *__first is known to be false
-    // *__last is known to be true
-    // __len >= 2
-    if (__len == 2)
-    {
-        swap(*__first, *__last);
-        return __last;
-    }
-    if (__len == 3)
-    {
-        _BidirectionalIterator __m = __first;
-        if (__pred(*++__m))
-        {
-            swap(*__first, *__m);
-            swap(*__m, *__last);
-            return __last;
-        }
-        swap(*__m, *__last);
-        swap(*__first, *__m);
-        return __m;
-    }
-    if (__len <= __p.second)
-    {   // The buffer is big enough to use
-        typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
-        __destruct_n __d(0);
-        unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);
-        // Move the falses into the temporary buffer, and the trues to the front of the line
-        // Update __first to always point to the end of the trues
-        value_type* __t = __p.first;
-        ::new(__t) value_type(_VSTD::move(*__first));
-        __d.__incr((value_type*)0);
-        ++__t;
-        _BidirectionalIterator __i = __first;
-        while (++__i != __last)
-        {
-            if (__pred(*__i))
-            {
-                *__first = _VSTD::move(*__i);
-                ++__first;
-            }
-            else
-            {
-                ::new(__t) value_type(_VSTD::move(*__i));
-                __d.__incr((value_type*)0);
-                ++__t;
-            }
-        }
-        // move *__last, known to be true
-        *__first = _VSTD::move(*__i);
-        __i = ++__first;
-        // All trues now at start of range, all falses in buffer
-        // Move falses back into range, but don't mess up __first which points to first false
-        for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, ++__i)
-            *__i = _VSTD::move(*__t2);
-        // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
-        return __first;
-    }
-    // Else not enough buffer, do in place
-    // __len >= 4
-    _BidirectionalIterator __m = __first;
-    _Distance __len2 = __len / 2;  // __len2 >= 2
-    _VSTD::advance(__m, __len2);
-    // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false
-    // F????????????????T
-    // f       m        l
-    _BidirectionalIterator __m1 = __m;
-    _BidirectionalIterator __first_false = __first;
-    _Distance __len_half = __len2;
-    while (!__pred(*--__m1))
-    {
-        if (__m1 == __first)
-            goto __first_half_done;
-        --__len_half;
-    }
-    // F???TFFF?????????T
-    // f   m1  m        l
-    typedef typename add_lvalue_reference<_Predicate>::type _PredRef;
-    __first_false = __stable_partition<_PredRef>(__first, __m1, __pred, __len_half, __p, __bit);
-__first_half_done:
-    // TTTFFFFF?????????T
-    // f  ff   m        l
-    // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true
-    __m1 = __m;
-    _BidirectionalIterator __second_false = __last;
-    ++__second_false;
-    __len_half = __len - __len2;
-    while (__pred(*__m1))
-    {
-        if (++__m1 == __last)
-            goto __second_half_done;
-        --__len_half;
-    }
-    // TTTFFFFFTTTF?????T
-    // f  ff   m  m1    l
-    __second_false = __stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __bit);
-__second_half_done:
-    // TTTFFFFFTTTTTFFFFF
-    // f  ff   m    sf  l
-    return _VSTD::rotate(__first_false, __m, __second_false);
-    // TTTTTTTTFFFFFFFFFF
-    //         |
-}
-
-template <class _Predicate, class _BidirectionalIterator>
-_BidirectionalIterator
-__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
-                   bidirectional_iterator_tag)
-{
-    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
-    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
-    const difference_type __alloc_limit = 4;  // might want to make this a function of trivial assignment
-    // Either prove all true and return __first or point to first false
-    while (true)
-    {
-        if (__first == __last)
-            return __first;
-        if (!__pred(*__first))
-            break;
-        ++__first;
-    }
-    // __first points to first false, everything prior to __first is already set.
-    // Either prove [__first, __last) is all false and return __first, or point __last to last true
-    do
-    {
-        if (__first == --__last)
-            return __first;
-    } while (!__pred(*__last));
-    // We now have a reduced range [__first, __last]
-    // *__first is known to be false
-    // *__last is known to be true
-    // __len >= 2
-    difference_type __len = _VSTD::distance(__first, __last) + 1;
-    pair<value_type*, ptrdiff_t> __p(0, 0);
-    unique_ptr<value_type, __return_temporary_buffer> __h;
-    if (__len >= __alloc_limit)
-    {
-        __p = _VSTD::get_temporary_buffer<value_type>(__len);
-        __h.reset(__p.first);
-    }
-    return __stable_partition<typename add_lvalue_reference<_Predicate>::type>
-                             (__first, __last, __pred, __len, __p, bidirectional_iterator_tag());
-}
-
-template <class _ForwardIterator, class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
-{
-    return __stable_partition<typename add_lvalue_reference<_Predicate>::type>
-                             (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());
-}
-
-// is_sorted_until
-
-template <class _ForwardIterator, class _Compare>
-_ForwardIterator
-is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
-{
-    if (__first != __last)
-    {
-        _ForwardIterator __i = __first;
-        while (++__i != __last)
-        {
-            if (__comp(*__i, *__first))
-                return __i;
-            __first = __i;
-        }
-    }
-    return __last;
-}
-
-template<class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
-{
-    return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
-}
-
-// is_sorted
-
-template <class _ForwardIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
-{
-    return _VSTD::is_sorted_until(__first, __last, __comp) == __last;
-}
-
-template<class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-is_sorted(_ForwardIterator __first, _ForwardIterator __last)
-{
-    return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
-}
-
-// sort
-
-// stable, 2-3 compares, 0-2 swaps
-
-template <class _Compare, class _ForwardIterator>
-unsigned
-__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c)
-{
-    unsigned __r = 0;
-    if (!__c(*__y, *__x))          // if x <= y
-    {
-        if (!__c(*__z, *__y))      // if y <= z
-            return __r;            // x <= y && y <= z
-                                   // x <= y && y > z
-        swap(*__y, *__z);          // x <= z && y < z
-        __r = 1;
-        if (__c(*__y, *__x))       // if x > y
-        {
-            swap(*__x, *__y);      // x < y && y <= z
-            __r = 2;
-        }
-        return __r;                // x <= y && y < z
-    }
-    if (__c(*__z, *__y))           // x > y, if y > z
-    {
-        swap(*__x, *__z);          // x < y && y < z
-        __r = 1;
-        return __r;
-    }
-    swap(*__x, *__y);              // x > y && y <= z
-    __r = 1;                       // x < y && x <= z
-    if (__c(*__z, *__y))           // if y > z
-    {
-        swap(*__y, *__z);          // x <= y && y < z
-        __r = 2;
-    }
-    return __r;
-}                                  // x <= y && y <= z
-
-// stable, 3-6 compares, 0-5 swaps
-
-template <class _Compare, class _ForwardIterator>
-unsigned
-__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
-            _ForwardIterator __x4, _Compare __c)
-{
-    unsigned __r = __sort3<_Compare>(__x1, __x2, __x3, __c);
-    if (__c(*__x4, *__x3))
-    {
-        swap(*__x3, *__x4);
-        ++__r;
-        if (__c(*__x3, *__x2))
-        {
-            swap(*__x2, *__x3);
-            ++__r;
-            if (__c(*__x2, *__x1))
-            {
-                swap(*__x1, *__x2);
-                ++__r;
-            }
-        }
-    }
-    return __r;
-}
-
-// stable, 4-10 compares, 0-9 swaps
-
-template <class _Compare, class _ForwardIterator>
-unsigned
-__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
-            _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c)
-{
-    unsigned __r = __sort4<_Compare>(__x1, __x2, __x3, __x4, __c);
-    if (__c(*__x5, *__x4))
-    {
-        swap(*__x4, *__x5);
-        ++__r;
-        if (__c(*__x4, *__x3))
-        {
-            swap(*__x3, *__x4);
-            ++__r;
-            if (__c(*__x3, *__x2))
-            {
-                swap(*__x2, *__x3);
-                ++__r;
-                if (__c(*__x2, *__x1))
-                {
-                    swap(*__x1, *__x2);
-                    ++__r;
-                }
-            }
-        }
-    }
-    return __r;
-}
-
-// Assumes size > 0
-template <class _Compare, class _BirdirectionalIterator>
-void
-__selection_sort(_BirdirectionalIterator __first, _BirdirectionalIterator __last, _Compare __comp)
-{
-    _BirdirectionalIterator __lm1 = __last;
-    for (--__lm1; __first != __lm1; ++__first)
-    {
-        _BirdirectionalIterator __i = _VSTD::min_element<_BirdirectionalIterator,
-                                                        typename add_lvalue_reference<_Compare>::type>
-                                                       (__first, __last, __comp);
-        if (__i != __first)
-            swap(*__first, *__i);
-    }
-}
-
-template <class _Compare, class _BirdirectionalIterator>
-void
-__insertion_sort(_BirdirectionalIterator __first, _BirdirectionalIterator __last, _Compare __comp)
-{
-    typedef typename iterator_traits<_BirdirectionalIterator>::value_type value_type;
-    if (__first != __last)
-    {
-        _BirdirectionalIterator __i = __first;
-        for (++__i; __i != __last; ++__i)
-        {
-            _BirdirectionalIterator __j = __i;
-            value_type __t(_VSTD::move(*__j));
-            for (_BirdirectionalIterator __k = __i; __k != __first && __comp(__t,  *--__k); --__j)
-                *__j = _VSTD::move(*__k);
-            *__j = _VSTD::move(__t);
-        }
-    }
-}
-
-template <class _Compare, class _RandomAccessIterator>
-void
-__insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
-    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
-    _RandomAccessIterator __j = __first+2;
-    __sort3<_Compare>(__first, __first+1, __j, __comp);
-    for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i)
-    {
-        if (__comp(*__i, *__j))
-        {
-            value_type __t(_VSTD::move(*__i));
-            _RandomAccessIterator __k = __j;
-            __j = __i;
-            do
-            {
-                *__j = _VSTD::move(*__k);
-                __j = __k;
-            } while (__j != __first && __comp(__t, *--__k));
-            *__j = _VSTD::move(__t);
-        }
-        __j = __i;
-    }
-}
-
-template <class _Compare, class _RandomAccessIterator>
-bool
-__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
-    switch (__last - __first)
-    {
-    case 0:
-    case 1:
-        return true;
-    case 2:
-        if (__comp(*--__last, *__first))
-            swap(*__first, *__last);
-        return true;
-    case 3:
-        _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp);
-        return true;
-    case 4:
-        _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);
-        return true;
-    case 5:
-        _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp);
-        return true;
-    }
-    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
-    _RandomAccessIterator __j = __first+2;
-    __sort3<_Compare>(__first, __first+1, __j, __comp);
-    const unsigned __limit = 8;
-    unsigned __count = 0;
-    for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i)
-    {
-        if (__comp(*__i, *__j))
-        {
-            value_type __t(_VSTD::move(*__i));
-            _RandomAccessIterator __k = __j;
-            __j = __i;
-            do
-            {
-                *__j = _VSTD::move(*__k);
-                __j = __k;
-            } while (__j != __first && __comp(__t, *--__k));
-            *__j = _VSTD::move(__t);
-            if (++__count == __limit)
-                return ++__i == __last;
-        }
-        __j = __i;
-    }
-    return true;
-}
-
-template <class _Compare, class _BirdirectionalIterator>
-void
-__insertion_sort_move(_BirdirectionalIterator __first1, _BirdirectionalIterator __last1,
-                      typename iterator_traits<_BirdirectionalIterator>::value_type* __first2, _Compare __comp)
-{
-    typedef typename iterator_traits<_BirdirectionalIterator>::value_type value_type;
-    if (__first1 != __last1)
-    {
-        __destruct_n __d(0);
-        unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
-        value_type* __last2 = __first2;
-        ::new(__last2) value_type(_VSTD::move(*__first1));
-        __d.__incr((value_type*)0);
-        for (++__last2; ++__first1 != __last1; ++__last2)
-        {
-            value_type* __j2 = __last2;
-            value_type* __i2 = __j2;
-            if (__comp(*__first1, *--__i2))
-            {
-                ::new(__j2) value_type(_VSTD::move(*__i2));
-                __d.__incr((value_type*)0);
-                for (--__j2; __i2 != __first2 && __comp(*__first1,  *--__i2); --__j2)
-                    *__j2 = _VSTD::move(*__i2);
-                *__j2 = _VSTD::move(*__first1);
-            }
-            else
-            {
-                ::new(__j2) value_type(_VSTD::move(*__first1));
-                __d.__incr((value_type*)0);
-            }
-        }
-        __h.release();
-    }
-}
-
-template <class _Compare, class _RandomAccessIterator>
-void
-__sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
-    // _Compare is known to be a reference type
-    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
-    const difference_type __limit = is_trivially_copy_constructible<value_type>::value &&
-                                    is_trivially_copy_assignable<value_type>::value ? 30 : 6;
-    while (true)
-    {
-    __restart:
-        difference_type __len = __last - __first;
-        switch (__len)
-        {
-        case 0:
-        case 1:
-            return;
-        case 2:
-            if (__comp(*--__last, *__first))
-                swap(*__first, *__last);
-            return;
-        case 3:
-            _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp);
-            return;
-        case 4:
-            _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);
-            return;
-        case 5:
-            _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp);
-            return;
-        }
-        if (__len <= __limit)
-        {
-            _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp);
-            return;
-        }
-        // __len > 5
-        _RandomAccessIterator __m = __first;
-        _RandomAccessIterator __lm1 = __last;
-        --__lm1;
-        unsigned __n_swaps;
-        {
-        difference_type __delta;
-        if (__len >= 1000)
-        {
-            __delta = __len/2;
-            __m += __delta;
-            __delta /= 2;
-            __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m+__delta, __lm1, __comp);
-        }
-        else
-        {
-            __delta = __len/2;
-            __m += __delta;
-            __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp);
-        }
-        }
-        // *__m is median
-        // partition [__first, __m) < *__m and *__m <= [__m, __last)
-        // (this inhibits tossing elements equivalent to __m around unnecessarily)
-        _RandomAccessIterator __i = __first;
-        _RandomAccessIterator __j = __lm1;
-        // j points beyond range to be tested, *__m is known to be <= *__lm1
-        // The search going up is known to be guarded but the search coming down isn't.
-        // Prime the downward search with a guard.
-        if (!__comp(*__i, *__m))  // if *__first == *__m
-        {
-            // *__first == *__m, *__first doesn't go in first part
-            // manually guard downward moving __j against __i
-            while (true)
-            {
-                if (__i == --__j)
-                {
-                    // *__first == *__m, *__m <= all other elements
-                    // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)
-                    ++__i;  // __first + 1
-                    __j = __last;
-                    if (!__comp(*__first, *--__j))  // we need a guard if *__first == *(__last-1)
-                    {
-                        while (true)
-                        {
-                            if (__i == __j)
-                                return;  // [__first, __last) all equivalent elements
-                            if (__comp(*__first, *__i))
-                            {
-                                swap(*__i, *__j);
-                                ++__n_swaps;
-                                ++__i;
-                                break;
-                            }
-                            ++__i;
-                        }
-                    }
-                    // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
-                    if (__i == __j)
-                        return;
-                    while (true)
-                    {
-                        while (!__comp(*__first, *__i))
-                            ++__i;
-                        while (__comp(*__first, *--__j))
-                            ;
-                        if (__i >= __j)
-                            break;
-                        swap(*__i, *__j);
-                        ++__n_swaps;
-                        ++__i;
-                    }
-                    // [__first, __i) == *__first and *__first < [__i, __last)
-                    // The first part is sorted, sort the secod part
-                    // _VSTD::__sort<_Compare>(__i, __last, __comp);
-                    __first = __i;
-                    goto __restart;
-                }
-                if (__comp(*__j, *__m))
-                {
-                    swap(*__i, *__j);
-                    ++__n_swaps;
-                    break;  // found guard for downward moving __j, now use unguarded partition
-                }
-            }
-        }
-        // It is known that *__i < *__m
-        ++__i;
-        // j points beyond range to be tested, *__m is known to be <= *__lm1
-        // if not yet partitioned...
-        if (__i < __j)
-        {
-            // known that *(__i - 1) < *__m
-            // known that __i <= __m
-            while (true)
-            {
-                // __m still guards upward moving __i
-                while (__comp(*__i, *__m))
-                    ++__i;
-                // It is now known that a guard exists for downward moving __j
-                while (!__comp(*--__j, *__m))
-                    ;
-                if (__i > __j)
-                    break;
-                swap(*__i, *__j);
-                ++__n_swaps;
-                // It is known that __m != __j
-                // If __m just moved, follow it
-                if (__m == __i)
-                    __m = __j;
-                ++__i;
-            }
-        }
-        // [__first, __i) < *__m and *__m <= [__i, __last)
-        if (__i != __m && __comp(*__m, *__i))
-        {
-            swap(*__i, *__m);
-            ++__n_swaps;
-        }
-        // [__first, __i) < *__i and *__i <= [__i+1, __last)
-        // If we were given a perfect partition, see if insertion sort is quick...
-        if (__n_swaps == 0)
-        {
-            bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp);
-            if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+1, __last, __comp))
-            {
-                if (__fs)
-                    return;
-                __last = __i;
-                continue;
-            }
-            else
-            {
-                if (__fs)
-                {
-                    __first = ++__i;
-                    continue;
-                }
-            }
-        }
-        // sort smaller range with recursive call and larger with tail recursion elimination
-        if (__i - __first < __last - __i)
-        {
-            _VSTD::__sort<_Compare>(__first, __i, __comp);
-            // _VSTD::__sort<_Compare>(__i+1, __last, __comp);
-            __first = ++__i;
-        }
-        else
-        {
-            _VSTD::__sort<_Compare>(__i+1, __last, __comp);
-            // _VSTD::__sort<_Compare>(__first, __i, __comp);
-            __last = __i;
-        }
-    }
-}
-
-// This forwarder keeps the top call and the recursive calls using the same instantiation, forcing a reference _Compare
-template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    __sort<_Comp_ref>(__first, __last, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    __sort<_Comp_ref>(__first, __last, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
-    _VSTD::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-sort(_Tp** __first, _Tp** __last)
-{
-    _VSTD::sort((size_t*)__first, (size_t*)__last, __less<size_t>());
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-sort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last)
-{
-    _VSTD::sort(__first.base(), __last.base());
-}
-
-template <class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-sort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last, _Compare __comp)
-{
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    _VSTD::sort<_Tp*, _Comp_ref>(__first.base(), __last.base(), __comp);
-}
-
-#ifdef _LIBCPP_MSVC
-#pragma warning( push )
-#pragma warning( disable: 4231)
-#endif // _LIBCPP_MSVC
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
-
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&))
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
-
-_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&))
-#ifdef _LIBCPP_MSVC
-#pragma warning( pop )
-#endif  // _LIBCPP_MSVC
-
-// lower_bound
-
-template <class _Compare, class _ForwardIterator, class _Tp>
-_ForwardIterator
-__lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
-{
-    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
-    difference_type __len = _VSTD::distance(__first, __last);
-    while (__len != 0)
-    {
-        difference_type __l2 = __len / 2;
-        _ForwardIterator __m = __first;
-        _VSTD::advance(__m, __l2);
-        if (__comp(*__m, __value_))
-        {
-            __first = ++__m;
-            __len -= __l2 + 1;
-        }
-        else
-            __len = __l2;
-    }
-    return __first;
-}
-
-template <class _ForwardIterator, class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return __lower_bound<_Comp_ref>(__first, __last, __value_, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return __lower_bound<_Comp_ref>(__first, __last, __value_, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _ForwardIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
-{
-    return _VSTD::lower_bound(__first, __last, __value_,
-                             __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
-}
-
-// upper_bound
-
-template <class _Compare, class _ForwardIterator, class _Tp>
-_ForwardIterator
-__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
-{
-    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
-    difference_type __len = _VSTD::distance(__first, __last);
-    while (__len != 0)
-    {
-        difference_type __l2 = __len / 2;
-        _ForwardIterator __m = __first;
-        _VSTD::advance(__m, __l2);
-        if (__comp(__value_, *__m))
-            __len = __l2;
-        else
-        {
-            __first = ++__m;
-            __len -= __l2 + 1;
-        }
-    }
-    return __first;
-}
-
-template <class _ForwardIterator, class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return __upper_bound<_Comp_ref>(__first, __last, __value_, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return __upper_bound<_Comp_ref>(__first, __last, __value_, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _ForwardIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
-{
-    return _VSTD::upper_bound(__first, __last, __value_,
-                             __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>());
-}
-
-// equal_range
-
-template <class _Compare, class _ForwardIterator, class _Tp>
-pair<_ForwardIterator, _ForwardIterator>
-__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
-{
-    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
-    difference_type __len = _VSTD::distance(__first, __last);
-    while (__len != 0)
-    {
-        difference_type __l2 = __len / 2;
-        _ForwardIterator __m = __first;
-        _VSTD::advance(__m, __l2);
-        if (__comp(*__m, __value_))
-        {
-            __first = ++__m;
-            __len -= __l2 + 1;
-        }
-        else if (__comp(__value_, *__m))
-        {
-            __last = __m;
-            __len = __l2;
-        }
-        else
-        {
-            _ForwardIterator __mp1 = __m;
-            return pair<_ForwardIterator, _ForwardIterator>
-                   (
-                      __lower_bound<_Compare>(__first, __m, __value_, __comp),
-                      __upper_bound<_Compare>(++__mp1, __last, __value_, __comp)
-                   );
-        }
-    }
-    return pair<_ForwardIterator, _ForwardIterator>(__first, __first);
-}
-
-template <class _ForwardIterator, class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-pair<_ForwardIterator, _ForwardIterator>
-equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return __equal_range<_Comp_ref>(__first, __last, __value_, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return __equal_range<_Comp_ref>(__first, __last, __value_, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _ForwardIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-pair<_ForwardIterator, _ForwardIterator>
-equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
-{
-    return _VSTD::equal_range(__first, __last, __value_,
-                             __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
-}
-
-// binary_search
-
-template <class _Compare, class _ForwardIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-__binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
-{
-    __first = __lower_bound<_Compare>(__first, __last, __value_, __comp);
-    return __first != __last && !__comp(__value_, *__first);
-}
-
-template <class _ForwardIterator, class _Tp, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return __binary_search<_Comp_ref>(__first, __last, __value_, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return __binary_search<_Comp_ref>(__first, __last, __value_, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _ForwardIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
-{
-    return _VSTD::binary_search(__first, __last, __value_,
-                             __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
-}
-
-// merge
-
-template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
-_OutputIterator
-__merge(_InputIterator1 __first1, _InputIterator1 __last1,
-        _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
-    for (; __first1 != __last1; ++__result)
-    {
-        if (__first2 == __last2)
-            return _VSTD::copy(__first1, __last1, __result);
-        if (__comp(*__first2, *__first1))
-        {
-            *__result = *__first2;
-            ++__first2;
-        }
-        else
-        {
-            *__result = *__first1;
-            ++__first1;
-        }
-    }
-    return _VSTD::copy(__first2, __last2, __result);
-}
-
-template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-merge(_InputIterator1 __first1, _InputIterator1 __last1,
-      _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-merge(_InputIterator1 __first1, _InputIterator1 __last1,
-      _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
-{
-    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
-    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
-    return merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>());
-}
-
-// inplace_merge
-
-template <class _Compare, class _BidirectionalIterator>
-void
-__buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
-                _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
-                                 typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
-                typename iterator_traits<_BidirectionalIterator>::value_type* __buff)
-{
-    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
-    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
-    typedef typename iterator_traits<_BidirectionalIterator>::pointer pointer;
-    __destruct_n __d(0);
-    unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
-    if (__len1 <= __len2)
-    {
-        value_type* __p = __buff;
-        for (_BidirectionalIterator __i = __first; __i != __middle; __d.__incr((value_type*)0), ++__i, ++__p)
-            ::new(__p) value_type(_VSTD::move(*__i));
-        __merge<_Compare>(move_iterator<value_type*>(__buff),
-                          move_iterator<value_type*>(__p),
-                          move_iterator<_BidirectionalIterator>(__middle),
-                          move_iterator<_BidirectionalIterator>(__last),
-                          __first, __comp);
-    }
-    else
-    {
-        value_type* __p = __buff;
-        for (_BidirectionalIterator __i = __middle; __i != __last; __d.__incr((value_type*)0), ++__i, ++__p)
-            ::new(__p) value_type(_VSTD::move(*__i));
-        typedef reverse_iterator<_BidirectionalIterator> _RBi;
-        typedef reverse_iterator<value_type*> _Rv;
-        __merge(move_iterator<_RBi>(_RBi(__middle)), move_iterator<_RBi>(_RBi(__first)),
-                move_iterator<_Rv>(_Rv(__p)), move_iterator<_Rv>(_Rv(__buff)),
-                _RBi(__last), __negate<_Compare>(__comp));
-    }
-}
-
-template <class _Compare, class _BidirectionalIterator>
-void
-__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
-                _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
-                                 typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
-                typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size)
-{
-    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
-    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
-    while (true)
-    {
-        // if __middle == __last, we're done
-        if (__len2 == 0)
-            return;
-        // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0
-        for (; true; ++__first, --__len1)
-        {
-            if (__len1 == 0)
-                return;
-            if (__comp(*__middle, *__first))
-                break;
-        }
-        if (__len1 <= __buff_size || __len2 <= __buff_size)
-        {
-            __buffered_inplace_merge<_Compare>(__first, __middle, __last, __comp, __len1, __len2, __buff);
-            return;
-        }
-        // __first < __middle < __last
-        // *__first > *__middle
-        // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that
-        //     all elements in:
-        //         [__first, __m1)  <= [__middle, __m2)
-        //         [__middle, __m2) <  [__m1, __middle)
-        //         [__m1, __middle) <= [__m2, __last)
-        //     and __m1 or __m2 is in the middle of its range
-        _BidirectionalIterator __m1;  // "median" of [__first, __middle)
-        _BidirectionalIterator __m2;  // "median" of [__middle, __last)
-        difference_type __len11;      // distance(__first, __m1)
-        difference_type __len21;      // distance(__middle, __m2)
-        // binary search smaller range
-        if (__len1 < __len2)
-        {   // __len >= 1, __len2 >= 2
-            __len21 = __len2 / 2;
-            __m2 = __middle;
-            _VSTD::advance(__m2, __len21);
-            __m1 = __upper_bound<_Compare>(__first, __middle, *__m2, __comp);
-            __len11 = _VSTD::distance(__first, __m1);
-        }
-        else
-        {
-            if (__len1 == 1)
-            {   // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1
-                // It is known *__first > *__middle
-                swap(*__first, *__middle);
-                return;
-            }
-            // __len1 >= 2, __len2 >= 1
-            __len11 = __len1 / 2;
-            __m1 = __first;
-            _VSTD::advance(__m1, __len11);
-            __m2 = __lower_bound<_Compare>(__middle, __last, *__m1, __comp);
-            __len21 = _VSTD::distance(__middle, __m2);
-        }
-        difference_type __len12 = __len1 - __len11;  // distance(__m1, __middle)
-        difference_type __len22 = __len2 - __len21;  // distance(__m2, __last)
-        // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last)
-        // swap middle two partitions
-        __middle = _VSTD::rotate(__m1, __middle, __m2);
-        // __len12 and __len21 now have swapped meanings
-        // merge smaller range with recurisve call and larger with tail recursion elimination
-        if (__len11 + __len21 < __len12 + __len22)
-        {
-            __inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
-//          __inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
-            __first = __middle;
-            __middle = __m2;
-            __len1 = __len12;
-            __len2 = __len22;
-        }
-        else
-        {
-            __inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
-//          __inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
-            __last = __middle;
-            __middle = __m1;
-            __len1 = __len11;
-            __len2 = __len21;
-        }
-    }
-}
-
-template <class _Tp>
-struct __inplace_merge_switch
-{
-    static const unsigned value = is_trivially_copy_assignable<_Tp>::value;
-};
-
-template <class _BidirectionalIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
-              _Compare __comp)
-{
-    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
-    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
-    difference_type __len1 = _VSTD::distance(__first, __middle);
-    difference_type __len2 = _VSTD::distance(__middle, __last);
-    difference_type __buf_size = _VSTD::min(__len1, __len2);
-    pair<value_type*, ptrdiff_t> __buf(0, 0);
-    unique_ptr<value_type, __return_temporary_buffer> __h;
-    if (__inplace_merge_switch<value_type>::value && __buf_size > 8)
-    {
-        __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size);
-        __h.reset(__buf.first);
-    }
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __c, __len1, __len2,
-                                            __buf.first, __buf.second);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2,
-                                            __buf.first, __buf.second);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _BidirectionalIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last)
-{
-    _VSTD::inplace_merge(__first, __middle, __last,
-                        __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
-}
-
-// stable_sort
-
-template <class _Compare, class _InputIterator1, class _InputIterator2>
-void
-__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1,
-        _InputIterator2 __first2, _InputIterator2 __last2,
-        typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp)
-{
-    typedef typename iterator_traits<_InputIterator1>::value_type value_type;
-    __destruct_n __d(0);
-    unique_ptr<value_type, __destruct_n&> __h(__result, __d);
-    for (; true; ++__result)
-    {
-        if (__first1 == __last1)
-        {
-            for (; __first2 != __last2; ++__first2, ++__result, __d.__incr((value_type*)0))
-                ::new (__result) value_type(_VSTD::move(*__first2));
-            __h.release();
-            return;
-        }
-        if (__first2 == __last2)
-        {
-            for (; __first1 != __last1; ++__first1, ++__result, __d.__incr((value_type*)0))
-                ::new (__result) value_type(_VSTD::move(*__first1));
-            __h.release();
-            return;
-        }
-        if (__comp(*__first2, *__first1))
-        {
-            ::new (__result) value_type(_VSTD::move(*__first2));
-            __d.__incr((value_type*)0);
-            ++__first2;
-        }
-        else
-        {
-            ::new (__result) value_type(_VSTD::move(*__first1));
-            __d.__incr((value_type*)0);
-            ++__first1;
-        }
-    }
-}
-
-template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
-void
-__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1,
-        _InputIterator2 __first2, _InputIterator2 __last2,
-        _OutputIterator __result, _Compare __comp)
-{
-    for (; __first1 != __last1; ++__result)
-    {
-        if (__first2 == __last2)
-        {
-            for (; __first1 != __last1; ++__first1, ++__result)
-                *__result = _VSTD::move(*__first1);
-            return;
-        }
-        if (__comp(*__first2, *__first1))
-        {
-            *__result = _VSTD::move(*__first2);
-            ++__first2;
-        }
-        else
-        {
-            *__result = _VSTD::move(*__first1);
-            ++__first1;
-        }
-    }
-    for (; __first2 != __last2; ++__first2, ++__result)
-        *__result = _VSTD::move(*__first2);
-}
-
-template <class _Compare, class _RandomAccessIterator>
-void
-__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
-              typename iterator_traits<_RandomAccessIterator>::difference_type __len,
-              typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size);
-
-template <class _Compare, class _RandomAccessIterator>
-void
-__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp,
-                   typename iterator_traits<_RandomAccessIterator>::difference_type __len,
-                   typename iterator_traits<_RandomAccessIterator>::value_type* __first2)
-{
-    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
-    switch (__len)
-    {
-    case 0:
-        return;
-    case 1:
-        ::new(__first2) value_type(_VSTD::move(*__first1));
-        return;
-    case 2:
-       __destruct_n __d(0);
-        unique_ptr<value_type, __destruct_n&> __h2(__first2, __d);
-         if (__comp(*--__last1, *__first1))
-        {
-            ::new(__first2) value_type(_VSTD::move(*__last1));
-            __d.__incr((value_type*)0);
-            ++__first2;
-            ::new(__first2) value_type(_VSTD::move(*__first1));
-        }
-        else
-        {
-            ::new(__first2) value_type(_VSTD::move(*__first1));
-            __d.__incr((value_type*)0);
-            ++__first2;
-            ::new(__first2) value_type(_VSTD::move(*__last1));
-        }
-        __h2.release();
-        return;
-    }
-    if (__len <= 8)
-    {
-        __insertion_sort_move<_Compare>(__first1, __last1, __first2, __comp);
-        return;
-    }
-    typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;
-    _RandomAccessIterator __m = __first1 + __l2;
-    __stable_sort<_Compare>(__first1, __m, __comp, __l2, __first2, __l2);
-    __stable_sort<_Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2);
-    __merge_move_construct<_Compare>(__first1, __m, __m, __last1, __first2, __comp);
-}
-
-template <class _Tp>
-struct __stable_sort_switch
-{
-    static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value;
-};
-
-template <class _Compare, class _RandomAccessIterator>
-void
-__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
-              typename iterator_traits<_RandomAccessIterator>::difference_type __len,
-              typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size)
-{
-    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
-    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    switch (__len)
-    {
-    case 0:
-    case 1:
-        return;
-    case 2:
-        if (__comp(*--__last, *__first))
-            swap(*__first, *__last);
-        return;
-    }
-    if (__len <= static_cast<difference_type>(__stable_sort_switch<value_type>::value))
-    {
-        __insertion_sort<_Compare>(__first, __last, __comp);
-        return;
-    }
-    typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;
-    _RandomAccessIterator __m = __first + __l2;
-    if (__len <= __buff_size)
-    {
-        __destruct_n __d(0);
-        unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
-        __stable_sort_move<_Compare>(__first, __m, __comp, __l2, __buff);
-        __d.__set(__l2, (value_type*)0);
-        __stable_sort_move<_Compare>(__m, __last, __comp, __len - __l2, __buff + __l2);
-        __d.__set(__len, (value_type*)0);
-        __merge_move_assign<_Compare>(__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp);
-//         __merge<_Compare>(move_iterator<value_type*>(__buff),
-//                           move_iterator<value_type*>(__buff + __l2),
-//                           move_iterator<_RandomAccessIterator>(__buff + __l2),
-//                           move_iterator<_RandomAccessIterator>(__buff + __len),
-//                           __first, __comp);
-        return;
-    }
-    __stable_sort<_Compare>(__first, __m, __comp, __l2, __buff, __buff_size);
-    __stable_sort<_Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size);
-    __inplace_merge<_Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size);
-}
-
-template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
-    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
-    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    difference_type __len = __last - __first;
-    pair<value_type*, ptrdiff_t> __buf(0, 0);
-    unique_ptr<value_type, __return_temporary_buffer> __h;
-    if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value))
-    {
-        __buf = _VSTD::get_temporary_buffer<value_type>(__len);
-        __h.reset(__buf.first);
-    }
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    __stable_sort<_Comp_ref>(__first, __last, __c, __len, __buf.first, __buf.second);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    __stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
-    _VSTD::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
-}
-
-// is_heap_until
-
-template <class _RandomAccessIterator, class _Compare>
-_RandomAccessIterator
-is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
-    typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    difference_type __len = __last - __first;
-    difference_type __p = 0;
-    difference_type __c = 1;
-    _RandomAccessIterator __pp = __first;
-    while (__c < __len)
-    {
-        _RandomAccessIterator __cp = __first + __c;
-        if (__comp(*__pp, *__cp))
-            return __cp;
-        ++__c;
-        ++__cp;
-        if (__c == __len)
-            return __last;
-        if (__comp(*__pp, *__cp))
-            return __cp;
-        ++__p;
-        ++__pp;
-        __c = 2 * __p + 1;
-    }
-    return __last;
-}
-
-template<class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_RandomAccessIterator
-is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
-    return _VSTD::is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
-}
-
-// is_heap
-
-template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
-    return _VSTD::is_heap_until(__first, __last, __comp) == __last;
-}
-
-template<class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
-    return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
-}
-
-// push_heap
-
-template <class _Compare, class _RandomAccessIterator>
-void
-__sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
-          typename iterator_traits<_RandomAccessIterator>::difference_type __len)
-{
-    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
-    if (__len > 1)
-    {
-        __len = (__len - 2) / 2;
-        _RandomAccessIterator __ptr = __first + __len;
-        if (__comp(*__ptr, *--__last))
-        {
-            value_type __t(_VSTD::move(*__last));
-            do
-            {
-                *__last = _VSTD::move(*__ptr);
-                __last = __ptr;
-                if (__len == 0)
-                    break;
-                __len = (__len - 1) / 2;
-                __ptr = __first + __len;
-            } while (__comp(*__ptr, __t));
-            *__last = _VSTD::move(__t);
-        }
-    }
-}
-
-template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    __sift_up<_Comp_ref>(__first, __last, __c, __last - __first);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    __sift_up<_Comp_ref>(__first, __last, __comp, __last - __first);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
-    _VSTD::push_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
-}
-
-// pop_heap
-
-template <class _Compare, class _RandomAccessIterator>
-void
-__sift_down(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
-            typename iterator_traits<_RandomAccessIterator>::difference_type __len,
-            _RandomAccessIterator __start)
-{
-    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
-    // left-child of __start is at 2 * __start + 1
-    // right-child of __start is at 2 * __start + 2
-    difference_type __child = __start - __first;
-
-    if (__len < 2 || (__len - 2) / 2 < __child)
-        return;
-
-    __child = 2 * __child + 1;
-    _RandomAccessIterator __child_i = __first + __child;
-
-    if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) {
-        // right-child exists and is greater than left-child
-        ++__child_i;
-        ++__child;
-    }
-
-    // check if we are in heap-order
-    if (__comp(*__child_i, *__start))
-        // we are, __start is larger than it's largest child
-        return;
-
-    value_type __top(_VSTD::move(*__start));
-    do
-    {
-        // we are not in heap-order, swap the parent with it's largest child
-        *__start = _VSTD::move(*__child_i);
-        __start = __child_i;
-
-        if ((__len - 2) / 2 < __child)
-            break;
-
-        // recompute the child based off of the updated parent
-        __child = 2 * __child + 1;
-        __child_i = __first + __child;
-
-        if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) {
-            // right-child exists and is greater than left-child
-            ++__child_i;
-            ++__child;
-        }
-
-        // check if we are in heap-order
-    } while (!__comp(*__child_i, __top));
-    *__start = _VSTD::move(__top);
-}
-
-template <class _Compare, class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
-           typename iterator_traits<_RandomAccessIterator>::difference_type __len)
-{
-    if (__len > 1)
-    {
-        swap(*__first, *--__last);
-        __sift_down<_Compare>(__first, __last, __comp, __len - 1, __first);
-    }
-}
-
-template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    __pop_heap<_Comp_ref>(__first, __last, __c, __last - __first);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    __pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
-    _VSTD::pop_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
-}
-
-// make_heap
-
-template <class _Compare, class _RandomAccessIterator>
-void
-__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
-    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    difference_type __n = __last - __first;
-    if (__n > 1)
-    {
-        // start from the first parent, there is no need to consider children
-        for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start)
-        {
-            __sift_down<_Compare>(__first, __last, __comp, __n, __first + __start);
-        }
-    }
-}
-
-template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    __make_heap<_Comp_ref>(__first, __last, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    __make_heap<_Comp_ref>(__first, __last, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
-    _VSTD::make_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
-}
-
-// sort_heap
-
-template <class _Compare, class _RandomAccessIterator>
-void
-__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
-    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    for (difference_type __n = __last - __first; __n > 1; --__last, --__n)
-        __pop_heap<_Compare>(__first, __last, __comp, __n);
-}
-
-template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    __sort_heap<_Comp_ref>(__first, __last, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    __sort_heap<_Comp_ref>(__first, __last, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
-    _VSTD::sort_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
-}
-
-// partial_sort
-
-template <class _Compare, class _RandomAccessIterator>
-void
-__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
-             _Compare __comp)
-{
-    __make_heap<_Compare>(__first, __middle, __comp);
-    typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;
-    for (_RandomAccessIterator __i = __middle; __i != __last; ++__i)
-    {
-        if (__comp(*__i, *__first))
-        {
-            swap(*__i, *__first);
-            __sift_down<_Compare>(__first, __middle, __comp, __len, __first);
-        }
-    }
-    __sort_heap<_Compare>(__first, __middle, __comp);
-}
-
-template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
-             _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    __partial_sort<_Comp_ref>(__first, __middle, __last, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    __partial_sort<_Comp_ref>(__first, __middle, __last, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
-{
-    _VSTD::partial_sort(__first, __middle, __last,
-                       __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
-}
-
-// partial_sort_copy
-
-template <class _Compare, class _InputIterator, class _RandomAccessIterator>
-_RandomAccessIterator
-__partial_sort_copy(_InputIterator __first, _InputIterator __last,
-                    _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
-{
-    _RandomAccessIterator __r = __result_first;
-    if (__r != __result_last)
-    {
-        for (; __first != __last && __r != __result_last; ++__first, ++__r)
-            *__r = *__first;
-        __make_heap<_Compare>(__result_first, __r, __comp);
-        typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first;
-        for (; __first != __last; ++__first)
-            if (__comp(*__first, *__result_first))
-            {
-                *__result_first = *__first;
-                __sift_down<_Compare>(__result_first, __r, __comp, __len, __result_first);
-            }
-        __sort_heap<_Compare>(__result_first, __r, __comp);
-    }
-    return __r;
-}
-
-template <class _InputIterator, class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-_RandomAccessIterator
-partial_sort_copy(_InputIterator __first, _InputIterator __last,
-                  _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _InputIterator, class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_RandomAccessIterator
-partial_sort_copy(_InputIterator __first, _InputIterator __last,
-                  _RandomAccessIterator __result_first, _RandomAccessIterator __result_last)
-{
-    return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last,
-                                   __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
-}
-
-// nth_element
-
-template <class _Compare, class _RandomAccessIterator>
-void
-__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
-{
-    // _Compare is known to be a reference type
-    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    const difference_type __limit = 7;
-    while (true)
-    {
-    __restart:
-        if (__nth == __last)
-            return;
-        difference_type __len = __last - __first;
-        switch (__len)
-        {
-        case 0:
-        case 1:
-            return;
-        case 2:
-            if (__comp(*--__last, *__first))
-                swap(*__first, *__last);
-            return;
-        case 3:
-            {
-            _RandomAccessIterator __m = __first;
-            _VSTD::__sort3<_Compare>(__first, ++__m, --__last, __comp);
-            return;
-            }
-        }
-        if (__len <= __limit)
-        {
-            __selection_sort<_Compare>(__first, __last, __comp);
-            return;
-        }
-        // __len > __limit >= 3
-        _RandomAccessIterator __m = __first + __len/2;
-        _RandomAccessIterator __lm1 = __last;
-        unsigned __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, --__lm1, __comp);
-        // *__m is median
-        // partition [__first, __m) < *__m and *__m <= [__m, __last)
-        // (this inhibits tossing elements equivalent to __m around unnecessarily)
-        _RandomAccessIterator __i = __first;
-        _RandomAccessIterator __j = __lm1;
-        // j points beyond range to be tested, *__lm1 is known to be <= *__m
-        // The search going up is known to be guarded but the search coming down isn't.
-        // Prime the downward search with a guard.
-        if (!__comp(*__i, *__m))  // if *__first == *__m
-        {
-            // *__first == *__m, *__first doesn't go in first part
-            // manually guard downward moving __j against __i
-            while (true)
-            {
-                if (__i == --__j)
-                {
-                    // *__first == *__m, *__m <= all other elements
-                    // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)
-                    ++__i;  // __first + 1
-                    __j = __last;
-                    if (!__comp(*__first, *--__j))  // we need a guard if *__first == *(__last-1)
-                    {
-                        while (true)
-                        {
-                            if (__i == __j)
-                                return;  // [__first, __last) all equivalent elements
-                            if (__comp(*__first, *__i))
-                            {
-                                swap(*__i, *__j);
-                                ++__n_swaps;
-                                ++__i;
-                                break;
-                            }
-                            ++__i;
-                        }
-                    }
-                    // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
-                    if (__i == __j)
-                        return;
-                    while (true)
-                    {
-                        while (!__comp(*__first, *__i))
-                            ++__i;
-                        while (__comp(*__first, *--__j))
-                            ;
-                        if (__i >= __j)
-                            break;
-                        swap(*__i, *__j);
-                        ++__n_swaps;
-                        ++__i;
-                    }
-                    // [__first, __i) == *__first and *__first < [__i, __last)
-                    // The first part is sorted,
-                    if (__nth < __i)
-                        return;
-                    // __nth_element the secod part
-                    // __nth_element<_Compare>(__i, __nth, __last, __comp);
-                    __first = __i;
-                    goto __restart;
-                }
-                if (__comp(*__j, *__m))
-                {
-                    swap(*__i, *__j);
-                    ++__n_swaps;
-                    break;  // found guard for downward moving __j, now use unguarded partition
-                }
-            }
-        }
-        ++__i;
-        // j points beyond range to be tested, *__lm1 is known to be <= *__m
-        // if not yet partitioned...
-        if (__i < __j)
-        {
-            // known that *(__i - 1) < *__m
-            while (true)
-            {
-                // __m still guards upward moving __i
-                while (__comp(*__i, *__m))
-                    ++__i;
-                // It is now known that a guard exists for downward moving __j
-                while (!__comp(*--__j, *__m))
-                    ;
-                if (__i >= __j)
-                    break;
-                swap(*__i, *__j);
-                ++__n_swaps;
-                // It is known that __m != __j
-                // If __m just moved, follow it
-                if (__m == __i)
-                    __m = __j;
-                ++__i;
-            }
-        }
-        // [__first, __i) < *__m and *__m <= [__i, __last)
-        if (__i != __m && __comp(*__m, *__i))
-        {
-            swap(*__i, *__m);
-            ++__n_swaps;
-        }
-        // [__first, __i) < *__i and *__i <= [__i+1, __last)
-        if (__nth == __i)
-            return;
-        if (__n_swaps == 0)
-        {
-            // We were given a perfectly partitioned sequence.  Coincidence?
-            if (__nth < __i)
-            {
-                // Check for [__first, __i) already sorted
-                __j = __m = __first;
-                while (++__j != __i)
-                {
-                    if (__comp(*__j, *__m))
-                        // not yet sorted, so sort
-                        goto not_sorted;
-                    __m = __j;
-                }
-                // [__first, __i) sorted
-                return;
-            }
-            else
-            {
-                // Check for [__i, __last) already sorted
-                __j = __m = __i;
-                while (++__j != __last)
-                {
-                    if (__comp(*__j, *__m))
-                        // not yet sorted, so sort
-                        goto not_sorted;
-                    __m = __j;
-                }
-                // [__i, __last) sorted
-                return;
-            }
-        }
-not_sorted:
-        // __nth_element on range containing __nth
-        if (__nth < __i)
-        {
-            // __nth_element<_Compare>(__first, __nth, __i, __comp);
-            __last = __i;
-        }
-        else
-        {
-            // __nth_element<_Compare>(__i+1, __nth, __last, __comp);
-            __first = ++__i;
-        }
-    }
-}
-
-template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    __nth_element<_Comp_ref>(__first, __nth, __last, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    __nth_element<_Comp_ref>(__first, __nth, __last, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last)
-{
-    _VSTD::nth_element(__first, __nth, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
-}
-
-// includes
-
-template <class _Compare, class _InputIterator1, class _InputIterator2>
-bool
-__includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
-           _Compare __comp)
-{
-    for (; __first2 != __last2; ++__first1)
-    {
-        if (__first1 == __last1 || __comp(*__first2, *__first1))
-            return false;
-        if (!__comp(*__first1, *__first2))
-            ++__first2;
-    }
-    return true;
-}
-
-template <class _InputIterator1, class _InputIterator2, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
-         _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _InputIterator1, class _InputIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2)
-{
-    return _VSTD::includes(__first1, __last1, __first2, __last2,
-                          __less<typename iterator_traits<_InputIterator1>::value_type,
-                                 typename iterator_traits<_InputIterator2>::value_type>());
-}
-
-// set_union
-
-template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
-_OutputIterator
-__set_union(_InputIterator1 __first1, _InputIterator1 __last1,
-            _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
-    for (; __first1 != __last1; ++__result)
-    {
-        if (__first2 == __last2)
-            return _VSTD::copy(__first1, __last1, __result);
-        if (__comp(*__first2, *__first1))
-        {
-            *__result = *__first2;
-            ++__first2;
-        }
-        else
-        {
-            *__result = *__first1;
-            if (!__comp(*__first1, *__first2))
-                ++__first2;
-            ++__first1;
-        }
-    }
-    return _VSTD::copy(__first2, __last2, __result);
-}
-
-template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-set_union(_InputIterator1 __first1, _InputIterator1 __last1,
-          _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-set_union(_InputIterator1 __first1, _InputIterator1 __last1,
-          _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
-{
-    return _VSTD::set_union(__first1, __last1, __first2, __last2, __result,
-                          __less<typename iterator_traits<_InputIterator1>::value_type,
-                                 typename iterator_traits<_InputIterator2>::value_type>());
-}
-
-// set_intersection
-
-template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
-_OutputIterator
-__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
-                   _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
-    while (__first1 != __last1 && __first2 != __last2)
-    {
-        if (__comp(*__first1, *__first2))
-            ++__first1;
-        else
-        {
-            if (!__comp(*__first2, *__first1))
-            {
-                *__result = *__first1;
-                ++__result;
-                ++__first1;
-            }
-            ++__first2;
-        }
-    }
-    return __result;
-}
-
-template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
-                 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
-                 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
-{
-    return _VSTD::set_intersection(__first1, __last1, __first2, __last2, __result,
-                                  __less<typename iterator_traits<_InputIterator1>::value_type,
-                                         typename iterator_traits<_InputIterator2>::value_type>());
-}
-
-// set_difference
-
-template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
-_OutputIterator
-__set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
-                 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
-    while (__first1 != __last1)
-    {
-        if (__first2 == __last2)
-            return _VSTD::copy(__first1, __last1, __result);
-        if (__comp(*__first1, *__first2))
-        {
-            *__result = *__first1;
-            ++__result;
-            ++__first1;
-        }
-        else
-        {
-            if (!__comp(*__first2, *__first1))
-                ++__first1;
-            ++__first2;
-        }
-    }
-    return __result;
-}
-
-template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
-               _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
-               _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
-{
-    return _VSTD::set_difference(__first1, __last1, __first2, __last2, __result,
-                                __less<typename iterator_traits<_InputIterator1>::value_type,
-                                       typename iterator_traits<_InputIterator2>::value_type>());
-}
-
-// set_symmetric_difference
-
-template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
-_OutputIterator
-__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
-                           _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
-    while (__first1 != __last1)
-    {
-        if (__first2 == __last2)
-            return _VSTD::copy(__first1, __last1, __result);
-        if (__comp(*__first1, *__first2))
-        {
-            *__result = *__first1;
-            ++__result;
-            ++__first1;
-        }
-        else
-        {
-            if (__comp(*__first2, *__first1))
-            {
-                *__result = *__first2;
-                ++__result;
-            }
-            else
-                ++__first1;
-            ++__first2;
-        }
-    }
-    return _VSTD::copy(__first2, __last2, __result);
-}
-
-template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
-                         _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
-                         _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
-{
-    return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result,
-                                          __less<typename iterator_traits<_InputIterator1>::value_type,
-                                                 typename iterator_traits<_InputIterator2>::value_type>());
-}
-
-// lexicographical_compare
-
-template <class _Compare, class _InputIterator1, class _InputIterator2>
-bool
-__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
-                          _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
-{
-    for (; __first2 != __last2; ++__first1, ++__first2)
-    {
-        if (__first1 == __last1 || __comp(*__first1, *__first2))
-            return true;
-        if (__comp(*__first2, *__first1))
-            return false;
-    }
-    return false;
-}
-
-template <class _InputIterator1, class _InputIterator2, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
-                        _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _InputIterator1, class _InputIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
-                        _InputIterator2 __first2, _InputIterator2 __last2)
-{
-    return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2,
-                                         __less<typename iterator_traits<_InputIterator1>::value_type,
-                                                typename iterator_traits<_InputIterator2>::value_type>());
-}
-
-// next_permutation
-
-template <class _Compare, class _BidirectionalIterator>
-bool
-__next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
-{
-    _BidirectionalIterator __i = __last;
-    if (__first == __last || __first == --__i)
-        return false;
-    while (true)
-    {
-        _BidirectionalIterator __ip1 = __i;
-        if (__comp(*--__i, *__ip1))
-        {
-            _BidirectionalIterator __j = __last;
-            while (!__comp(*__i, *--__j))
-                ;
-            swap(*__i, *__j);
-            _VSTD::reverse(__ip1, __last);
-            return true;
-        }
-        if (__i == __first)
-        {
-            _VSTD::reverse(__first, __last);
-            return false;
-        }
-    }
-}
-
-template <class _BidirectionalIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return __next_permutation<_Comp_ref>(__first, __last, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return __next_permutation<_Comp_ref>(__first, __last, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _BidirectionalIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
-{
-    return _VSTD::next_permutation(__first, __last,
-                                  __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
-}
-
-// prev_permutation
-
-template <class _Compare, class _BidirectionalIterator>
-bool
-__prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
-{
-    _BidirectionalIterator __i = __last;
-    if (__first == __last || __first == --__i)
-        return false;
-    while (true)
-    {
-        _BidirectionalIterator __ip1 = __i;
-        if (__comp(*__ip1, *--__i))
-        {
-            _BidirectionalIterator __j = __last;
-            while (!__comp(*--__j, *__i))
-                ;
-            swap(*__i, *__j);
-            _VSTD::reverse(__ip1, __last);
-            return true;
-        }
-        if (__i == __first)
-        {
-            _VSTD::reverse(__first, __last);
-            return false;
-        }
-    }
-}
-
-template <class _BidirectionalIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
-{
-#ifdef _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
-    __debug_less<_Compare> __c(__comp);
-    return __prev_permutation<_Comp_ref>(__first, __last, __c);
-#else  // _LIBCPP_DEBUG
-    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
-    return __prev_permutation<_Comp_ref>(__first, __last, __comp);
-#endif  // _LIBCPP_DEBUG
-}
-
-template <class _BidirectionalIterator>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
-{
-    return _VSTD::prev_permutation(__first, __last,
-                                  __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value,
-    _Tp
->::type
-__rotate_left(_Tp __t, _Tp __n = 1)
-{
-    const unsigned __bits = static_cast<unsigned>(sizeof(_Tp) * __CHAR_BIT__ - 1);
-    __n &= __bits;
-    return static_cast<_Tp>((__t << __n) | (static_cast<typename make_unsigned<_Tp>::type>(__t) >> (__bits - __n)));
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_integral<_Tp>::value,
-    _Tp
->::type
-__rotate_right(_Tp __t, _Tp __n = 1)
-{
-    const unsigned __bits = static_cast<unsigned>(sizeof(_Tp) * __CHAR_BIT__ - 1);
-    __n &= __bits;
-    return static_cast<_Tp>((__t << (__bits - __n)) | (static_cast<typename make_unsigned<_Tp>::type>(__t) >> __n));
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif  // _LIBCPP_ALGORITHM
+#endif // _LIBCPP_ALGORITHM
diff --git a/include/any b/include/any
new file mode 100644
index 0000000..3a826c4
--- /dev/null
+++ b/include/any
@@ -0,0 +1,686 @@
+// -*- C++ -*-
+//===------------------------------ any -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_ANY
+#define _LIBCPP_ANY
+
+/*
+   any synopsis
+
+namespace std {
+
+  class bad_any_cast : public bad_cast
+  {
+  public:
+    virtual const char* what() const noexcept;
+  };
+
+  class any
+  {
+  public:
+
+    // 6.3.1 any construct/destruct
+    any() noexcept;
+
+    any(const any& other);
+    any(any&& other) noexcept;
+
+    template <class ValueType>
+      any(ValueType&& value);
+
+    ~any();
+
+    // 6.3.2 any assignments
+    any& operator=(const any& rhs);
+    any& operator=(any&& rhs) noexcept;
+
+    template <class ValueType>
+      any& operator=(ValueType&& rhs);
+
+    // 6.3.3 any modifiers
+    template <class ValueType, class... Args>
+      decay_t<ValueType>& emplace(Args&&... args);
+    template <class ValueType, class U, class... Args>
+      decay_t<ValueType>& emplace(initializer_list<U>, Args&&...);
+    void reset() noexcept;
+    void swap(any& rhs) noexcept;
+
+    // 6.3.4 any observers
+    bool has_value() const noexcept;
+    const type_info& type() const noexcept;
+  };
+
+   // 6.4 Non-member functions
+  void swap(any& x, any& y) noexcept;
+
+  template <class T, class ...Args>
+    any make_any(Args&& ...args);
+  template <class T, class U, class ...Args>
+    any make_any(initializer_list<U>, Args&& ...args);
+
+  template<class ValueType>
+    ValueType any_cast(const any& operand);
+  template<class ValueType>
+    ValueType any_cast(any& operand);
+  template<class ValueType>
+    ValueType any_cast(any&& operand);
+
+  template<class ValueType>
+    const ValueType* any_cast(const any* operand) noexcept;
+  template<class ValueType>
+    ValueType* any_cast(any* operand) noexcept;
+
+} // namespace std
+
+*/
+
+#include <__availability>
+#include <__config>
+#include <__utility/forward.h>
+#include <cstdlib>
+#include <memory>
+#include <type_traits>
+#include <typeinfo>
+#include <version>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+namespace std {
+class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
+{
+public:
+    virtual const char* what() const _NOEXCEPT;
+};
+} // namespace std
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
+void __throw_bad_any_cast()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    throw bad_any_cast();
+#else
+    _VSTD::abort();
+#endif
+}
+
+// Forward declarations
+class _LIBCPP_TEMPLATE_VIS any;
+
+template <class _ValueType>
+_LIBCPP_INLINE_VISIBILITY
+add_pointer_t<add_const_t<_ValueType>>
+any_cast(any const *) _NOEXCEPT;
+
+template <class _ValueType>
+_LIBCPP_INLINE_VISIBILITY
+add_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT;
+
+namespace __any_imp
+{
+  using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>;
+
+  template <class _Tp>
+  using _IsSmallObject = integral_constant<bool
+        , sizeof(_Tp) <= sizeof(_Buffer)
+          && alignment_of<_Buffer>::value
+             % alignment_of<_Tp>::value == 0
+          && is_nothrow_move_constructible<_Tp>::value
+        >;
+
+  enum class _Action {
+    _Destroy,
+    _Copy,
+    _Move,
+    _Get,
+    _TypeInfo
+  };
+
+  template <class _Tp> struct _SmallHandler;
+  template <class _Tp> struct _LargeHandler;
+
+  template <class _Tp>
+  struct  _LIBCPP_TEMPLATE_VIS __unique_typeinfo { static constexpr int __id = 0; };
+  template <class _Tp> constexpr int __unique_typeinfo<_Tp>::__id;
+
+  template <class _Tp>
+  inline _LIBCPP_INLINE_VISIBILITY
+  constexpr const void* __get_fallback_typeid() {
+      return &__unique_typeinfo<remove_cv_t<remove_reference_t<_Tp>>>::__id;
+  }
+
+  template <class _Tp>
+  inline _LIBCPP_INLINE_VISIBILITY
+  bool __compare_typeid(type_info const* __id, const void* __fallback_id)
+  {
+#if !defined(_LIBCPP_NO_RTTI)
+      if (__id && *__id == typeid(_Tp))
+          return true;
+#endif
+      if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>())
+          return true;
+      return false;
+  }
+
+  template <class _Tp>
+  using _Handler = conditional_t<
+    _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;
+
+} // namespace __any_imp
+
+class _LIBCPP_TEMPLATE_VIS any
+{
+public:
+  // construct/destruct
+  _LIBCPP_INLINE_VISIBILITY
+  constexpr any() _NOEXCEPT : __h(nullptr) {}
+
+  _LIBCPP_INLINE_VISIBILITY
+  any(any const & __other) : __h(nullptr)
+  {
+    if (__other.__h) __other.__call(_Action::_Copy, this);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  any(any && __other) _NOEXCEPT : __h(nullptr)
+  {
+    if (__other.__h) __other.__call(_Action::_Move, this);
+  }
+
+  template <
+      class _ValueType
+    , class _Tp = decay_t<_ValueType>
+    , class = enable_if_t<
+        !is_same<_Tp, any>::value &&
+        !__is_inplace_type<_ValueType>::value &&
+        is_copy_constructible<_Tp>::value>
+    >
+  _LIBCPP_INLINE_VISIBILITY
+  any(_ValueType && __value);
+
+  template <class _ValueType, class ..._Args,
+    class _Tp = decay_t<_ValueType>,
+    class = enable_if_t<
+        is_constructible<_Tp, _Args...>::value &&
+        is_copy_constructible<_Tp>::value
+    >
+  >
+  _LIBCPP_INLINE_VISIBILITY
+  explicit any(in_place_type_t<_ValueType>, _Args&&... __args);
+
+  template <class _ValueType, class _Up, class ..._Args,
+    class _Tp = decay_t<_ValueType>,
+    class = enable_if_t<
+        is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
+        is_copy_constructible<_Tp>::value>
+  >
+  _LIBCPP_INLINE_VISIBILITY
+  explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);
+
+  _LIBCPP_INLINE_VISIBILITY
+  ~any() { this->reset(); }
+
+  // assignments
+  _LIBCPP_INLINE_VISIBILITY
+  any & operator=(any const & __rhs) {
+    any(__rhs).swap(*this);
+    return *this;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  any & operator=(any && __rhs) _NOEXCEPT {
+    any(_VSTD::move(__rhs)).swap(*this);
+    return *this;
+  }
+
+  template <
+      class _ValueType
+    , class _Tp = decay_t<_ValueType>
+    , class = enable_if_t<
+          !is_same<_Tp, any>::value
+          && is_copy_constructible<_Tp>::value>
+    >
+  _LIBCPP_INLINE_VISIBILITY
+  any & operator=(_ValueType && __rhs);
+
+  template <class _ValueType, class ..._Args,
+    class _Tp = decay_t<_ValueType>,
+    class = enable_if_t<
+        is_constructible<_Tp, _Args...>::value &&
+        is_copy_constructible<_Tp>::value>
+    >
+  _LIBCPP_INLINE_VISIBILITY
+  _Tp& emplace(_Args&&... args);
+
+  template <class _ValueType, class _Up, class ..._Args,
+    class _Tp = decay_t<_ValueType>,
+    class = enable_if_t<
+        is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
+        is_copy_constructible<_Tp>::value>
+  >
+  _LIBCPP_INLINE_VISIBILITY
+  _Tp& emplace(initializer_list<_Up>, _Args&&...);
+
+  // 6.3.3 any modifiers
+  _LIBCPP_INLINE_VISIBILITY
+  void reset() _NOEXCEPT { if (__h) this->__call(_Action::_Destroy); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void swap(any & __rhs) _NOEXCEPT;
+
+  // 6.3.4 any observers
+  _LIBCPP_INLINE_VISIBILITY
+  bool has_value() const _NOEXCEPT { return __h != nullptr; }
+
+#if !defined(_LIBCPP_NO_RTTI)
+  _LIBCPP_INLINE_VISIBILITY
+  const type_info & type() const _NOEXCEPT {
+    if (__h) {
+        return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo));
+    } else {
+        return typeid(void);
+    }
+  }
+#endif
+
+private:
+    typedef __any_imp::_Action _Action;
+    using _HandleFuncPtr =  void* (*)(_Action, any const *, any *, const type_info *,
+      const void* __fallback_info);
+
+    union _Storage {
+        constexpr _Storage() : __ptr(nullptr) {}
+        void *  __ptr;
+        __any_imp::_Buffer __buf;
+    };
+
+    _LIBCPP_INLINE_VISIBILITY
+    void * __call(_Action __a, any * __other = nullptr,
+                  type_info const * __info = nullptr,
+                   const void* __fallback_info = nullptr) const
+    {
+        return __h(__a, this, __other, __info, __fallback_info);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void * __call(_Action __a, any * __other = nullptr,
+                  type_info const * __info = nullptr,
+                  const void* __fallback_info = nullptr)
+    {
+        return __h(__a, this, __other, __info, __fallback_info);
+    }
+
+    template <class>
+    friend struct __any_imp::_SmallHandler;
+    template <class>
+    friend struct __any_imp::_LargeHandler;
+
+    template <class _ValueType>
+    friend add_pointer_t<add_const_t<_ValueType>>
+    any_cast(any const *) _NOEXCEPT;
+
+    template <class _ValueType>
+    friend add_pointer_t<_ValueType>
+    any_cast(any *) _NOEXCEPT;
+
+    _HandleFuncPtr __h = nullptr;
+    _Storage __s;
+};
+
+namespace __any_imp
+{
+  template <class _Tp>
+  struct _LIBCPP_TEMPLATE_VIS _SmallHandler
+  {
+     _LIBCPP_INLINE_VISIBILITY
+     static void* __handle(_Action __act, any const * __this, any * __other,
+                           type_info const * __info, const void* __fallback_info)
+     {
+        switch (__act)
+        {
+        case _Action::_Destroy:
+          __destroy(const_cast<any &>(*__this));
+          return nullptr;
+        case _Action::_Copy:
+            __copy(*__this, *__other);
+            return nullptr;
+        case _Action::_Move:
+          __move(const_cast<any &>(*__this), *__other);
+          return nullptr;
+        case _Action::_Get:
+            return __get(const_cast<any &>(*__this), __info, __fallback_info);
+        case _Action::_TypeInfo:
+          return __type_info();
+        }
+    }
+
+    template <class ..._Args>
+    _LIBCPP_INLINE_VISIBILITY
+    static _Tp& __create(any & __dest, _Args&&... __args) {
+        typedef allocator<_Tp> _Alloc;
+        typedef allocator_traits<_Alloc> _ATraits;
+        _Alloc __a;
+        _Tp * __ret = static_cast<_Tp*>(static_cast<void*>(&__dest.__s.__buf));
+        _ATraits::construct(__a, __ret, _VSTD::forward<_Args>(__args)...);
+        __dest.__h = &_SmallHandler::__handle;
+        return *__ret;
+    }
+
+  private:
+    _LIBCPP_INLINE_VISIBILITY
+    static void __destroy(any & __this) {
+        typedef allocator<_Tp> _Alloc;
+        typedef allocator_traits<_Alloc> _ATraits;
+        _Alloc __a;
+        _Tp * __p = static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
+        _ATraits::destroy(__a, __p);
+        __this.__h = nullptr;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __copy(any const & __this, any & __dest) {
+        _SmallHandler::__create(__dest, *static_cast<_Tp const *>(
+            static_cast<void const *>(&__this.__s.__buf)));
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __move(any & __this, any & __dest) {
+        _SmallHandler::__create(__dest, _VSTD::move(
+            *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf))));
+        __destroy(__this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void* __get(any & __this,
+                       type_info const * __info,
+                       const void* __fallback_id)
+    {
+        if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id))
+            return static_cast<void*>(&__this.__s.__buf);
+        return nullptr;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void* __type_info()
+    {
+#if !defined(_LIBCPP_NO_RTTI)
+        return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
+#else
+        return nullptr;
+#endif
+    }
+  };
+
+  template <class _Tp>
+  struct _LIBCPP_TEMPLATE_VIS _LargeHandler
+  {
+    _LIBCPP_INLINE_VISIBILITY
+    static void* __handle(_Action __act, any const * __this,
+                          any * __other, type_info const * __info,
+                          void const* __fallback_info)
+    {
+        switch (__act)
+        {
+        case _Action::_Destroy:
+          __destroy(const_cast<any &>(*__this));
+          return nullptr;
+        case _Action::_Copy:
+          __copy(*__this, *__other);
+          return nullptr;
+        case _Action::_Move:
+          __move(const_cast<any &>(*__this), *__other);
+          return nullptr;
+        case _Action::_Get:
+            return __get(const_cast<any &>(*__this), __info, __fallback_info);
+        case _Action::_TypeInfo:
+          return __type_info();
+        }
+    }
+
+    template <class ..._Args>
+    _LIBCPP_INLINE_VISIBILITY
+    static _Tp& __create(any & __dest, _Args&&... __args) {
+        typedef allocator<_Tp> _Alloc;
+        typedef allocator_traits<_Alloc> _ATraits;
+        typedef __allocator_destructor<_Alloc> _Dp;
+        _Alloc __a;
+        unique_ptr<_Tp, _Dp> __hold(_ATraits::allocate(__a, 1), _Dp(__a, 1));
+        _Tp * __ret = __hold.get();
+        _ATraits::construct(__a, __ret, _VSTD::forward<_Args>(__args)...);
+        __dest.__s.__ptr = __hold.release();
+        __dest.__h = &_LargeHandler::__handle;
+        return *__ret;
+    }
+
+  private:
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __destroy(any & __this){
+        typedef allocator<_Tp> _Alloc;
+        typedef allocator_traits<_Alloc> _ATraits;
+        _Alloc __a;
+        _Tp * __p = static_cast<_Tp *>(__this.__s.__ptr);
+        _ATraits::destroy(__a, __p);
+        _ATraits::deallocate(__a, __p, 1);
+        __this.__h = nullptr;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __copy(any const & __this, any & __dest) {
+        _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr));
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __move(any & __this, any & __dest) {
+      __dest.__s.__ptr = __this.__s.__ptr;
+      __dest.__h = &_LargeHandler::__handle;
+      __this.__h = nullptr;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void* __get(any & __this, type_info const * __info,
+                       void const* __fallback_info)
+    {
+        if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info))
+            return static_cast<void*>(__this.__s.__ptr);
+        return nullptr;
+
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void* __type_info()
+    {
+#if !defined(_LIBCPP_NO_RTTI)
+        return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
+#else
+        return nullptr;
+#endif
+    }
+  };
+
+} // namespace __any_imp
+
+
+template <class _ValueType, class _Tp, class>
+any::any(_ValueType && __v) : __h(nullptr)
+{
+  __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v));
+}
+
+template <class _ValueType, class ..._Args, class _Tp, class>
+any::any(in_place_type_t<_ValueType>, _Args&&... __args) {
+  __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
+}
+
+template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
+any::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
+  __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
+}
+
+template <class _ValueType, class, class>
+inline _LIBCPP_INLINE_VISIBILITY
+any & any::operator=(_ValueType && __v)
+{
+  any(_VSTD::forward<_ValueType>(__v)).swap(*this);
+  return *this;
+}
+
+template <class _ValueType, class ..._Args, class _Tp, class>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp& any::emplace(_Args&&... __args) {
+  reset();
+  return __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
+}
+
+template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
+  reset();
+  return __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void any::swap(any & __rhs) _NOEXCEPT
+{
+    if (this == &__rhs)
+      return;
+    if (__h && __rhs.__h) {
+        any __tmp;
+        __rhs.__call(_Action::_Move, &__tmp);
+        this->__call(_Action::_Move, &__rhs);
+        __tmp.__call(_Action::_Move, this);
+    }
+    else if (__h) {
+        this->__call(_Action::_Move, &__rhs);
+    }
+    else if (__rhs.__h) {
+        __rhs.__call(_Action::_Move, this);
+    }
+}
+
+// 6.4 Non-member functions
+
+inline _LIBCPP_INLINE_VISIBILITY
+void swap(any & __lhs, any & __rhs) _NOEXCEPT
+{
+    __lhs.swap(__rhs);
+}
+
+template <class _Tp, class ..._Args>
+inline _LIBCPP_INLINE_VISIBILITY
+any make_any(_Args&&... __args) {
+    return any(in_place_type<_Tp>, _VSTD::forward<_Args>(__args)...);
+}
+
+template <class _Tp, class _Up, class ..._Args>
+inline _LIBCPP_INLINE_VISIBILITY
+any make_any(initializer_list<_Up> __il, _Args&&... __args) {
+    return any(in_place_type<_Tp>, __il, _VSTD::forward<_Args>(__args)...);
+}
+
+template <class _ValueType>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
+_ValueType any_cast(any const & __v)
+{
+    using _RawValueType = __uncvref_t<_ValueType>;
+    static_assert(is_constructible<_ValueType, _RawValueType const &>::value,
+                  "ValueType is required to be a const lvalue reference "
+                  "or a CopyConstructible type");
+    auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v);
+    if (__tmp == nullptr)
+        __throw_bad_any_cast();
+    return static_cast<_ValueType>(*__tmp);
+}
+
+template <class _ValueType>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
+_ValueType any_cast(any & __v)
+{
+    using _RawValueType = __uncvref_t<_ValueType>;
+    static_assert(is_constructible<_ValueType, _RawValueType &>::value,
+                  "ValueType is required to be an lvalue reference "
+                  "or a CopyConstructible type");
+    auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
+    if (__tmp == nullptr)
+        __throw_bad_any_cast();
+    return static_cast<_ValueType>(*__tmp);
+}
+
+template <class _ValueType>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
+_ValueType any_cast(any && __v)
+{
+    using _RawValueType = __uncvref_t<_ValueType>;
+    static_assert(is_constructible<_ValueType, _RawValueType>::value,
+                  "ValueType is required to be an rvalue reference "
+                  "or a CopyConstructible type");
+    auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
+    if (__tmp == nullptr)
+        __throw_bad_any_cast();
+    return static_cast<_ValueType>(_VSTD::move(*__tmp));
+}
+
+template <class _ValueType>
+inline _LIBCPP_INLINE_VISIBILITY
+add_pointer_t<add_const_t<_ValueType>>
+any_cast(any const * __any) _NOEXCEPT
+{
+    static_assert(!is_reference<_ValueType>::value,
+                  "_ValueType may not be a reference.");
+    return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any));
+}
+
+template <class _RetType>
+inline _LIBCPP_INLINE_VISIBILITY
+_RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept {
+  return static_cast<_RetType>(__p);
+}
+
+template <class _RetType>
+inline _LIBCPP_INLINE_VISIBILITY
+_RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept {
+  return nullptr;
+}
+
+template <class _ValueType>
+add_pointer_t<_ValueType>
+any_cast(any * __any) _NOEXCEPT
+{
+    using __any_imp::_Action;
+    static_assert(!is_reference<_ValueType>::value,
+                  "_ValueType may not be a reference.");
+    typedef typename add_pointer<_ValueType>::type _ReturnType;
+    if (__any && __any->__h) {
+      void *__p = __any->__call(_Action::_Get, nullptr,
+#if !defined(_LIBCPP_NO_RTTI)
+                          &typeid(_ValueType),
+#else
+                          nullptr,
+#endif
+                          __any_imp::__get_fallback_typeid<_ValueType>());
+        return _VSTD::__pointer_or_func_cast<_ReturnType>(
+            __p, is_function<_ValueType>{});
+    }
+    return nullptr;
+}
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_ANY
diff --git a/include/array b/include/array
index d37075d..022172b 100644
--- a/include/array
+++ b/include/array
@@ -1,10 +1,9 @@
 // -*- C++ -*-
 //===---------------------------- array -----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -33,24 +32,24 @@
     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 
     // 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 fill(const T& u);                                      // constexpr in C++20
+    void swap(array& a) noexcept(is_nothrow_swappable_v<T>);    // constexpr in C++20
 
     // iterators:
-    iterator begin() noexcept;
-    const_iterator begin() const noexcept;
-    iterator end() noexcept;
-    const_iterator end() const noexcept;
+    iterator begin() noexcept;                                  // constexpr in C++17
+    const_iterator begin() const noexcept;                      // constexpr in C++17
+    iterator end() noexcept;                                    // constexpr in C++17
+    const_iterator end() const noexcept;                        // constexpr in C++17
 
-    reverse_iterator rbegin() noexcept;
-    const_reverse_iterator rbegin() const noexcept;
-    reverse_iterator rend() noexcept;
-    const_reverse_iterator rend() const noexcept;
+    reverse_iterator rbegin() noexcept;                         // constexpr in C++17
+    const_reverse_iterator rbegin() const noexcept;             // constexpr in C++17
+    reverse_iterator rend() noexcept;                           // constexpr in C++17
+    const_reverse_iterator rend() const noexcept;               // constexpr in C++17
 
-    const_iterator cbegin() const noexcept;
-    const_iterator cend() const noexcept;
-    const_reverse_iterator crbegin() const noexcept;
-    const_reverse_iterator crend() const noexcept;
+    const_iterator cbegin() const noexcept;                     // constexpr in C++17
+    const_iterator cend() const noexcept;                       // constexpr in C++17
+    const_reverse_iterator crbegin() const noexcept;            // constexpr in C++17
+    const_reverse_iterator crend() const noexcept;              // constexpr in C++17
 
     // capacity:
     constexpr size_type size() const noexcept;
@@ -58,58 +57,67 @@
     constexpr bool empty() const noexcept;
 
     // element access:
-    reference operator[](size_type n);
-    const_reference operator[](size_type n) const; // constexpr in C++14
-    const_reference at(size_type n) const; // constexpr in C++14
-    reference at(size_type n);
+    reference operator[](size_type n);                          // constexpr in C++17
+    const_reference operator[](size_type n) const;              // constexpr in C++14
+    reference at(size_type n);                                  // constexpr in C++17
+    const_reference at(size_type n) const;                      // constexpr in C++14
 
-    reference front();
-    const_reference front() const; // constexpr in C++14
-    reference back();
-    const_reference back() const; // constexpr in C++14
+    reference front();                                          // constexpr in C++17
+    const_reference front() const;                              // constexpr in C++14
+    reference back();                                           // constexpr in C++17
+    const_reference back() const;                               // constexpr in C++14
 
-    T* data() noexcept;
-    const T* data() const noexcept;
+    T* data() noexcept;                                         // constexpr in C++17
+    const T* data() const noexcept;                             // constexpr in C++17
 };
 
+template <class T, class... U>
+  array(T, U...) -> array<T, 1 + sizeof...(U)>;                 // C++17
+
 template <class T, size_t N>
-  bool operator==(const array<T,N>& x, const array<T,N>& y);
+  bool operator==(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20
 template <class T, size_t N>
-  bool operator!=(const array<T,N>& x, const array<T,N>& y);
+  bool operator!=(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20
 template <class T, size_t N>
-  bool operator<(const array<T,N>& x, const array<T,N>& y);
+  bool operator<(const array<T,N>& x, const array<T,N>& y);     // constexpr in C++20
 template <class T, size_t N>
-  bool operator>(const array<T,N>& x, const array<T,N>& y);
+  bool operator>(const array<T,N>& x, const array<T,N>& y);     // constexpr in C++20
 template <class T, size_t N>
-  bool operator<=(const array<T,N>& x, const array<T,N>& y);
+  bool operator<=(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20
 template <class T, size_t N>
-  bool operator>=(const array<T,N>& x, const array<T,N>& y);
+  bool operator>=(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20
 
 template <class T, size_t N >
-  void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y)));
+  void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20
 
-template <class T> class tuple_size;
-template <int I, class T> class tuple_element;
+template <class T, size_t N>
+  constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]);  // C++20
+template <class T, size_t N>
+  constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]); // C++20
+
+template <class T> struct tuple_size;
+template <size_t I, class T> struct 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
 
 */
 
 #include <__config>
+#include <__debug>
 #include <__tuple>
+#include <algorithm>
+#include <cstdlib> // for _LIBCPP_UNREACHABLE
+#include <iterator>
+#include <stdexcept>
 #include <type_traits>
 #include <utility>
-#include <iterator>
-#include <algorithm>
-#include <stdexcept>
-#if defined(_LIBCPP_NO_EXCEPTIONS)
-    #include <cassert>
-#endif
+#include <version>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -118,7 +126,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, size_t _Size>
-struct _LIBCPP_TYPE_VIS_ONLY array
+struct _LIBCPP_TEMPLATE_VIS array
 {
     // types:
     typedef array __self;
@@ -131,44 +139,48 @@
     typedef const value_type*                     const_pointer;
     typedef size_t                                size_type;
     typedef ptrdiff_t                             difference_type;
-    typedef std::reverse_iterator<iterator>       reverse_iterator;
-    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+    typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
+    typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
 
-    value_type __elems_[_Size > 0 ? _Size : 1];
+    _Tp __elems_[_Size];
 
     // No explicit construct/copy/destroy for aggregate type
-    _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_);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    void fill(const value_type& __u) {
+        _VSTD::fill_n(data(), _Size, __u);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) {
+        _VSTD::swap_ranges(data(), data() + _Size, __a.data());
+    }
 
     // iterators:
-    _LIBCPP_INLINE_VISIBILITY
-    iterator begin() _NOEXCEPT {return iterator(__elems_);}
-    _LIBCPP_INLINE_VISIBILITY
-    const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);}
-    _LIBCPP_INLINE_VISIBILITY
-    iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);}
-    _LIBCPP_INLINE_VISIBILITY
-    const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    iterator begin() _NOEXCEPT {return iterator(data());}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const_iterator begin() const _NOEXCEPT {return const_iterator(data());}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    iterator end() _NOEXCEPT {return iterator(data() + _Size);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const_iterator end() const _NOEXCEPT {return const_iterator(data() + _Size);}
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
     reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
     const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
     reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
     const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
     const_iterator cbegin() const _NOEXCEPT {return begin();}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
     const_iterator cend() const _NOEXCEPT {return end();}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
     const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
     const_reverse_iterator crend() const _NOEXCEPT {return rend();}
 
     // capacity:
@@ -176,64 +188,193 @@
     _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return _Size;}
     _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;}
 
     // element access:
-    _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n)             {return __elems_[__n];}
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference operator[](size_type __n) const {return __elems_[__n];}
-    reference at(size_type __n);
-    _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reference operator[](size_type __n) _NOEXCEPT {
+        _LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array<T, N>");
+        return __elems_[__n];
+    }
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    const_reference operator[](size_type __n) const _NOEXCEPT {
+        _LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array<T, N>");
+        return __elems_[__n];
+    }
 
-    _LIBCPP_INLINE_VISIBILITY reference front()             {return __elems_[0];}
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const {return __elems_[0];}
-    _LIBCPP_INLINE_VISIBILITY reference back()              {return __elems_[_Size > 0 ? _Size-1 : 0];}
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const  {return __elems_[_Size > 0 ? _Size-1 : 0];}
+    _LIBCPP_CONSTEXPR_AFTER_CXX14 reference at(size_type __n)
+    {
+        if (__n >= _Size)
+            __throw_out_of_range("array::at");
+        return __elems_[__n];
+    }
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const
+    {
+        if (__n >= _Size)
+            __throw_out_of_range("array::at");
+        return __elems_[__n];
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference front()             _NOEXCEPT {return (*this)[0];}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const _NOEXCEPT {return (*this)[0];}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference back()              _NOEXCEPT {return (*this)[_Size - 1];}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const  _NOEXCEPT {return (*this)[_Size - 1];}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
     value_type* data() _NOEXCEPT {return __elems_;}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
     const value_type* data() const _NOEXCEPT {return __elems_;}
 };
 
-template <class _Tp, size_t _Size>
-typename array<_Tp, _Size>::reference
-array<_Tp, _Size>::at(size_type __n)
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
 {
-    if (__n >= _Size)
-#ifndef _LIBCPP_NO_EXCEPTIONS
-        throw out_of_range("array::at");
-#else
-        assert(!"array::at out_of_range");
-#endif
-    return __elems_[__n];
-}
+    // types:
+    typedef array __self;
+    typedef _Tp                                   value_type;
+    typedef value_type&                           reference;
+    typedef const value_type&                     const_reference;
+    typedef value_type*                           iterator;
+    typedef const value_type*                     const_iterator;
+    typedef value_type*                           pointer;
+    typedef const value_type*                     const_pointer;
+    typedef size_t                                size_type;
+    typedef ptrdiff_t                             difference_type;
+    typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
+    typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
 
-template <class _Tp, size_t _Size>
-_LIBCPP_CONSTEXPR_AFTER_CXX11
-typename array<_Tp, _Size>::const_reference
-array<_Tp, _Size>::at(size_type __n) const
-{
-    if (__n >= _Size)
-#ifndef _LIBCPP_NO_EXCEPTIONS
-        throw out_of_range("array::at");
-#else
-        assert(!"array::at out_of_range");
+    typedef typename conditional<is_const<_Tp>::value, const char,
+                                char>::type _CharType;
+
+    struct  _ArrayInStructT { _Tp __data_[1]; };
+    _ALIGNAS_TYPE(_ArrayInStructT) _CharType __elems_[sizeof(_ArrayInStructT)];
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    value_type* data() _NOEXCEPT {return nullptr;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const value_type* data() const _NOEXCEPT {return nullptr;}
+
+    // No explicit construct/copy/destroy for aggregate type
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    void fill(const value_type&) {
+      static_assert(!is_const<_Tp>::value,
+                    "cannot fill zero-sized array of type 'const T'");
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    void swap(array&) _NOEXCEPT {
+      static_assert(!is_const<_Tp>::value,
+                    "cannot swap zero-sized array of type 'const T'");
+    }
+
+    // iterators:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    iterator begin() _NOEXCEPT {return iterator(data());}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const_iterator begin() const _NOEXCEPT {return const_iterator(data());}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    iterator end() _NOEXCEPT {return iterator(data());}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const_iterator end() const _NOEXCEPT {return const_iterator(data());}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const_iterator cbegin() const _NOEXCEPT {return begin();}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const_iterator cend() const _NOEXCEPT {return end();}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
+
+    // capacity:
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return 0; }
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return 0;}
+    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return true;}
+
+    // element access:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reference operator[](size_type) _NOEXCEPT {
+      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
+      _LIBCPP_UNREACHABLE();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    const_reference operator[](size_type) const _NOEXCEPT {
+      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
+      _LIBCPP_UNREACHABLE();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reference at(size_type) {
+      __throw_out_of_range("array<T, 0>::at");
+      _LIBCPP_UNREACHABLE();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    const_reference at(size_type) const {
+      __throw_out_of_range("array<T, 0>::at");
+      _LIBCPP_UNREACHABLE();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reference front() _NOEXCEPT {
+      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
+      _LIBCPP_UNREACHABLE();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    const_reference front() const _NOEXCEPT {
+      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
+      _LIBCPP_UNREACHABLE();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reference back() _NOEXCEPT {
+      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
+      _LIBCPP_UNREACHABLE();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    const_reference back() const _NOEXCEPT {
+      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
+      _LIBCPP_UNREACHABLE();
+    }
+};
+
+
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+template<class _Tp, class... _Args,
+         class = _EnableIf<__all<_IsSame<_Tp, _Args>::value...>::value>
+         >
+array(_Tp, _Args...)
+  -> array<_Tp, 1 + sizeof...(_Args)>;
 #endif
-    return __elems_[__n];
-}
 
 template <class _Tp, size_t _Size>
 inline _LIBCPP_INLINE_VISIBILITY
-bool
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
 operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
 {
-    return _VSTD::equal(__x.__elems_, __x.__elems_ + _Size, __y.__elems_);
+    return _VSTD::equal(__x.begin(), __x.end(), __y.begin());
 }
 
 template <class _Tp, size_t _Size>
 inline _LIBCPP_INLINE_VISIBILITY
-bool
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
 operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
 {
     return !(__x == __y);
@@ -241,15 +382,16 @@
 
 template <class _Tp, size_t _Size>
 inline _LIBCPP_INLINE_VISIBILITY
-bool
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
 operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
 {
-    return _VSTD::lexicographical_compare(__x.__elems_, __x.__elems_ + _Size, __y.__elems_, __y.__elems_ + _Size);
+    return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
+                                          __y.begin(), __y.end());
 }
 
 template <class _Tp, size_t _Size>
 inline _LIBCPP_INLINE_VISIBILITY
-bool
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
 operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
 {
     return __y < __x;
@@ -257,7 +399,7 @@
 
 template <class _Tp, size_t _Size>
 inline _LIBCPP_INLINE_VISIBILITY
-bool
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
 operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
 {
     return !(__y < __x);
@@ -265,48 +407,38 @@
 
 template <class _Tp, size_t _Size>
 inline _LIBCPP_INLINE_VISIBILITY
-bool
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
 operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
 {
     return !(__x < __y);
 }
 
 template <class _Tp, size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 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);
 }
 
 template <class _Tp, size_t _Size>
-class _LIBCPP_TYPE_VIS_ONLY tuple_size<array<_Tp, _Size> >
-    : public integral_constant<size_t, _Size> {};
-
-template <class _Tp, size_t _Size>
-class _LIBCPP_TYPE_VIS_ONLY tuple_size<const array<_Tp, _Size> >
+struct _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> >
     : public integral_constant<size_t, _Size> {};
 
 template <size_t _Ip, class _Tp, size_t _Size>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, array<_Tp, _Size> >
+struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, array<_Tp, _Size> >
 {
-public:
+    static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::array)");
     typedef _Tp type;
 };
 
 template <size_t _Ip, class _Tp, size_t _Size>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const array<_Tp, _Size> >
-{
-public:
-    typedef const _Tp type;
-};
-
-template <size_t _Ip, class _Tp, size_t _Size>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp&
 get(array<_Tp, _Size>& __a) _NOEXCEPT
@@ -324,8 +456,6 @@
     return __a.__elems_[_Ip];
 }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <size_t _Ip, class _Tp, size_t _Size>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp&&
@@ -335,8 +465,56 @@
     return _VSTD::move(__a.__elems_[_Ip]);
 }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+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]);
+}
+
+#if _LIBCPP_STD_VER > 17
+
+template <typename _Tp, size_t _Size, size_t... _Index>
+_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
+__to_array_lvalue_impl(_Tp (&__arr)[_Size], index_sequence<_Index...>) {
+  return {{__arr[_Index]...}};
+}
+
+template <typename _Tp, size_t _Size, size_t... _Index>
+_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
+__to_array_rvalue_impl(_Tp(&&__arr)[_Size], index_sequence<_Index...>) {
+  return {{_VSTD::move(__arr[_Index])...}};
+}
+
+template <typename _Tp, size_t _Size>
+_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
+to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) {
+  static_assert(
+      !is_array_v<_Tp>,
+      "[array.creation]/1: to_array does not accept multidimensional arrays.");
+  static_assert(
+      is_constructible_v<_Tp, _Tp&>,
+      "[array.creation]/1: to_array requires copy constructible elements.");
+  return _VSTD::__to_array_lvalue_impl(__arr, make_index_sequence<_Size>());
+}
+
+template <typename _Tp, size_t _Size>
+_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
+to_array(_Tp(&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) {
+  static_assert(
+      !is_array_v<_Tp>,
+      "[array.creation]/4: to_array does not accept multidimensional arrays.");
+  static_assert(
+      is_move_constructible_v<_Tp>,
+      "[array.creation]/4: to_array requires move constructible elements.");
+  return _VSTD::__to_array_rvalue_impl(_VSTD::move(__arr),
+                                       make_index_sequence<_Size>());
+}
+
+#endif // _LIBCPP_STD_VER > 17
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif  // _LIBCPP_ARRAY
+#endif // _LIBCPP_ARRAY
diff --git a/include/atomic b/include/atomic
index 91f1829..0f6aee8 100644
--- a/include/atomic
+++ b/include/atomic
@@ -1,10 +1,9 @@
 // -*- C++ -*-
 //===--------------------------- atomic -----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -17,17 +16,31 @@
 namespace std
 {
 
-// order and consistency
+// feature test macro [version.syn]
 
-typedef enum memory_order
-{
-    memory_order_relaxed,
-    memory_order_consume,  // load-consume
-    memory_order_acquire,  // load-acquire
-    memory_order_release,  // store-release
-    memory_order_acq_rel,  // store-release load-acquire
-    memory_order_seq_cst   // store-release load-acquire
-} memory_order;
+#define __cpp_lib_atomic_is_always_lock_free
+#define __cpp_lib_atomic_flag_test
+#define __cpp_lib_atomic_lock_free_type_aliases
+#define __cpp_lib_atomic_wait
+
+ // order and consistency
+
+ enum memory_order: unspecified // enum class in C++20
+ {
+    relaxed,
+    consume, // load-consume
+    acquire, // load-acquire
+    release, // store-release
+    acq_rel, // store-release load-acquire
+    seq_cst // store-release load-acquire
+ };
+
+ inline constexpr auto memory_order_relaxed = memory_order::relaxed;
+ inline constexpr auto memory_order_consume = memory_order::consume;
+ inline constexpr auto memory_order_acquire = memory_order::acquire;
+ inline constexpr auto memory_order_release = memory_order::release;
+ inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
+ inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
 
 template <class T> T kill_dependency(T y) noexcept;
 
@@ -35,6 +48,7 @@
 
 #define ATOMIC_BOOL_LOCK_FREE unspecified
 #define ATOMIC_CHAR_LOCK_FREE unspecified
+#define ATOMIC_CHAR8_T_LOCK_FREE unspecified // C++20
 #define ATOMIC_CHAR16_T_LOCK_FREE unspecified
 #define ATOMIC_CHAR32_T_LOCK_FREE unspecified
 #define ATOMIC_WCHAR_T_LOCK_FREE unspecified
@@ -44,59 +58,31 @@
 #define ATOMIC_LLONG_LOCK_FREE unspecified
 #define ATOMIC_POINTER_LOCK_FREE unspecified
 
-// flag type and operations
-
-typedef struct atomic_flag
-{
-    bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
-    bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
-    void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
-    void clear(memory_order m = memory_order_seq_cst) noexcept;
-    atomic_flag()  noexcept = default;
-    atomic_flag(const atomic_flag&) = delete;
-    atomic_flag& operator=(const atomic_flag&) = delete;
-    atomic_flag& operator=(const atomic_flag&) volatile = delete;
-} atomic_flag;
-
-bool
-    atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
-
-bool
-    atomic_flag_test_and_set(atomic_flag* obj) noexcept;
-
-bool
-    atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
-                                      memory_order m) noexcept;
-
-bool
-    atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
-
-void
-    atomic_flag_clear(volatile atomic_flag* obj) noexcept;
-
-void
-    atomic_flag_clear(atomic_flag* obj) noexcept;
-
-void
-    atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
-
-void
-    atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
-
-#define ATOMIC_FLAG_INIT see below
-#define ATOMIC_VAR_INIT(value) see below
-
 template <class T>
 struct atomic
 {
+    using value_type = 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;
-    void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
+
+    atomic() noexcept = default; // until C++20
+    constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>); // since C++20
+    constexpr atomic(T desr) noexcept;
+    atomic(const atomic&) = delete;
+    atomic& operator=(const atomic&) = delete;
+    atomic& operator=(const atomic&) volatile = delete;
+
     T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
     T load(memory_order m = memory_order_seq_cst) const noexcept;
     operator T() const volatile noexcept;
     operator T() const noexcept;
+    void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
+    void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
+    T operator=(T) volatile noexcept;
+    T operator=(T) noexcept;
+
     T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
     T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
     bool compare_exchange_weak(T& expc, T desr,
@@ -115,26 +101,39 @@
     bool compare_exchange_strong(T& expc, T desr,
                                  memory_order m = memory_order_seq_cst) noexcept;
 
-    atomic() noexcept = default;
-    constexpr atomic(T desr) noexcept;
-    atomic(const atomic&) = delete;
-    atomic& operator=(const atomic&) = delete;
-    atomic& operator=(const atomic&) volatile = delete;
-    T operator=(T) volatile noexcept;
-    T operator=(T) noexcept;
+    void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
+    void wait(T, memory_order = memory_order::seq_cst) const noexcept;
+    void notify_one() volatile noexcept;
+    void notify_one() noexcept;
+    void notify_all() volatile noexcept;
+    void notify_all() noexcept;
 };
 
 template <>
 struct atomic<integral>
 {
+    using value_type = integral;
+    using difference_type = value_type;
+
+    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;
-    void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
+
+    atomic() noexcept = default;
+    constexpr atomic(integral desr) noexcept;
+    atomic(const atomic&) = delete;
+    atomic& operator=(const atomic&) = delete;
+    atomic& operator=(const atomic&) volatile = delete;
+
     integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
     integral load(memory_order m = memory_order_seq_cst) const noexcept;
     operator integral() const volatile noexcept;
     operator integral() const noexcept;
+    void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
+    void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
+    integral operator=(integral desr) volatile noexcept;
+    integral operator=(integral desr) noexcept;
+
     integral exchange(integral desr,
                       memory_order m = memory_order_seq_cst) volatile noexcept;
     integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
@@ -155,30 +154,17 @@
     bool compare_exchange_strong(integral& expc, integral desr,
                                  memory_order m = memory_order_seq_cst) noexcept;
 
-    integral
-        fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
+    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
     integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
-    integral
-        fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
+    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
     integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
-    integral
-        fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
+    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
     integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
-    integral
-        fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
+    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
     integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
-    integral
-        fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
+    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
     integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
 
-    atomic() noexcept = default;
-    constexpr atomic(integral desr) noexcept;
-    atomic(const atomic&) = delete;
-    atomic& operator=(const atomic&) = delete;
-    atomic& operator=(const atomic&) volatile = delete;
-    integral operator=(integral desr) volatile noexcept;
-    integral operator=(integral desr) noexcept;
-
     integral operator++(int) volatile noexcept;
     integral operator++(int) noexcept;
     integral operator--(int) volatile noexcept;
@@ -197,19 +183,41 @@
     integral operator|=(integral op) noexcept;
     integral operator^=(integral op) volatile noexcept;
     integral operator^=(integral op) noexcept;
+
+    void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept;
+    void wait(integral, memory_order = memory_order::seq_cst) const noexcept;
+    void notify_one() volatile noexcept;
+    void notify_one() noexcept;
+    void notify_all() volatile noexcept;
+    void notify_all() noexcept;
 };
 
 template <class T>
 struct atomic<T*>
 {
+    using value_type = T*;
+    using difference_type = ptrdiff_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;
-    void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
+
+    atomic() noexcept = default; // until C++20
+    constexpr atomic() noexcept; // since C++20
+    constexpr atomic(T* desr) noexcept;
+    atomic(const atomic&) = delete;
+    atomic& operator=(const atomic&) = delete;
+    atomic& operator=(const atomic&) volatile = delete;
+
     T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
     T* load(memory_order m = memory_order_seq_cst) const noexcept;
     operator T*() const volatile noexcept;
     operator T*() const noexcept;
+    void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
+    void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
+    T* operator=(T*) volatile noexcept;
+    T* operator=(T*) noexcept;
+
     T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
     T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
     bool compare_exchange_weak(T*& expc, T* desr,
@@ -233,14 +241,6 @@
     T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
     T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
 
-    atomic() noexcept = default;
-    constexpr atomic(T* desr) noexcept;
-    atomic(const atomic&) = delete;
-    atomic& operator=(const atomic&) = delete;
-    atomic& operator=(const atomic&) volatile = delete;
-
-    T* operator=(T*) volatile noexcept;
-    T* operator=(T*) noexcept;
     T* operator++(int) volatile noexcept;
     T* operator++(int) noexcept;
     T* operator--(int) volatile noexcept;
@@ -253,224 +253,206 @@
     T* operator+=(ptrdiff_t op) noexcept;
     T* operator-=(ptrdiff_t op) volatile noexcept;
     T* operator-=(ptrdiff_t op) noexcept;
+
+    void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
+    void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
+    void notify_one() volatile noexcept;
+    void notify_one() noexcept;
+    void notify_all() volatile noexcept;
+    void notify_all() noexcept;
 };
 
 
 template <class T>
-    bool
-    atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
+  bool atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
 
 template <class T>
-    bool
-    atomic_is_lock_free(const atomic<T>* obj) noexcept;
+  bool atomic_is_lock_free(const atomic<T>* obj) noexcept;
 
 template <class T>
-    void
-    atomic_init(volatile atomic<T>* obj, T desr) noexcept;
+  void atomic_store(volatile atomic<T>* obj, T desr) noexcept;
 
 template <class T>
-    void
-    atomic_init(atomic<T>* obj, T desr) noexcept;
+  void atomic_store(atomic<T>* obj, T desr) noexcept;
 
 template <class T>
-    void
-    atomic_store(volatile atomic<T>* obj, T desr) noexcept;
+  void atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
 
 template <class T>
-    void
-    atomic_store(atomic<T>* obj, T desr) noexcept;
+  void atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
 
 template <class T>
-    void
-    atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
+  T atomic_load(const volatile atomic<T>* obj) noexcept;
 
 template <class T>
-    void
-    atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
+  T atomic_load(const atomic<T>* obj) noexcept;
 
 template <class T>
-    T
-    atomic_load(const volatile atomic<T>* obj) noexcept;
+  T atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
 
 template <class T>
-    T
-    atomic_load(const atomic<T>* obj) noexcept;
+  T atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
 
 template <class T>
-    T
-    atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
+  T atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
 
 template <class T>
-    T
-    atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
+  T atomic_exchange(atomic<T>* obj, T desr) noexcept;
 
 template <class T>
-    T
-    atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
+  T atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
 
 template <class T>
-    T
-    atomic_exchange(atomic<T>* obj, T desr) noexcept;
+  T atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
 
 template <class T>
-    T
-    atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
+  bool atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
 
 template <class T>
-    T
-    atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
+  bool atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
 
 template <class T>
-    bool
-    atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
+  bool atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
 
 template <class T>
-    bool
-    atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
+  bool atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
 
 template <class T>
-    bool
-    atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
+  bool atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
+                                             T desr,
+                                             memory_order s, memory_order f) noexcept;
 
 template <class T>
-    bool
-    atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
+  bool atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
+                                             memory_order s, memory_order f) noexcept;
 
 template <class T>
-    bool
-    atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
-                                          T desr,
-                                          memory_order s, memory_order f) noexcept;
+  bool atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
+                                               T* expc, T desr,
+                                               memory_order s, memory_order f) noexcept;
 
 template <class T>
-    bool
-    atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
-                                          memory_order s, memory_order f) noexcept;
+  bool atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
+                                               T desr,
+                                               memory_order s, memory_order f) noexcept;
 
 template <class T>
-    bool
-    atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
-                                            T* expc, T desr,
-                                            memory_order s, memory_order f) noexcept;
+  void atomic_wait(const volatile atomic<T>* obj, T old) noexcept;
 
 template <class T>
-    bool
-    atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
-